@shopify/react-native-skia 2.0.2 → 2.0.3

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.
@@ -20,9 +20,6 @@ static __weak SkiaManager *sharedInstance = nil;
20
20
  }
21
21
 
22
22
  - (void)invalidate {
23
- if (_skManager != nullptr) {
24
- _skManager->invalidate();
25
- }
26
23
  _skManager = nullptr;
27
24
  }
28
25
 
@@ -3,6 +3,7 @@
3
3
  #include <functional>
4
4
  #include <memory>
5
5
  #include <mutex>
6
+ #include <shared_mutex>
6
7
  #include <string>
7
8
  #include <unordered_map>
8
9
  #include <utility>
@@ -23,6 +24,47 @@ using RNSkViewInfo = struct RNSkViewInfo {
23
24
  std::unordered_map<std::string, RNJsi::ViewProperty> props;
24
25
  };
25
26
 
27
+ class ViewRegistry {
28
+ public:
29
+ static ViewRegistry &getInstance() {
30
+ static ViewRegistry instance;
31
+ return instance;
32
+ }
33
+
34
+ ViewRegistry(const ViewRegistry &) = delete;
35
+ ViewRegistry &operator=(const ViewRegistry &) = delete;
36
+
37
+ void removeViewInfo(size_t id) {
38
+ std::unique_lock<std::shared_mutex> lock(_mutex);
39
+ _registry.erase(id);
40
+ }
41
+
42
+ // Execute a function while holding the registry lock
43
+ template<typename F>
44
+ auto withViewInfo(size_t id, F&& func) -> decltype(func(std::shared_ptr<RNSkViewInfo>())) {
45
+ std::unique_lock<std::shared_mutex> lock(_mutex);
46
+ auto it = _registry.find(id);
47
+ std::shared_ptr<RNSkViewInfo> info;
48
+ if (it != _registry.end()) {
49
+ info = it->second;
50
+ } else {
51
+ info = std::make_shared<RNSkViewInfo>();
52
+ _registry[id] = info;
53
+ }
54
+ return func(info);
55
+ }
56
+
57
+ void clear() {
58
+ std::unique_lock<std::shared_mutex> lock(_mutex);
59
+ _registry.clear();
60
+ }
61
+
62
+ private:
63
+ ViewRegistry() = default;
64
+ mutable std::shared_mutex _mutex;
65
+ std::unordered_map<size_t, std::shared_ptr<RNSkViewInfo>> _registry;
66
+ };
67
+
26
68
  class RNSkJsiViewApi : public RNJsi::JsiHostObject,
27
69
  public std::enable_shared_from_this<RNSkJsiViewApi> {
28
70
  public:
@@ -53,19 +95,21 @@ public:
53
95
  }
54
96
 
55
97
  auto nativeId = arguments[0].asNumber();
56
- std::lock_guard<std::mutex> lock(_mutex);
57
- auto info = getEnsuredViewInfo(nativeId);
58
-
59
- info->props.insert_or_assign(arguments[1].asString(runtime).utf8(runtime),
60
- RNJsi::ViewProperty(runtime, arguments[2]));
61
-
62
- // Now let's see if we have a view that we can update
63
- if (info->view != nullptr) {
64
- // Update view!
65
- info->view->setNativeId(nativeId);
66
- info->view->setJsiProperties(info->props);
67
- info->props.clear();
68
- }
98
+
99
+ // Safely execute operations while holding the registry lock
100
+ ViewRegistry::getInstance().withViewInfo(nativeId, [&](std::shared_ptr<RNSkViewInfo> info) {
101
+ info->props.insert_or_assign(arguments[1].asString(runtime).utf8(runtime),
102
+ RNJsi::ViewProperty(runtime, arguments[2]));
103
+
104
+ // Now let's see if we have a view that we can update
105
+ if (info->view != nullptr) {
106
+ // Update view!
107
+ info->view->setNativeId(nativeId);
108
+ info->view->setJsiProperties(info->props);
109
+ info->props.clear();
110
+ }
111
+ return nullptr; // Return type for template deduction
112
+ });
69
113
 
70
114
  return jsi::Value::undefined();
71
115
  }
@@ -88,11 +132,12 @@ public:
88
132
 
89
133
  // find Skia View
90
134
  int nativeId = arguments[0].asNumber();
91
- std::lock_guard<std::mutex> lock(_mutex);
92
- auto info = getEnsuredViewInfo(nativeId);
93
- if (info->view != nullptr) {
94
- info->view->requestRedraw();
95
- }
135
+ ViewRegistry::getInstance().withViewInfo(nativeId, [](std::shared_ptr<RNSkViewInfo> info) {
136
+ if (info->view != nullptr) {
137
+ info->view->requestRedraw();
138
+ }
139
+ return nullptr;
140
+ });
96
141
  return jsi::Value::undefined();
97
142
  }
98
143
 
@@ -113,12 +158,10 @@ public:
113
158
  // find Skia view
114
159
  int nativeId = arguments[0].asNumber();
115
160
  sk_sp<SkImage> image;
116
- std::shared_ptr<RNSkView> view;
117
- {
118
- std::lock_guard<std::mutex> lock(_mutex);
119
- auto info = getEnsuredViewInfo(nativeId);
120
- view = info->view;
121
- }
161
+ std::shared_ptr<RNSkView> view = ViewRegistry::getInstance().withViewInfo(nativeId,
162
+ [](std::shared_ptr<RNSkViewInfo> info) {
163
+ return info->view;
164
+ });
122
165
  if (view != nullptr) {
123
166
  if (count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()) {
124
167
  auto rect = JsiSkRect::fromValue(runtime, arguments[1]);
@@ -154,12 +197,10 @@ public:
154
197
 
155
198
  // find Skia view
156
199
  int nativeId = arguments[0].asNumber();
157
- std::shared_ptr<RNSkView> view;
158
- {
159
- std::lock_guard<std::mutex> lock(_mutex);
160
- auto info = getEnsuredViewInfo(nativeId);
161
- view = info->view;
162
- }
200
+ std::shared_ptr<RNSkView> view = ViewRegistry::getInstance().withViewInfo(nativeId,
201
+ [](std::shared_ptr<RNSkViewInfo> info) {
202
+ return info->view;
203
+ });
163
204
  auto context = _platformContext;
164
205
  auto bounds =
165
206
  count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()
@@ -205,8 +246,7 @@ public:
205
246
  Call to remove all draw view infos
206
247
  */
207
248
  void unregisterAll() {
208
- std::lock_guard<std::mutex> lock(_mutex);
209
- _viewInfos.clear();
249
+ ViewRegistry::getInstance().clear();
210
250
  }
211
251
 
212
252
  /**
@@ -215,12 +255,13 @@ public:
215
255
  * @param view View to register
216
256
  */
217
257
  void registerSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view) {
218
- std::lock_guard<std::mutex> lock(_mutex);
219
- auto info = getEnsuredViewInfo(nativeId);
220
- info->view = view;
221
- info->view->setNativeId(nativeId);
222
- info->view->setJsiProperties(info->props);
223
- info->props.clear();
258
+ ViewRegistry::getInstance().withViewInfo(nativeId, [&](std::shared_ptr<RNSkViewInfo> info) {
259
+ info->view = view;
260
+ info->view->setNativeId(nativeId);
261
+ info->view->setJsiProperties(info->props);
262
+ info->props.clear();
263
+ return nullptr;
264
+ });
224
265
  }
225
266
 
226
267
  /**
@@ -228,14 +269,7 @@ public:
228
269
  * @param nativeId View id
229
270
  */
230
271
  void unregisterSkiaView(size_t nativeId) {
231
- std::lock_guard<std::mutex> lock(_mutex);
232
- if (_viewInfos.count(nativeId) == 0) {
233
- return;
234
- }
235
- auto info = getEnsuredViewInfo(nativeId);
236
-
237
- info->view = nullptr;
238
- _viewInfos.erase(nativeId);
272
+ ViewRegistry::getInstance().removeViewInfo(nativeId);
239
273
  }
240
274
 
241
275
  /**
@@ -245,34 +279,20 @@ public:
245
279
  or a valid view, effectively toggling the view's availability.
246
280
  */
247
281
  void setSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view) {
248
- std::lock_guard<std::mutex> lock(_mutex);
249
- auto info = getEnsuredViewInfo(nativeId);
250
- if (view != nullptr) {
251
- info->view = view;
252
- info->view->setNativeId(nativeId);
253
- info->view->setJsiProperties(info->props);
254
- info->props.clear();
255
- } else if (view == nullptr) {
256
- info->view = view;
257
- }
282
+ ViewRegistry::getInstance().withViewInfo(nativeId, [&](std::shared_ptr<RNSkViewInfo> info) {
283
+ if (view != nullptr) {
284
+ info->view = view;
285
+ info->view->setNativeId(nativeId);
286
+ info->view->setJsiProperties(info->props);
287
+ info->props.clear();
288
+ } else {
289
+ info->view = view; // Set to nullptr
290
+ }
291
+ return nullptr;
292
+ });
258
293
  }
259
294
 
260
295
  private:
261
- /**
262
- * Creates or returns the callback info object for the given view
263
- * @param nativeId View id
264
- * @return The callback info object for the requested view
265
- */
266
- RNSkViewInfo *getEnsuredViewInfo(size_t nativeId) {
267
- if (_viewInfos.count(nativeId) == 0) {
268
- RNSkViewInfo info;
269
- _viewInfos.emplace(nativeId, info);
270
- }
271
- return &_viewInfos.at(nativeId);
272
- }
273
-
274
- std::unordered_map<size_t, RNSkViewInfo> _viewInfos;
275
296
  std::shared_ptr<RNSkPlatformContext> _platformContext;
276
- std::mutex _mutex;
277
297
  };
278
298
  } // namespace RNSkia
@@ -30,7 +30,6 @@ RNSkManager::RNSkManager(
30
30
  }
31
31
 
32
32
  RNSkManager::~RNSkManager() {
33
- invalidate();
34
33
  // Free up any references
35
34
  _viewApi = nullptr;
36
35
  _jsRuntime = nullptr;
@@ -38,36 +37,22 @@ RNSkManager::~RNSkManager() {
38
37
  _jsCallInvoker = nullptr;
39
38
  }
40
39
 
41
- void RNSkManager::invalidate() {
42
- if (_isInvalidated) {
43
- return;
44
- }
45
- _isInvalidated = true;
46
-
47
- // Invalidate members
48
- _viewApi->unregisterAll();
49
- }
50
-
51
40
  void RNSkManager::registerSkiaView(size_t nativeId,
52
41
  std::shared_ptr<RNSkView> view) {
53
- if (!_isInvalidated && _viewApi != nullptr)
54
- _viewApi->registerSkiaView(nativeId, std::move(view));
42
+ _viewApi->registerSkiaView(nativeId, std::move(view));
55
43
  }
56
44
 
57
45
  void RNSkManager::unregisterSkiaView(size_t nativeId) {
58
- if (!_isInvalidated && _viewApi != nullptr)
59
- _viewApi->unregisterSkiaView(nativeId);
46
+ _viewApi->unregisterSkiaView(nativeId);
60
47
  }
61
48
 
62
49
  void RNSkManager::setSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view) {
63
- if (!_isInvalidated && _viewApi != nullptr)
64
- _viewApi->setSkiaView(nativeId, std::move(view));
50
+ _viewApi->setSkiaView(nativeId, std::move(view));
65
51
  }
66
52
 
67
53
  void RNSkManager::installBindings() {
68
54
  // Create the API objects and install it on the global object in the
69
55
  // provided runtime.
70
-
71
56
  auto skiaApi = std::make_shared<JsiSkApi>(_platformContext);
72
57
  _jsRuntime->global().setProperty(
73
58
  *_jsRuntime, "SkiaApi",
@@ -33,11 +33,6 @@ public:
33
33
 
34
34
  ~RNSkManager();
35
35
 
36
- /**
37
- Invalidates the Skia Manager
38
- */
39
- void invalidate();
40
-
41
36
  /**
42
37
  * Registers a RNSkView with the given native id
43
38
  * @param nativeId Native view id
@@ -77,7 +72,6 @@ private:
77
72
  std::shared_ptr<RNSkPlatformContext> _platformContext;
78
73
  std::shared_ptr<facebook::react::CallInvoker> _jsCallInvoker;
79
74
  std::shared_ptr<RNSkJsiViewApi> _viewApi;
80
- std::atomic<bool> _isInvalidated = {false};
81
75
  };
82
76
 
83
77
  } // namespace RNSkia
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "setup-skia-web": "scripts/setup-canvaskit.js"
9
9
  },
10
10
  "title": "React Native Skia",
11
- "version": "2.0.2",
11
+ "version": "2.0.3",
12
12
  "description": "High-performance React Native Graphics using Skia",
13
13
  "main": "lib/module/index.js",
14
14
  "react-native": "src/index.ts",