@shopify/react-native-skia 0.1.180 → 0.1.181

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.
@@ -28,6 +28,11 @@ def safeExtGet(prop, fallback) {
28
28
 
29
29
  apply plugin: 'com.android.library'
30
30
 
31
+ def reactNativeArchitectures() {
32
+ def value = project.getProperties().get("reactNativeArchitectures")
33
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
34
+ }
35
+
31
36
  static def findNodeModules(baseDir) {
32
37
  def basePath = baseDir.toPath().normalize()
33
38
  // Node's module resolution algorithm searches up to the root directory,
@@ -119,7 +124,7 @@ android {
119
124
  externalNativeBuild {
120
125
  cmake {
121
126
  cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
122
- abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
127
+ abiFilters (*reactNativeArchitectures())
123
128
  arguments '-DANDROID_STL=c++_shared',
124
129
  "-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
125
130
  "-DNODE_MODULES_DIR=${nodeModules}",
@@ -1,5 +1,3 @@
1
- #pragma once
2
-
3
1
  #include "RuntimeAwareCache.h"
4
2
 
5
3
  namespace RNJsi {
@@ -22,7 +22,7 @@ RNSkDomRenderer::RNSkDomRenderer(std::function<void()> requestRedraw,
22
22
 
23
23
  RNSkDomRenderer::~RNSkDomRenderer() {
24
24
  if (_root != nullptr) {
25
- _root->dispose();
25
+ _root->dispose(true);
26
26
  _root = nullptr;
27
27
  }
28
28
  }
@@ -63,7 +63,7 @@ void RNSkDomRenderer::renderImmediate(
63
63
  void RNSkDomRenderer::setRoot(std::shared_ptr<JsiDomRenderNode> node) {
64
64
  std::lock_guard<std::mutex> lock(_rootLock);
65
65
  if (_root != nullptr) {
66
- _root->dispose();
66
+ _root->dispose(true);
67
67
  _root = nullptr;
68
68
  }
69
69
  _root = node;
@@ -112,8 +112,8 @@ public:
112
112
 
113
113
  /**
114
114
  * Creates an offscreen surface
115
- * @param width
116
- * @param height
115
+ * @param width width of the surface
116
+ * @param height height of the surface
117
117
  * @return sk_sp<SkSurface>
118
118
  */
119
119
  virtual sk_sp<SkSurface> makeOffscreenSurface(int width, int height) = 0;
@@ -23,8 +23,10 @@ class JsiDependencyManager
23
23
  public std::enable_shared_from_this<JsiDependencyManager> {
24
24
  public:
25
25
  JsiDependencyManager(std::shared_ptr<RNSkPlatformContext> context,
26
- jsi::Object &&registerValuesCallback)
27
- : _registerValuesCallback(std::move(registerValuesCallback)),
26
+ jsi::Runtime &runtime,
27
+ const jsi::Value &registerValuesCallback)
28
+ : _registerValuesCallback(std::make_shared<jsi::Object>(
29
+ registerValuesCallback.asObject(runtime))),
28
30
  JsiHostObject() {}
29
31
 
30
32
  ~JsiDependencyManager() { unsubscribeAll(); }
@@ -158,7 +160,7 @@ public:
158
160
  }
159
161
 
160
162
  // Call JS registerValues callback
161
- auto func = _registerValuesCallback.asFunction(runtime);
163
+ auto func = _registerValuesCallback->asFunction(runtime);
162
164
  _unregisterValues = std::make_shared<jsi::Object>(
163
165
  func.call(runtime, array, 1).asObject(runtime));
164
166
 
@@ -187,6 +189,8 @@ public:
187
189
 
188
190
  unsubscribeAll();
189
191
 
192
+ _registerValuesCallback = nullptr;
193
+
190
194
  return jsi::Value::undefined();
191
195
  }
192
196
 
@@ -203,8 +207,8 @@ public:
203
207
  return JSI_HOST_FUNCTION_LAMBDA {
204
208
  // Params: registerValues: (values: Array<SkiaValue<unknown>>) => () =>
205
209
  // void
206
- auto obj = std::make_shared<JsiDependencyManager>(
207
- context, getArgumentAsObject(runtime, arguments, count, 0));
210
+ auto obj = std::make_shared<JsiDependencyManager>(context, runtime,
211
+ arguments[0]);
208
212
 
209
213
  return jsi::Object::createFromHostObject(runtime, std::move(obj));
210
214
  };
@@ -283,7 +287,7 @@ private:
283
287
  return false;
284
288
  }
285
289
 
286
- jsi::Object _registerValuesCallback;
290
+ std::shared_ptr<jsi::Object> _registerValuesCallback;
287
291
  std::shared_ptr<jsi::Object> _unregisterValues;
288
292
  std::map<JsiDomNode *,
289
293
  std::vector<std::pair<std::shared_ptr<RNSkReadonlyValue>,
@@ -49,7 +49,19 @@ public:
49
49
  JsiDomNode(std::shared_ptr<RNSkPlatformContext> context, const char *type,
50
50
  NodeClass nodeClass)
51
51
  : _type(type), _context(context), _nodeClass(nodeClass),
52
- _nodeId(NodeIdent++), JsiHostObject() {}
52
+ _nodeId(NodeIdent++), JsiHostObject() {
53
+ #if SKIA_DOM_DEBUG
54
+ printDebugInfo("JsiDomNode." + std::string(_type) +
55
+ " CTOR - nodeId: " + std::to_string(_nodeId));
56
+ #endif
57
+ }
58
+
59
+ virtual ~JsiDomNode() {
60
+ #if SKIA_DOM_DEBUG
61
+ printDebugInfo("JsiDomNode." + std::string(_type) +
62
+ " DTOR - nodeId: " + std::to_string(_nodeId));
63
+ #endif
64
+ }
53
65
 
54
66
  /**
55
67
  Called when creating the node, resolves properties from the node constructor.
@@ -65,7 +77,7 @@ public:
65
77
  JSI_HOST_FUNCTION(setProps) {
66
78
  if (count == 1) {
67
79
  // Initialize properties container
68
- setProps(runtime, getArgumentAsObject(runtime, arguments, count, 0));
80
+ setProps(runtime, arguments[0]);
69
81
  } else {
70
82
  setEmptyProps();
71
83
  }
@@ -102,7 +114,7 @@ public:
102
114
  tree. Use for cleaning up.
103
115
  */
104
116
  JSI_HOST_FUNCTION(dispose) {
105
- dispose();
117
+ dispose(false);
106
118
  return jsi::Value::undefined();
107
119
  }
108
120
 
@@ -247,36 +259,9 @@ public:
247
259
  _propsContainer->markAsResolved();
248
260
  }
249
261
 
250
- // Now let's dispose if needed
262
+ // Now let's invalidate if needed
251
263
  if (_isDisposing && !_isDisposed) {
252
- _isDisposed = true;
253
-
254
- this->setParent(nullptr);
255
-
256
- // Callback signaling that we're done
257
- if (_disposeCallback != nullptr) {
258
- _disposeCallback();
259
- _disposeCallback = nullptr;
260
- }
261
-
262
- // Clear props
263
- if (_propsContainer != nullptr) {
264
- _propsContainer->dispose();
265
- }
266
-
267
- // Remove children
268
- std::vector<std::shared_ptr<JsiDomNode>> tmp;
269
- {
270
- std::lock_guard<std::mutex> lock(_childrenLock);
271
- tmp.reserve(_children.size());
272
- for (auto &child : _children) {
273
- tmp.push_back(child);
274
- }
275
- _children.clear();
276
- }
277
- for (auto &child : tmp) {
278
- child->dispose();
279
- }
264
+ invalidate();
280
265
  }
281
266
 
282
267
  // Resolve children
@@ -292,6 +277,22 @@ public:
292
277
  // Empty implementation
293
278
  }
294
279
 
280
+ /**
281
+ Called when a node has been removed from the dom tree and needs to be cleaned
282
+ up. If the invalidate parameter is set, we will invalidate the node directly.
283
+ Calling dispose from the JS dispose function calls this with invalidate set
284
+ to false, while the dom render view calls this with true.
285
+ */
286
+ virtual void dispose(bool immediate) {
287
+ if (_isDisposing) {
288
+ return;
289
+ }
290
+ _isDisposing = true;
291
+ if (immediate) {
292
+ invalidate();
293
+ }
294
+ }
295
+
295
296
  protected:
296
297
  /**
297
298
  Adds an operation that will be executed when the render cycle is finished.
@@ -319,24 +320,17 @@ protected:
319
320
 
320
321
  /**
321
322
  Native implementation of the set properties method. This is called from the
322
- reconciler when properties are set due to changes in React. This method will
323
- always call the onPropsSet method as a signal that things have changed.
323
+ reconciler when properties are set due to changes in React.
324
324
  */
325
- void setProps(jsi::Runtime &runtime, jsi::Object &&props) {
325
+ void setProps(jsi::Runtime &runtime, const jsi::Value &maybeProps) {
326
326
  #if SKIA_DOM_DEBUG
327
327
  printDebugInfo("JS:setProps(nodeId: " + std::to_string(_nodeId) + ")");
328
328
  #endif
329
- if (_propsContainer == nullptr) {
329
+ // Initialize properties container
330
+ ensurePropertyContainer();
330
331
 
331
- // Initialize properties container
332
- _propsContainer = std::make_shared<NodePropsContainer>(
333
- getType(), [=](BaseNodeProp *p) { onPropertyChanged(p); });
334
-
335
- // Ask sub classes to define their properties
336
- defineProperties(_propsContainer.get());
337
- }
338
332
  // Update properties container
339
- _propsContainer->setProps(runtime, std::move(props));
333
+ _propsContainer->setProps(runtime, maybeProps);
340
334
 
341
335
  // Invalidate context
342
336
  invalidateContext();
@@ -349,15 +343,8 @@ protected:
349
343
  #if SKIA_DOM_DEBUG
350
344
  printDebugInfo("JS:setEmptyProps(nodeId: " + std::to_string(_nodeId) + ")");
351
345
  #endif
352
- if (_propsContainer == nullptr) {
353
-
354
- // Initialize properties container
355
- _propsContainer = std::make_shared<NodePropsContainer>(
356
- getType(), [=](BaseNodeProp *p) { onPropertyChanged(p); });
357
-
358
- // Ask sub classes to define their properties
359
- defineProperties(_propsContainer.get());
360
- }
346
+ // Initialize properties container
347
+ ensurePropertyContainer();
361
348
  }
362
349
 
363
350
  /**
@@ -381,9 +368,12 @@ protected:
381
368
  printDebugInfo("JS:addChild(childId: " + std::to_string(child->_nodeId) +
382
369
  ")");
383
370
  #endif
384
- enqueAsynOperation([child, this]() {
385
- _children.push_back(child);
386
- child->setParent(this);
371
+ enqueAsynOperation([child, weakSelf = weak_from_this()]() {
372
+ auto self = weakSelf.lock();
373
+ if (self) {
374
+ self->_children.push_back(child);
375
+ child->setParent(self.get());
376
+ }
387
377
  });
388
378
  }
389
379
 
@@ -398,10 +388,14 @@ protected:
398
388
  "JS:insertChildBefore(childId: " + std::to_string(child->_nodeId) +
399
389
  ", beforeId: " + std::to_string(before->_nodeId) + ")");
400
390
  #endif
401
- enqueAsynOperation([child, before, this]() {
402
- auto position = std::find(_children.begin(), _children.end(), before);
403
- _children.insert(position, child);
404
- child->setParent(this);
391
+ enqueAsynOperation([child, before, weakSelf = weak_from_this()]() {
392
+ auto self = weakSelf.lock();
393
+ if (self) {
394
+ auto position =
395
+ std::find(self->_children.begin(), self->_children.end(), before);
396
+ self->_children.insert(position, child);
397
+ child->setParent(self.get());
398
+ }
405
399
  });
406
400
  }
407
401
 
@@ -414,27 +408,25 @@ protected:
414
408
  printDebugInfo("JS:removeChild(childId: " + std::to_string(child->_nodeId) +
415
409
  ")");
416
410
  #endif
417
- enqueAsynOperation([child, this]() {
418
- // Delete child itself
419
- _children.erase(
420
- std::remove_if(_children.begin(), _children.end(),
421
- [child](const auto &node) { return node == child; }),
422
- _children.end());
423
-
424
- child->dispose();
425
- });
426
- }
411
+ auto removeChild = [child,
412
+ weakSelf = weak_from_this()](bool immediate = false) {
413
+ auto self = weakSelf.lock();
414
+ if (self) {
415
+ // Delete child itself
416
+ self->_children.erase(
417
+ std::remove_if(self->_children.begin(), self->_children.end(),
418
+ [child](const auto &node) { return node == child; }),
419
+ self->_children.end());
420
+
421
+ child->dispose(immediate);
422
+ }
423
+ };
427
424
 
428
- /**
429
- Called when a node has been removed from the dom tree and needs to be cleaned
430
- up.
431
- */
432
- virtual void dispose() {
433
425
  if (_isDisposing) {
434
- return;
426
+ removeChild(false);
427
+ } else {
428
+ enqueAsynOperation(removeChild);
435
429
  }
436
-
437
- _isDisposing = true;
438
430
  }
439
431
 
440
432
  #if SKIA_DOM_DEBUG
@@ -477,6 +469,69 @@ protected:
477
469
  }
478
470
 
479
471
  private:
472
+ /**
473
+ Invalidates the node - meaning removing and clearing children and properties
474
+ **/
475
+ void invalidate() {
476
+ if (_isDisposing && !_isDisposed) {
477
+ #if SKIA_DOM_DEBUG
478
+ printDebugInfo("JsiDomNode::invalidate: nodeid: " +
479
+ std::to_string(_nodeId));
480
+ #endif
481
+
482
+ _isDisposed = true;
483
+
484
+ // Clear parent
485
+ this->setParent(nullptr);
486
+
487
+ // Clear any async operations
488
+ _queuedNodeOps.clear();
489
+
490
+ // Callback signaling that we're done
491
+ if (_disposeCallback != nullptr) {
492
+ _disposeCallback();
493
+ _disposeCallback = nullptr;
494
+ }
495
+
496
+ // Clear props
497
+ if (_propsContainer != nullptr) {
498
+ _propsContainer->dispose();
499
+ }
500
+
501
+ // Remove children
502
+ std::vector<std::shared_ptr<JsiDomNode>> tmp;
503
+ {
504
+ std::lock_guard<std::mutex> lock(_childrenLock);
505
+ tmp.reserve(_children.size());
506
+ for (auto &child : _children) {
507
+ tmp.push_back(child);
508
+ }
509
+ _children.clear();
510
+ }
511
+ for (auto &child : tmp) {
512
+ child->dispose(true);
513
+ }
514
+ }
515
+ }
516
+
517
+ /**
518
+ Creates and sets up the property container
519
+ */
520
+ void ensurePropertyContainer() {
521
+ if (_propsContainer == nullptr) {
522
+ _propsContainer = std::make_shared<NodePropsContainer>(
523
+ getType(), [weakSelf = weak_from_this()](BaseNodeProp *p) {
524
+ auto self = weakSelf.lock();
525
+ if (self) {
526
+ self->onPropertyChanged(p);
527
+ }
528
+ });
529
+
530
+ // Ask sub classes to define their properties
531
+ defineProperties(_propsContainer.get());
532
+ }
533
+ }
534
+
480
535
  const char *_type;
481
536
  std::shared_ptr<RNSkPlatformContext> _context;
482
537
 
@@ -132,19 +132,19 @@ public:
132
132
  */
133
133
  void resetPendingChanges() override { JsiDomNode::resetPendingChanges(); }
134
134
 
135
- /**
136
- Signal from the JS side that the node is removed from the dom.
137
- */
138
- void dispose() override { JsiDomNode::dispose(); }
139
-
140
135
  protected:
141
136
  /**
142
137
  Invalidates and marks then context as changed.
143
138
  */
144
139
  void invalidateContext() override {
145
- enqueAsynOperation([=]() {
146
- _paintCache.parent = nullptr;
147
- _paintCache.child = nullptr;
140
+ enqueAsynOperation([weakSelf = weak_from_this()]() {
141
+ auto self = weakSelf.lock();
142
+ if (self) {
143
+ std::static_pointer_cast<JsiDomRenderNode>(self)->_paintCache.parent =
144
+ nullptr;
145
+ std::static_pointer_cast<JsiDomRenderNode>(self)->_paintCache.child =
146
+ nullptr;
147
+ }
148
148
  });
149
149
  }
150
150
 
@@ -33,7 +33,7 @@ public:
33
33
  // readValueFromJS Function (which comes from the reconciler
34
34
  // setting a new property value on the property
35
35
  if (_value == nullptr) {
36
- _value = std::make_shared<JsiValue>(runtime, read(runtime, _name, this));
36
+ _value = std::make_unique<JsiValue>(runtime, read(runtime, _name, this));
37
37
  _isChanged = true;
38
38
  _hasNewValue = false;
39
39
  } else {
@@ -41,7 +41,7 @@ public:
41
41
  std::lock_guard<std::mutex> lock(_swapMutex);
42
42
  if (_buffer == nullptr) {
43
43
  _buffer =
44
- std::make_shared<JsiValue>(runtime, read(runtime, _name, this));
44
+ std::make_unique<JsiValue>(runtime, read(runtime, _name, this));
45
45
  } else {
46
46
  _buffer->setCurrent(runtime, read(runtime, _name, this));
47
47
  }
@@ -60,7 +60,7 @@ public:
60
60
  // and we don't want to rip out the underlying value object.
61
61
  std::lock_guard<std::mutex> lock(_swapMutex);
62
62
  if (_buffer == nullptr) {
63
- _buffer = std::make_shared<JsiValue>(runtime, value);
63
+ _buffer = std::make_unique<JsiValue>(runtime, value);
64
64
  } else {
65
65
  _buffer->setCurrent(runtime, value);
66
66
  }
@@ -129,8 +129,8 @@ private:
129
129
 
130
130
  std::function<void(BaseNodeProp *)> _onChange;
131
131
 
132
- std::shared_ptr<JsiValue> _value;
133
- std::shared_ptr<JsiValue> _buffer;
132
+ std::unique_ptr<JsiValue> _value;
133
+ std::unique_ptr<JsiValue> _buffer;
134
134
  std::atomic<bool> _isChanged = {false};
135
135
  std::atomic<bool> _hasNewValue = {false};
136
136
  std::mutex _swapMutex;
@@ -82,10 +82,16 @@ public:
82
82
  /**
83
83
  Called when the React / JS side sets properties on a node
84
84
  */
85
- void setProps(jsi::Runtime &runtime, jsi::Object &&props) {
85
+ void setProps(jsi::Runtime &runtime, const jsi::Value &maybePropsObject) {
86
86
  // Clear property mapping
87
87
  _mappedProperties.clear();
88
88
 
89
+ if (!maybePropsObject.isObject()) {
90
+ throw jsi::JSError(runtime, "Expected property object.");
91
+ }
92
+
93
+ auto props = maybePropsObject.asObject(runtime);
94
+
89
95
  // Use specialized reader function to be able to intercept calls that
90
96
  // reads specific named values from the js property object.
91
97
  auto read = [&](jsi::Runtime &runtime, PropId name, NodeProp *prop) {
@@ -22,43 +22,36 @@ public:
22
22
  explicit ClipProp(PropId name,
23
23
  const std::function<void(BaseNodeProp *)> &onChange)
24
24
  : BaseDerivedProp(onChange) {
25
- _pathProp = defineProperty<PathProp>(name);
26
- _rectProp = defineProperty<RectProp>(name);
27
- _rrectProp = defineProperty<RRectProp>(name);
25
+ _clipProp = defineProperty<NodeProp>(name);
28
26
  }
29
27
 
30
28
  void updateDerivedValue() override {
31
- if (_pathProp->isSet()) {
32
- _rect = nullptr;
33
- _rrect = nullptr;
34
- _path = _pathProp->getDerivedValue();
35
- } else if (_rrectProp->isSet()) {
36
- _rect = nullptr;
37
- _rrect = _rrectProp->getDerivedValue();
38
- _path = nullptr;
39
- } else if (_rectProp->isSet()) {
40
- _rect = _rectProp->getDerivedValue();
29
+ if (_clipProp->isSet()) {
30
+ auto value = _clipProp->value();
31
+ _rect = RectProp::processRect(value);
41
32
  _rrect = nullptr;
42
33
  _path = nullptr;
34
+ if (!_rect) {
35
+ _path = PathProp::processPath(value);
36
+ if (!_path) {
37
+ _rrect = RRectProp::processRRect(value);
38
+ }
39
+ }
43
40
  }
44
41
  }
45
42
 
46
- bool isSet() override {
47
- return _pathProp->isSet() || _rectProp->isSet() || _rrectProp->isSet();
48
- }
43
+ bool isSet() override { return _clipProp->isSet(); }
49
44
 
50
45
  const SkPath *getPath() { return _path.get(); }
51
46
  const SkRect *getRect() { return _rect.get(); }
52
47
  const SkRRect *getRRect() { return _rrect.get(); }
53
48
 
54
49
  private:
55
- PathProp *_pathProp;
56
- RectProp *_rectProp;
57
- RRectProp *_rrectProp;
50
+ NodeProp *_clipProp;
58
51
 
59
52
  std::shared_ptr<const SkPath> _path;
60
53
  std::shared_ptr<const SkRect> _rect;
61
54
  std::shared_ptr<const SkRRect> _rrect;
62
55
  };
63
56
 
64
- } // namespace RNSkia
57
+ } // namespace RNSkia
@@ -22,32 +22,34 @@ public:
22
22
  _pathProp = defineProperty<NodeProp>(name);
23
23
  }
24
24
 
25
- void updateDerivedValue() override {
26
- if (!_pathProp->isSet()) {
27
- setDerivedValue(nullptr);
28
- return;
29
- }
30
-
31
- if (_pathProp->value().getType() == PropType::HostObject) {
25
+ static std::shared_ptr<SkPath> processPath(const JsiValue &value) {
26
+ if (value.getType() == PropType::HostObject) {
32
27
  // Try reading as Path
33
- auto ptr = std::dynamic_pointer_cast<JsiSkPath>(
34
- _pathProp->value().getAsHostObject());
28
+ auto ptr = std::dynamic_pointer_cast<JsiSkPath>(value.getAsHostObject());
35
29
  if (ptr != nullptr) {
36
- setDerivedValue(ptr->getObject());
30
+ return ptr->getObject();
37
31
  }
38
- } else if (_pathProp->value().getType() == PropType::String) {
32
+ } else if (value.getType() == PropType::String) {
39
33
  // Read as string
40
- auto pathString = _pathProp->value().getAsString();
34
+ auto pathString = value.getAsString();
41
35
  SkPath result;
42
36
 
43
37
  if (SkParsePath::FromSVGString(pathString.c_str(), &result)) {
44
- setDerivedValue(std::make_shared<SkPath>(result));
38
+ return std::make_shared<SkPath>(result);
45
39
  } else {
46
40
  throw std::runtime_error("Could not parse path from string.");
47
41
  }
48
- } else {
42
+ }
43
+ return nullptr;
44
+ }
45
+
46
+ void updateDerivedValue() override {
47
+ if (!_pathProp->isSet()) {
49
48
  setDerivedValue(nullptr);
49
+ return;
50
50
  }
51
+ auto value = _pathProp->value();
52
+ setDerivedValue(PathProp::processPath(value));
51
53
  }
52
54
 
53
55
  private:
@@ -29,7 +29,7 @@ public:
29
29
  void updateDerivedValue() override {
30
30
  if (_pointProp->isSet()) {
31
31
  // Check for JsiSkRect and JsiSkPoint
32
- setDerivedValue(std::move(processValue(_pointProp->value())));
32
+ setDerivedValue(processValue(_pointProp->value()));
33
33
  } else {
34
34
  setDerivedValue(nullptr);
35
35
  }
@@ -33,35 +33,33 @@ public:
33
33
  _prop = defineProperty<NodeProp>(name);
34
34
  }
35
35
 
36
- void updateDerivedValue() override {
37
- if (_prop->isSet()) {
38
- // Check for JsiSkRRect
39
- if (_prop->value().getType() == PropType::HostObject) {
40
- // Try reading as rect
41
- auto rectPtr = std::dynamic_pointer_cast<JsiSkRRect>(
42
- _prop->value().getAsHostObject());
43
- if (rectPtr != nullptr) {
44
- auto rrect = rectPtr->getObject();
45
- setDerivedValue(SkRRect::MakeRectXY(
46
- SkRect::MakeXYWH(rrect->rect().x(), rrect->rect().y(),
47
- rrect->rect().width(), rrect->rect().height()),
48
- rrect->getSimpleRadii().x(), rrect->getSimpleRadii().y()));
49
- }
50
- } else {
51
- if (_prop->isSet() && _prop->value().getType() == PropType::Object) {
52
- auto p = _prop->value();
53
- if (p.hasValue(PropNameX) && p.hasValue(PropNameY) &&
54
- p.hasValue(PropNameWidth) && p.hasValue(PropNameHeight) &&
55
- p.hasValue(PropNameRx) && p.hasValue(PropNameRy)) {
56
- auto x = _prop->value().getValue(PropNameX);
57
- auto y = _prop->value().getValue(PropNameY);
58
- auto width = _prop->value().getValue(PropNameWidth);
59
- auto height = _prop->value().getValue(PropNameHeight);
60
- auto rx = _prop->value().getValue(PropNameRx);
61
- auto ry = _prop->value().getValue(PropNameRy);
36
+ static std::shared_ptr<SkRRect> processRRect(const JsiValue &value) {
37
+ if (value.getType() == PropType::HostObject) {
38
+ // Try reading as rect
39
+ auto rectPtr =
40
+ std::dynamic_pointer_cast<JsiSkRRect>(value.getAsHostObject());
41
+ if (rectPtr != nullptr) {
42
+ auto rrect = rectPtr->getObject();
43
+ return std::make_shared<SkRRect>(
44
+ SkRRect::MakeRectXY(rrect->rect(), rrect->getSimpleRadii().x(),
45
+ rrect->getSimpleRadii().y()));
46
+ }
47
+ } else {
48
+ if (value.getType() == PropType::Object) {
49
+ if (value.hasValue(PropNameRect) && value.hasValue(PropNameRx) &&
50
+ value.hasValue(PropNameRy)) {
51
+ auto rect = value.getValue(PropNameRect);
52
+ if (rect.hasValue(PropNameX) && rect.hasValue(PropNameY) &&
53
+ rect.hasValue(PropNameWidth) && rect.hasValue(PropNameHeight)) {
54
+ auto x = rect.getValue(PropNameX);
55
+ auto y = rect.getValue(PropNameY);
56
+ auto width = rect.getValue(PropNameWidth);
57
+ auto height = rect.getValue(PropNameHeight);
58
+ auto rx = value.getValue(PropNameRx);
59
+ auto ry = value.getValue(PropNameRy);
62
60
 
63
61
  // Update cache from js object value
64
- setDerivedValue(SkRRect::MakeRectXY(
62
+ return std::make_shared<SkRRect>(SkRRect::MakeRectXY(
65
63
  SkRect::MakeXYWH(x.getAsNumber(), y.getAsNumber(),
66
64
  width.getAsNumber(), height.getAsNumber()),
67
65
  rx.getAsNumber(), ry.getAsNumber()));
@@ -69,6 +67,14 @@ public:
69
67
  }
70
68
  }
71
69
  }
70
+ return nullptr;
71
+ }
72
+
73
+ void updateDerivedValue() override {
74
+ if (_prop->isSet()) {
75
+ auto value = _prop->value();
76
+ setDerivedValue(RRectProp::processRRect(value));
77
+ }
72
78
  }
73
79
 
74
80
  private:
@@ -150,40 +156,12 @@ public:
150
156
  }
151
157
 
152
158
  void updateDerivedValue() override {
153
- if (_boxProp->value().getType() == PropType::HostObject) {
154
- auto rectPtr = std::dynamic_pointer_cast<JsiSkRect>(
155
- _boxProp->value().getAsHostObject());
156
- auto rrectPtr = std::dynamic_pointer_cast<JsiSkRRect>(
157
- _boxProp->value().getAsHostObject());
158
- // 1. box is SkRect
159
- if (rectPtr != nullptr) {
160
- auto rect = rectPtr->getObject();
161
- setDerivedValue(SkRRect::MakeRect(*rect));
162
- // 2. box is SkRRect
163
- } else if (rrectPtr != nullptr) {
164
- setDerivedValue(rrectPtr->getObject());
165
- }
166
- } else if (_boxProp->value().getType() == PropType::Object) {
167
- if (_boxProp->value().hasValue(PropNameRect)) {
168
- // 3. box is { rect: { x, y, width, height }, rx, ry }
169
- auto rectProp = _boxProp->value().getValue(PropNameRect);
170
- auto x = rectProp.getValue(PropNameX).getAsNumber();
171
- auto y = rectProp.getValue(PropNameY).getAsNumber();
172
- auto width = rectProp.getValue(PropNameWidth).getAsNumber();
173
- auto height = rectProp.getValue(PropNameHeight).getAsNumber();
174
- auto rx = _boxProp->value().getValue(PropNameRx).getAsNumber();
175
- auto ry = _boxProp->value().getValue(PropNameRy).getAsNumber();
176
- setDerivedValue(
177
- SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, width, height), rx, ry));
178
- } else {
179
- // 4. box is { x, y, width, height }
180
- auto x = _boxProp->value().getValue(PropNameX).getAsNumber();
181
- auto y = _boxProp->value().getValue(PropNameY).getAsNumber();
182
- auto width = _boxProp->value().getValue(PropNameWidth).getAsNumber();
183
- auto height = _boxProp->value().getValue(PropNameHeight).getAsNumber();
184
- setDerivedValue(
185
- SkRRect::MakeRect(SkRect::MakeXYWH(x, y, width, height)));
186
- }
159
+ auto value = _boxProp->value();
160
+ auto rect = RectProp::processRect(value);
161
+ if (rect) {
162
+ setDerivedValue(SkRRect::MakeRect(*rect));
163
+ } else {
164
+ setDerivedValue(RRectProp::processRRect(value));
187
165
  }
188
166
  }
189
167
 
@@ -31,33 +31,35 @@ public:
31
31
  _prop = defineProperty<NodeProp>(name);
32
32
  }
33
33
 
34
+ static std::shared_ptr<SkRect> processRect(const JsiValue &value) {
35
+ if (value.getType() == PropType::HostObject) {
36
+ auto rectPtr =
37
+ std::dynamic_pointer_cast<JsiSkRect>(value.getAsHostObject());
38
+ if (rectPtr != nullptr) {
39
+ return std::make_shared<SkRect>(SkRect::MakeXYWH(
40
+ rectPtr->getObject()->x(), rectPtr->getObject()->y(),
41
+ rectPtr->getObject()->width(), rectPtr->getObject()->height()));
42
+ }
43
+ } else if (value.getType() == PropType::Object &&
44
+ value.hasValue(PropNameX) && value.hasValue(PropNameY) &&
45
+ value.hasValue(PropNameWidth) &&
46
+ value.hasValue(PropNameHeight)) {
47
+ // Save props for fast access
48
+ auto x = value.getValue(PropNameX);
49
+ auto y = value.getValue(PropNameY);
50
+ auto width = value.getValue(PropNameWidth);
51
+ auto height = value.getValue(PropNameHeight);
52
+ // Update cache from js object value
53
+ return std::make_shared<SkRect>(
54
+ SkRect::MakeXYWH(x.getAsNumber(), y.getAsNumber(),
55
+ width.getAsNumber(), height.getAsNumber()));
56
+ }
57
+ return nullptr;
58
+ }
59
+
34
60
  void updateDerivedValue() override {
35
61
  if (_prop->isSet()) {
36
- // Check for JsiSkRect
37
- if (_prop->value().getType() == PropType::HostObject) {
38
- auto rectPtr = std::dynamic_pointer_cast<JsiSkRect>(
39
- _prop->value().getAsHostObject());
40
- if (rectPtr != nullptr) {
41
- setDerivedValue(SkRect::MakeXYWH(
42
- rectPtr->getObject()->x(), rectPtr->getObject()->y(),
43
- rectPtr->getObject()->width(), rectPtr->getObject()->height()));
44
- }
45
- } else {
46
- auto p = _prop->value();
47
- if (p.hasValue(PropNameX) && p.hasValue(PropNameY) &&
48
- p.hasValue(PropNameWidth) && p.hasValue(PropNameHeight)) {
49
- // Save props for fast access
50
- auto x = p.getValue(PropNameX);
51
- auto y = p.getValue(PropNameY);
52
- auto width = p.getValue(PropNameWidth);
53
- auto height = p.getValue(PropNameHeight);
54
-
55
- // Update cache from js object value
56
- setDerivedValue(SkRect::MakeXYWH(x.getAsNumber(), y.getAsNumber(),
57
- width.getAsNumber(),
58
- height.getAsNumber()));
59
- }
60
- }
62
+ setDerivedValue(RectProp::processRect(_prop->value()));
61
63
  }
62
64
  }
63
65
 
@@ -4,7 +4,6 @@
4
4
  #include <thread>
5
5
  #include <utility>
6
6
 
7
- #include <RNSkMeasureTime.h>
8
7
  #include <SkiaMetalRenderer.h>
9
8
 
10
9
  #pragma clang diagnostic push
@@ -20,7 +19,6 @@ void RNSkiOSPlatformContext::performStreamOperation(
20
19
  const std::string &sourceUri,
21
20
  const std::function<void(std::unique_ptr<SkStreamAsset>)> &op) {
22
21
 
23
- RNSkMeasureTime("PlatformContext::performStreamOperation");
24
22
  auto loader = [=]() {
25
23
  NSURL *url = [[NSURL alloc]
26
24
  initWithString:[NSString stringWithUTF8String:sourceUri.c_str()]];
@@ -103,8 +103,12 @@ class SkiaBaseWebView extends _react.default.Component {
103
103
  }
104
104
 
105
105
  componentWillUnmount() {
106
+ var _this$_canvasRef$curr, _this$_canvasRef$curr2, _this$_canvasRef$curr3;
107
+
106
108
  this.unsubscribeAll();
107
- cancelAnimationFrame(this.requestId);
109
+ cancelAnimationFrame(this.requestId); // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
110
+
111
+ (_this$_canvasRef$curr = this._canvasRef.current) === null || _this$_canvasRef$curr === void 0 ? void 0 : (_this$_canvasRef$curr2 = _this$_canvasRef$curr.getContext("webgl2")) === null || _this$_canvasRef$curr2 === void 0 ? void 0 : (_this$_canvasRef$curr3 = _this$_canvasRef$curr2.getExtension("WEBGL_lose_context")) === null || _this$_canvasRef$curr3 === void 0 ? void 0 : _this$_canvasRef$curr3.loseContext();
108
112
  }
109
113
  /**
110
114
  * Creates a snapshot from the canvas in the surface
@@ -1 +1 @@
1
- {"version":3,"names":["pd","PixelRatio","get","SkiaBaseWebView","React","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","JsiSkSurface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","TouchType","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["pd","PixelRatio","get","SkiaBaseWebView","React","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","JsiSkSurface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","getContext","getExtension","loseContext","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","TouchType","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context\n this._canvasRef.current\n ?.getContext(\"webgl2\")\n ?.getExtension(\"WEBGL_lose_context\")\n ?.loseContext();\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
@@ -92,8 +92,12 @@ export class SkiaBaseWebView extends React.Component {
92
92
  }
93
93
 
94
94
  componentWillUnmount() {
95
+ var _this$_canvasRef$curr, _this$_canvasRef$curr2, _this$_canvasRef$curr3;
96
+
95
97
  this.unsubscribeAll();
96
- cancelAnimationFrame(this.requestId);
98
+ cancelAnimationFrame(this.requestId); // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
99
+
100
+ (_this$_canvasRef$curr = this._canvasRef.current) === null || _this$_canvasRef$curr === void 0 ? void 0 : (_this$_canvasRef$curr2 = _this$_canvasRef$curr.getContext("webgl2")) === null || _this$_canvasRef$curr2 === void 0 ? void 0 : (_this$_canvasRef$curr3 = _this$_canvasRef$curr2.getExtension("WEBGL_lose_context")) === null || _this$_canvasRef$curr3 === void 0 ? void 0 : _this$_canvasRef$curr3.loseContext();
97
101
  }
98
102
  /**
99
103
  * Creates a snapshot from the canvas in the surface
@@ -1 +1 @@
1
- {"version":3,"names":["React","PixelRatio","View","JsiSkSurface","TouchType","pd","get","SkiaBaseWebView","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["React","PixelRatio","View","JsiSkSurface","TouchType","pd","get","SkiaBaseWebView","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","getContext","getExtension","loseContext","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context\n this._canvasRef.current\n ?.getContext(\"webgl2\")\n ?.getExtension(\"WEBGL_lose_context\")\n ?.loseContext();\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "setup-skia-web": "./scripts/setup-canvaskit.js"
8
8
  },
9
9
  "title": "React Native Skia",
10
- "version": "0.1.180",
10
+ "version": "0.1.181",
11
11
  "description": "High-performance React Native Graphics using Skia",
12
12
  "main": "lib/module/index.js",
13
13
  "files": [
@@ -78,6 +78,11 @@ export abstract class SkiaBaseWebView<
78
78
  componentWillUnmount() {
79
79
  this.unsubscribeAll();
80
80
  cancelAnimationFrame(this.requestId);
81
+ // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
82
+ this._canvasRef.current
83
+ ?.getContext("webgl2")
84
+ ?.getExtension("WEBGL_lose_context")
85
+ ?.loseContext();
81
86
  }
82
87
 
83
88
  /**