@shopify/react-native-skia 0.1.145 → 0.1.146
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/cpp/api/JsiSkContourMeasure.h +4 -4
- package/cpp/api/JsiSkDataFactory.h +3 -3
- package/cpp/api/JsiSkFont.h +1 -1
- package/cpp/api/JsiSkPathFactory.h +1 -1
- package/cpp/api/JsiSkPictureFactory.h +1 -1
- package/cpp/api/JsiSkRuntimeEffect.h +6 -6
- package/cpp/api/JsiSkRuntimeEffectFactory.h +1 -1
- package/cpp/jsi/JsiSimpleValueWrapper.h +27 -27
- package/cpp/jsi/JsiValueWrapper.h +127 -0
- package/cpp/rnskia/RNSkDrawView.cpp +41 -17
- package/cpp/rnskia/RNSkDrawView.h +17 -19
- package/cpp/rnskia/RNSkJsiViewApi.h +180 -166
- package/cpp/rnskia/values/RNSkComputedValue.h +11 -11
- package/cpp/rnskia/values/RNSkReadonlyValue.h +19 -19
- package/cpp/rnskia/values/RNSkValue.h +13 -13
- package/cpp/utils/RNSkLog.h +4 -4
- package/lib/commonjs/renderer/HostConfig.js +17 -1
- package/lib/commonjs/renderer/HostConfig.js.map +1 -1
- package/lib/commonjs/views/SkiaView.js +11 -27
- package/lib/commonjs/views/SkiaView.js.map +1 -1
- package/lib/commonjs/views/types.js.map +1 -1
- package/lib/module/renderer/HostConfig.js +17 -1
- package/lib/module/renderer/HostConfig.js.map +1 -1
- package/lib/module/views/SkiaView.js +11 -26
- package/lib/module/views/SkiaView.js.map +1 -1
- package/lib/module/views/types.js.map +1 -1
- package/lib/typescript/src/views/SkiaView.d.ts +1 -11
- package/lib/typescript/src/views/types.d.ts +5 -5
- package/package.json +1 -1
- package/src/renderer/HostConfig.ts +11 -1
- package/src/views/SkiaView.tsx +17 -28
- package/src/views/types.ts +7 -6
@@ -2,10 +2,12 @@
|
|
2
2
|
|
3
3
|
#include <functional>
|
4
4
|
#include <memory>
|
5
|
+
#include <mutex>
|
5
6
|
#include <string>
|
6
7
|
#include <vector>
|
7
8
|
|
8
9
|
#include <JsiHostObject.h>
|
10
|
+
#include <JsiValueWrapper.h>
|
9
11
|
#include <RNSkDrawView.h>
|
10
12
|
#include <RNSkPlatformContext.h>
|
11
13
|
#include <RNSkValue.h>
|
@@ -14,96 +16,143 @@
|
|
14
16
|
namespace RNSkia {
|
15
17
|
using namespace facebook;
|
16
18
|
|
17
|
-
using
|
18
|
-
|
19
|
-
drawCallback = nullptr;
|
19
|
+
using RNSkViewInfo = struct RNSkViewInfo {
|
20
|
+
RNSkViewInfo() {
|
20
21
|
view = nullptr;
|
21
22
|
}
|
22
|
-
std::shared_ptr<FunctionWrapper> drawCallback;
|
23
23
|
std::shared_ptr<RNSkDrawView> view;
|
24
|
+
std::unordered_map<std::string, JsiValueWrapper> props;
|
24
25
|
};
|
25
26
|
|
26
|
-
class RNSkJsiViewApi : public JsiHostObject {
|
27
|
+
class RNSkJsiViewApi : public JsiHostObject, public std::enable_shared_from_this<RNSkJsiViewApi> {
|
27
28
|
public:
|
28
|
-
|
29
|
-
|
29
|
+
/**
|
30
|
+
Sets a custom property on a view given a view id. The property name/value will
|
31
|
+
be stored in a map alongside the id of the view and propagated to the view when
|
32
|
+
needed.
|
33
|
+
*/
|
34
|
+
JSI_HOST_FUNCTION(setJsiProperty) {
|
35
|
+
if (count != 3) {
|
30
36
|
_platformContext->raiseError(
|
31
|
-
std::string("
|
37
|
+
std::string("setJsiProperty: Expected 3 arguments, got " +
|
32
38
|
std::to_string(count) + "."));
|
33
39
|
return jsi::Value::undefined();
|
34
40
|
}
|
35
41
|
|
36
42
|
if (!arguments[0].isNumber()) {
|
37
43
|
_platformContext->raiseError(
|
38
|
-
"
|
44
|
+
"setJsiProperty: First argument must be a number");
|
39
45
|
return jsi::Value::undefined();
|
40
46
|
}
|
41
47
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
_platformContext->raiseError(
|
46
|
-
"setDrawCallback: Second argument must be a function");
|
47
|
-
return jsi::Value::undefined();
|
48
|
-
}
|
49
|
-
if (!arguments[1].asObject(runtime).isFunction(runtime)) {
|
50
|
-
_platformContext->raiseError(
|
51
|
-
"setDrawCallback: Second argument must be a function");
|
52
|
-
return jsi::Value::undefined();
|
53
|
-
}
|
54
|
-
}
|
55
|
-
|
56
|
-
// find skia draw view
|
57
|
-
int nativeId = arguments[0].asNumber();
|
48
|
+
if (!arguments[1].isString()) {
|
49
|
+
_platformContext->raiseError(
|
50
|
+
"setJsiProperty: Second argument must be the name of the property to set.");
|
58
51
|
|
59
|
-
|
60
|
-
auto info = getEnsuredCallbackInfo(nativeId);
|
61
|
-
if (arguments[1].isUndefined()) {
|
62
|
-
info->drawCallback = nullptr;
|
63
|
-
} else {
|
64
|
-
info->drawCallback = std::make_shared<FunctionWrapper>(
|
65
|
-
arguments[1].asObject(runtime).asFunction(runtime));
|
52
|
+
return jsi::Value::undefined();
|
66
53
|
}
|
54
|
+
auto nativeId = arguments[0].asNumber();
|
55
|
+
auto info = getEnsuredViewInfo(nativeId);
|
67
56
|
|
68
|
-
|
69
|
-
|
57
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
58
|
+
info->props.emplace(arguments[1].asString(runtime).utf8(runtime), JsiValueWrapper(runtime, arguments[2]));
|
59
|
+
|
60
|
+
// Now let's see if we have a view that we can update
|
61
|
+
if(info->view != nullptr) {
|
62
|
+
// Update view!
|
70
63
|
info->view->setNativeId(nativeId);
|
71
|
-
info->view->
|
64
|
+
info->view->setJsiProperties(info->props);
|
65
|
+
info->props.clear();
|
72
66
|
}
|
73
67
|
|
74
68
|
return jsi::Value::undefined();
|
75
69
|
}
|
76
70
|
|
77
|
-
|
78
|
-
|
71
|
+
/**
|
72
|
+
Calls a custom command / method on a view by the view id.
|
73
|
+
*/
|
74
|
+
JSI_HOST_FUNCTION(callJsiMethod) {
|
75
|
+
if (count < 2) {
|
79
76
|
_platformContext->raiseError(
|
80
|
-
std::string("
|
77
|
+
std::string("callCustomCommand: Expected at least 2 arguments, got " +
|
81
78
|
std::to_string(count) + "."));
|
79
|
+
|
82
80
|
return jsi::Value::undefined();
|
83
81
|
}
|
84
82
|
|
85
83
|
if (!arguments[0].isNumber()) {
|
86
84
|
_platformContext->raiseError(
|
87
|
-
"
|
85
|
+
"callCustomCommand: First argument must be a number");
|
86
|
+
|
88
87
|
return jsi::Value::undefined();
|
89
88
|
}
|
90
89
|
|
91
|
-
|
92
|
-
|
90
|
+
if (!arguments[1].isString()) {
|
91
|
+
_platformContext->raiseError(
|
92
|
+
"callCustomCommand: Second argument must be the name of the action to call.");
|
93
93
|
|
94
|
-
|
95
|
-
if (info->view != nullptr) {
|
96
|
-
info->view->requestRedraw();
|
94
|
+
return jsi::Value::undefined();
|
97
95
|
}
|
98
|
-
|
96
|
+
|
97
|
+
auto nativeId = arguments[0].asNumber();
|
98
|
+
auto action = arguments[1].asString(runtime).utf8(runtime);
|
99
|
+
|
100
|
+
auto info = getEnsuredViewInfo(nativeId);
|
101
|
+
|
102
|
+
if(info->view == nullptr) {
|
103
|
+
throw jsi::JSError(runtime,
|
104
|
+
std::string("callCustomCommand: Could not call action " + action +
|
105
|
+
" on view - view not ready.").c_str());
|
106
|
+
|
107
|
+
return jsi::Value::undefined();
|
108
|
+
}
|
109
|
+
|
110
|
+
// Get arguments
|
111
|
+
size_t paramsCount = count - 2;
|
112
|
+
const jsi::Value* params = paramsCount > 0 ? &arguments[2] : nullptr;
|
113
|
+
return info->view->callJsiMethod(runtime, action, params, paramsCount);
|
99
114
|
}
|
100
|
-
|
115
|
+
|
116
|
+
JSI_HOST_FUNCTION(requestRedraw) {
|
117
|
+
if (count < 2) {
|
118
|
+
_platformContext->raiseError(
|
119
|
+
std::string("requestRedraw: Expected 2 arguments, got " + std::to_string(count) + "."));
|
120
|
+
|
121
|
+
return jsi::Value::undefined();
|
122
|
+
}
|
123
|
+
|
124
|
+
if (!arguments[0].isNumber()) {
|
125
|
+
_platformContext->raiseError(
|
126
|
+
"requestRedraw: First argument must be a number");
|
127
|
+
|
128
|
+
return jsi::Value::undefined();
|
129
|
+
}
|
130
|
+
|
131
|
+
// find Skia View
|
132
|
+
int nativeId = arguments[0].asNumber();
|
133
|
+
|
134
|
+
auto info = getEnsuredViewInfo(nativeId);
|
135
|
+
if (info->view != nullptr) {
|
136
|
+
info->view->requestRedraw();
|
137
|
+
}
|
138
|
+
return jsi::Value::undefined();
|
139
|
+
}
|
140
|
+
|
101
141
|
JSI_HOST_FUNCTION(makeImageSnapshot) {
|
102
|
-
|
103
|
-
|
142
|
+
if (count < 1) {
|
143
|
+
_platformContext->raiseError(std::string("makeImageSnapshot: Expected at least 1 argument, got " + std::to_string(count) + "."));
|
144
|
+
return jsi::Value::undefined();
|
145
|
+
}
|
146
|
+
|
147
|
+
if (!arguments[0].isNumber()) {
|
148
|
+
_platformContext->raiseError("makeImageSnapshot: First argument must be a number");
|
149
|
+
return jsi::Value::undefined();
|
150
|
+
}
|
151
|
+
|
152
|
+
// find Skia view
|
104
153
|
int nativeId = arguments[0].asNumber();
|
105
154
|
sk_sp<SkImage> image;
|
106
|
-
auto info =
|
155
|
+
auto info = getEnsuredViewInfo(nativeId);
|
107
156
|
if (info->view != nullptr) {
|
108
157
|
if(count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()) {
|
109
158
|
auto rect = JsiSkRect::fromValue(runtime, arguments[1]);
|
@@ -112,88 +161,66 @@ public:
|
|
112
161
|
image = info->view->makeImageSnapshot(nullptr);
|
113
162
|
}
|
114
163
|
if(image == nullptr) {
|
115
|
-
jsi::
|
164
|
+
throw jsi::JSError(runtime, "Could not create image from current surface.");
|
116
165
|
return jsi::Value::undefined();
|
117
166
|
}
|
118
167
|
return jsi::Object::createFromHostObject(runtime, std::make_shared<JsiSkImage>(_platformContext, image));
|
119
168
|
}
|
120
|
-
jsi::
|
169
|
+
throw jsi::JSError(runtime, "No Skia View currently available.");
|
121
170
|
return jsi::Value::undefined();
|
122
171
|
}
|
123
|
-
|
124
|
-
JSI_HOST_FUNCTION(setDrawMode) {
|
125
|
-
if (count != 2) {
|
126
|
-
_platformContext->raiseError(
|
127
|
-
std::string("setDrawMode: Expected 2 arguments, got " +
|
128
|
-
std::to_string(count) + "."));
|
129
|
-
return jsi::Value::undefined();
|
130
|
-
}
|
131
172
|
|
132
|
-
if (!arguments[0].isNumber()) {
|
133
|
-
_platformContext->raiseError(
|
134
|
-
"setDrawMode: First argument must be a number");
|
135
|
-
return jsi::Value::undefined();
|
136
|
-
}
|
137
|
-
|
138
|
-
// find skia draw view
|
139
|
-
int nativeId = arguments[0].asNumber();
|
140
|
-
auto info = getEnsuredCallbackInfo(nativeId);
|
141
|
-
if (info->view != nullptr) {
|
142
|
-
auto nextMode = arguments[1].asString(runtime).utf8(runtime);
|
143
|
-
if(nextMode.compare("continuous") == 0) {
|
144
|
-
info->view->setDrawingMode(RNSkDrawingMode::Continuous);
|
145
|
-
} else {
|
146
|
-
info->view->setDrawingMode(RNSkDrawingMode::Default);
|
147
|
-
}
|
148
|
-
}
|
149
|
-
return jsi::Value::undefined();
|
150
|
-
}
|
151
|
-
|
152
173
|
JSI_HOST_FUNCTION(registerValuesInView) {
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
}
|
158
|
-
|
159
|
-
// Get identifier of native SkiaView
|
160
|
-
int nativeId = arguments[0].asNumber();
|
161
|
-
|
162
|
-
// Get values that should be added as dependencies
|
163
|
-
auto values = arguments[1].asObject(runtime).asArray(runtime);
|
164
|
-
std::vector<std::function<void()>> unsubscribers;
|
165
|
-
const std::size_t size = values.size(runtime);
|
166
|
-
unsubscribers.reserve(size);
|
167
|
-
for(size_t i=0; i<size; ++i) {
|
168
|
-
auto value = values.getValueAtIndex(runtime, i).asObject(runtime).asHostObject<RNSkReadonlyValue>(runtime);
|
169
|
-
|
170
|
-
if(value != nullptr) {
|
171
|
-
// Add change listener
|
172
|
-
unsubscribers.push_back(value->addListener([this, nativeId](jsi::Runtime&){
|
173
|
-
requestRedrawView(nativeId);
|
174
|
-
}));
|
174
|
+
// Check params
|
175
|
+
if(!arguments[1].isObject() || !arguments[1].asObject(runtime).isArray(runtime)) {
|
176
|
+
throw jsi::JSError(runtime, "Expected array of Values as second parameter");
|
177
|
+
return jsi::Value::undefined();
|
175
178
|
}
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
for(
|
186
|
-
|
179
|
+
|
180
|
+
// Get identifier of native SkiaView
|
181
|
+
int nativeId = arguments[0].asNumber();
|
182
|
+
|
183
|
+
// Get values that should be added as dependencies
|
184
|
+
auto values = arguments[1].asObject(runtime).asArray(runtime);
|
185
|
+
std::vector<std::function<void()>> unsubscribers;
|
186
|
+
const std::size_t size = values.size(runtime);
|
187
|
+
unsubscribers.reserve(size);
|
188
|
+
for(size_t i=0; i<size; ++i) {
|
189
|
+
auto value = values.getValueAtIndex(runtime, i).asObject(runtime).asHostObject<RNSkReadonlyValue>(runtime);
|
190
|
+
|
191
|
+
if(value != nullptr) {
|
192
|
+
// Add change listener
|
193
|
+
unsubscribers.push_back(value->addListener([weakSelf = weak_from_this(), nativeId](jsi::Runtime&){
|
194
|
+
auto self = weakSelf.lock();
|
195
|
+
if(self) {
|
196
|
+
auto info = self->getEnsuredViewInfo(nativeId);
|
197
|
+
if(info->view != nullptr) {
|
198
|
+
info->view->requestRedraw();
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}));
|
202
|
+
}
|
187
203
|
}
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
204
|
+
|
205
|
+
// Return unsubscribe method that unsubscribes to all values
|
206
|
+
// that we subscribed to.
|
207
|
+
return jsi::Function::createFromHostFunction(runtime,
|
208
|
+
jsi::PropNameID::forUtf8(runtime, "unsubscribe"),
|
209
|
+
0,
|
210
|
+
JSI_HOST_FUNCTION_LAMBDA {
|
211
|
+
// decrease dependency count on the Skia View
|
212
|
+
for(auto &unsub : unsubscribers) {
|
213
|
+
unsub();
|
214
|
+
}
|
215
|
+
return jsi::Value::undefined();
|
216
|
+
});
|
217
|
+
}
|
218
|
+
|
219
|
+
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(RNSkJsiViewApi, setJsiProperty),
|
220
|
+
JSI_EXPORT_FUNC(RNSkJsiViewApi, callJsiMethod),
|
221
|
+
JSI_EXPORT_FUNC(RNSkJsiViewApi, registerValuesInView),
|
222
|
+
JSI_EXPORT_FUNC(RNSkJsiViewApi, requestRedraw),
|
223
|
+
JSI_EXPORT_FUNC(RNSkJsiViewApi, makeImageSnapshot))
|
197
224
|
|
198
225
|
/**
|
199
226
|
* Constructor
|
@@ -203,7 +230,7 @@ public:
|
|
203
230
|
: JsiHostObject(), _platformContext(platformContext) {}
|
204
231
|
|
205
232
|
/**
|
206
|
-
* Invalidates the
|
233
|
+
* Invalidates the Skia View Api object
|
207
234
|
*/
|
208
235
|
void invalidate() {
|
209
236
|
unregisterAll();
|
@@ -214,11 +241,12 @@ public:
|
|
214
241
|
*/
|
215
242
|
void unregisterAll() {
|
216
243
|
// Unregister all views
|
217
|
-
auto tempList =
|
244
|
+
auto tempList = _viewInfos;
|
218
245
|
for (const auto& info : tempList) {
|
219
246
|
unregisterSkiaDrawView(info.first);
|
220
247
|
}
|
221
|
-
|
248
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
249
|
+
_viewInfos.clear();
|
222
250
|
}
|
223
251
|
|
224
252
|
/**
|
@@ -227,12 +255,12 @@ public:
|
|
227
255
|
* @param view View to register
|
228
256
|
*/
|
229
257
|
void registerSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view) {
|
230
|
-
auto info =
|
258
|
+
auto info = getEnsuredViewInfo(nativeId);
|
259
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
231
260
|
info->view = view;
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
}
|
261
|
+
info->view->setNativeId(nativeId);
|
262
|
+
info->view->setJsiProperties(info->props);
|
263
|
+
info->props.clear();
|
236
264
|
}
|
237
265
|
|
238
266
|
/**
|
@@ -240,37 +268,34 @@ public:
|
|
240
268
|
* @param nativeId View id
|
241
269
|
*/
|
242
270
|
void unregisterSkiaDrawView(size_t nativeId) {
|
243
|
-
if (
|
271
|
+
if (_viewInfos.count(nativeId) == 0) {
|
244
272
|
return;
|
245
273
|
}
|
246
|
-
auto info =
|
247
|
-
|
248
|
-
|
249
|
-
}
|
274
|
+
auto info = getEnsuredViewInfo(nativeId);
|
275
|
+
|
276
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
250
277
|
info->view = nullptr;
|
251
|
-
|
252
|
-
_callbackInfos.erase(nativeId);
|
278
|
+
_viewInfos.erase(nativeId);
|
253
279
|
}
|
254
|
-
|
280
|
+
|
255
281
|
/**
|
256
282
|
Sets a skia draw view for the given id. This function can be used
|
257
283
|
to mark that an underlying SkiaView is not available (it could be
|
258
284
|
removed due to ex. a transition). The view can be set to a nullptr
|
259
|
-
or a valid view, effectively toggling the view's availability.
|
260
|
-
a valid view is set, the setDrawCallback method is called on the
|
261
|
-
view (if a valid callback exists).
|
285
|
+
or a valid view, effectively toggling the view's availability.
|
262
286
|
*/
|
263
287
|
void setSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view) {
|
264
|
-
if (
|
288
|
+
if (_viewInfos.find(nativeId) == _viewInfos.end()) {
|
265
289
|
return;
|
266
290
|
}
|
267
|
-
auto info =
|
268
|
-
|
291
|
+
auto info = getEnsuredViewInfo(nativeId);
|
292
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
293
|
+
if (view != nullptr) {
|
269
294
|
info->view = view;
|
270
295
|
info->view->setNativeId(nativeId);
|
271
|
-
info->view->
|
272
|
-
|
273
|
-
|
296
|
+
info->view->setJsiProperties(info->props);
|
297
|
+
info->props.clear();
|
298
|
+
} else if(view == nullptr) {
|
274
299
|
info->view = view;
|
275
300
|
}
|
276
301
|
}
|
@@ -281,28 +306,17 @@ private:
|
|
281
306
|
* @param nativeId View id
|
282
307
|
* @return The callback info object for the requested view
|
283
308
|
*/
|
284
|
-
|
285
|
-
if (
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
return &_callbackInfos.at(nativeId);
|
290
|
-
}
|
291
|
-
|
292
|
-
/**
|
293
|
-
Send a redraw request to the view
|
294
|
-
*/
|
295
|
-
void requestRedrawView(size_t nativeId) {
|
296
|
-
auto info = getEnsuredCallbackInfo(nativeId);
|
297
|
-
if(info->view != nullptr) {
|
298
|
-
info->view->requestRedraw();
|
309
|
+
RNSkViewInfo *getEnsuredViewInfo(size_t nativeId) {
|
310
|
+
if (_viewInfos.count(nativeId) == 0) {
|
311
|
+
RNSkViewInfo info;
|
312
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
313
|
+
_viewInfos.emplace(nativeId, info);
|
299
314
|
}
|
315
|
+
return &_viewInfos.at(nativeId);
|
300
316
|
}
|
301
|
-
|
302
|
-
|
303
|
-
std::unordered_map<size_t, CallbackInfo> _callbackInfos;
|
304
|
-
|
305
|
-
// Platform context
|
317
|
+
|
318
|
+
std::unordered_map<size_t, RNSkViewInfo> _viewInfos;
|
306
319
|
std::shared_ptr<RNSkPlatformContext> _platformContext;
|
320
|
+
std::mutex _mutex;
|
307
321
|
};
|
308
322
|
} // namespace RNSkia
|
@@ -31,32 +31,32 @@ public:
|
|
31
31
|
// Verify input
|
32
32
|
if(!arguments[0].isObject() ||
|
33
33
|
!arguments[0].asObject(runtime).isFunction(runtime)) {
|
34
|
-
jsi::
|
34
|
+
throw jsi::JSError(runtime, "Expected callback function as first parameter");
|
35
35
|
}
|
36
|
-
|
36
|
+
|
37
37
|
if(!arguments[1].isObject() ||
|
38
38
|
!arguments[1].asObject(runtime).isArray(runtime)) {
|
39
|
-
jsi::
|
39
|
+
throw jsi::JSError(runtime, "Expected array of dependencies as second parameter");
|
40
40
|
}
|
41
|
-
|
41
|
+
|
42
42
|
// Get callback for calculating result
|
43
43
|
_callback = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
|
44
44
|
}
|
45
|
-
|
45
|
+
|
46
46
|
void invalidate() override {
|
47
47
|
RNSkReadonlyValue::invalidate();
|
48
|
-
|
48
|
+
|
49
49
|
// Unregister listeners
|
50
50
|
for(const auto &unsubscribe: _unsubscribers) {
|
51
51
|
unsubscribe();
|
52
52
|
}
|
53
53
|
_unsubscribers.clear();
|
54
54
|
}
|
55
|
-
|
55
|
+
|
56
56
|
void initializeDependencies(jsi::Runtime &runtime, const jsi::Value *arguments, size_t count) {
|
57
57
|
// Save dependencies
|
58
58
|
std::vector<std::shared_ptr<RNSkReadonlyValue>> dependencies;
|
59
|
-
|
59
|
+
|
60
60
|
// Ensure that all dependencies are Values
|
61
61
|
auto deps = arguments[1].asObject(runtime).asArray(runtime);
|
62
62
|
const std::size_t size = deps.size(runtime);
|
@@ -73,7 +73,7 @@ public:
|
|
73
73
|
}
|
74
74
|
dependencies.push_back(value);
|
75
75
|
}
|
76
|
-
|
76
|
+
|
77
77
|
// register change handler on dependencies
|
78
78
|
_unsubscribers.reserve(_unsubscribers.size() + size);
|
79
79
|
for(const auto &dep: dependencies) {
|
@@ -85,11 +85,11 @@ public:
|
|
85
85
|
}
|
86
86
|
}));
|
87
87
|
}
|
88
|
-
|
88
|
+
|
89
89
|
// Set initial value
|
90
90
|
dependencyUpdated(runtime);
|
91
91
|
}
|
92
|
-
|
92
|
+
|
93
93
|
private:
|
94
94
|
void dependencyUpdated(jsi::Runtime &runtime) {
|
95
95
|
// Calculate new value
|
@@ -29,7 +29,7 @@ public:
|
|
29
29
|
: JsiSkHostObject(platformContext),
|
30
30
|
_valueHolder(std::make_unique<JsiSimpleValueWrapper>(*platformContext->getJsRuntime()))
|
31
31
|
{ }
|
32
|
-
|
32
|
+
|
33
33
|
virtual ~RNSkReadonlyValue() {
|
34
34
|
invalidate();
|
35
35
|
}
|
@@ -37,21 +37,21 @@ public:
|
|
37
37
|
JSI_PROPERTY_GET(__typename__) {
|
38
38
|
return jsi::String::createFromUtf8(runtime, "RNSkValue");
|
39
39
|
}
|
40
|
-
|
40
|
+
|
41
41
|
JSI_PROPERTY_GET(current) {
|
42
42
|
return getCurrent(runtime);
|
43
43
|
}
|
44
|
-
|
44
|
+
|
45
45
|
JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(RNSkReadonlyValue, __typename__),
|
46
46
|
JSI_EXPORT_PROP_GET(RNSkReadonlyValue, current))
|
47
|
-
|
47
|
+
|
48
48
|
JSI_HOST_FUNCTION(addListener) {
|
49
49
|
if(!arguments[0].isObject() || !arguments[0].asObject(runtime).isFunction(runtime)) {
|
50
|
-
jsi::
|
50
|
+
throw jsi::JSError(runtime, "Expected function as first parameter.");
|
51
51
|
return jsi::Value::undefined();
|
52
52
|
}
|
53
53
|
auto callback = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
|
54
|
-
|
54
|
+
|
55
55
|
auto unsubscribe = addListener([weakSelf = weak_from_this(),
|
56
56
|
callback = std::move(callback)](jsi::Runtime& runtime){
|
57
57
|
auto self = weakSelf.lock();
|
@@ -60,7 +60,7 @@ public:
|
|
60
60
|
callback->call(runtime, selfReadonlyValue->get_current(runtime));
|
61
61
|
}
|
62
62
|
});
|
63
|
-
|
63
|
+
|
64
64
|
return jsi::Function::createFromHostFunction(runtime,
|
65
65
|
jsi::PropNameID::forUtf8(runtime, "unsubscribe"),
|
66
66
|
0,
|
@@ -69,17 +69,17 @@ public:
|
|
69
69
|
return jsi::Value::undefined();
|
70
70
|
});
|
71
71
|
}
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
|
73
|
+
|
74
|
+
|
75
75
|
JSI_HOST_FUNCTION(__invalidate) {
|
76
76
|
invalidate();
|
77
77
|
return jsi::Value::undefined();
|
78
78
|
}
|
79
|
-
|
79
|
+
|
80
80
|
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(RNSkReadonlyValue, addListener),
|
81
81
|
JSI_EXPORT_FUNC(RNSkReadonlyValue, __invalidate))
|
82
|
-
|
82
|
+
|
83
83
|
/**
|
84
84
|
* Adds a callback that will be called whenever the value changes
|
85
85
|
* @param cb Callback
|
@@ -96,7 +96,7 @@ public:
|
|
96
96
|
}
|
97
97
|
};
|
98
98
|
}
|
99
|
-
|
99
|
+
|
100
100
|
/**
|
101
101
|
Updates the underlying value and notifies all listeners about the change.
|
102
102
|
Listeners are only notified if the value was actually changed for numeric, boolean and string
|
@@ -111,7 +111,7 @@ public:
|
|
111
111
|
notifyListeners(runtime);
|
112
112
|
}
|
113
113
|
}
|
114
|
-
|
114
|
+
|
115
115
|
/**
|
116
116
|
Override to implement invalidation logic for the value. In the base class this function
|
117
117
|
clears all subscribers.
|
@@ -120,13 +120,13 @@ public:
|
|
120
120
|
std::lock_guard<std::mutex> lock(_mutex);
|
121
121
|
_listeners.clear();
|
122
122
|
}
|
123
|
-
|
123
|
+
|
124
124
|
jsi::Value getCurrent(jsi::Runtime &runtime) {
|
125
125
|
return _valueHolder->getCurrent(runtime);
|
126
126
|
}
|
127
|
-
|
127
|
+
|
128
128
|
protected:
|
129
|
-
|
129
|
+
|
130
130
|
/**
|
131
131
|
Notifies listeners about changes
|
132
132
|
@param runtime Current JS Runtime
|
@@ -141,7 +141,7 @@ protected:
|
|
141
141
|
listener.second(runtime);
|
142
142
|
}
|
143
143
|
}
|
144
|
-
|
144
|
+
|
145
145
|
/**
|
146
146
|
Removes a subscription listeners
|
147
147
|
@param listenerId identifier of listener to remove
|
@@ -153,7 +153,7 @@ protected:
|
|
153
153
|
|
154
154
|
private:
|
155
155
|
std::unique_ptr<JsiSimpleValueWrapper> _valueHolder;
|
156
|
-
|
156
|
+
|
157
157
|
long _listenerId = 0;
|
158
158
|
std::unordered_map<long, std::function<void(jsi::Runtime&)>> _listeners;
|
159
159
|
std::mutex _mutex;
|