@shopify/react-native-skia 0.1.145 → 0.1.146

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,7 +29,7 @@ namespace RNSkia
29
29
  {
30
30
  if (contourMeasure == nullptr)
31
31
  {
32
- jsi::detail::throwJSError(*context->getJsRuntime(), "Contour measure is null");
32
+ throw jsi::JSError(*context->getJsRuntime(), "Contour measure is null");
33
33
  }
34
34
  };
35
35
 
@@ -41,7 +41,7 @@ namespace RNSkia
41
41
  auto result = getObject()->getPosTan(dist, &position, &tangent);
42
42
  if (!result)
43
43
  {
44
- jsi::detail::throwJSError(runtime, "getSegment() failed");
44
+ throw jsi::JSError(runtime, "getSegment() failed");
45
45
  }
46
46
  auto posTan = jsi::Object(runtime);
47
47
  posTan.setProperty(runtime, "px", position.x());
@@ -70,7 +70,7 @@ namespace RNSkia
70
70
  auto result = getObject()->getSegment(start, end, &path, startWithMoveTo);
71
71
  if (!result)
72
72
  {
73
- jsi::detail::throwJSError(runtime, "getSegment() failed");
73
+ throw jsi::JSError(runtime, "getSegment() failed");
74
74
  }
75
75
  return JsiSkPath::toValue(runtime, getContext(), std::move(path));
76
76
  }
@@ -99,4 +99,4 @@ namespace RNSkia
99
99
  ->getObject();
100
100
  }
101
101
  };
102
- } // namespace RNSkia
102
+ } // namespace RNSkia
@@ -64,7 +64,7 @@ namespace RNSkia {
64
64
  size_t len;
65
65
  auto err = SkBase64::Decode(&base64.utf8(runtime).c_str()[0], size, nullptr, &len);
66
66
  if(err != SkBase64::Error::kNoError) {
67
- jsi::detail::throwJSError(runtime, "Error decoding base64 string");
67
+ throw jsi::JSError(runtime, "Error decoding base64 string");
68
68
  return jsi::Value::undefined();
69
69
  }
70
70
 
@@ -72,10 +72,10 @@ namespace RNSkia {
72
72
  auto data = SkData::MakeUninitialized(len);
73
73
  err = SkBase64::Decode(&base64.utf8(runtime).c_str()[0], size, data->writable_data(), &len);
74
74
  if(err != SkBase64::Error::kNoError) {
75
- jsi::detail::throwJSError(runtime, "Error decoding base64 string");
75
+ throw jsi::JSError(runtime, "Error decoding base64 string");
76
76
  return jsi::Value::undefined();
77
77
  }
78
-
78
+
79
79
  return jsi::Object::createFromHostObject(runtime,
80
80
  std::make_shared<JsiSkData>(
81
81
  getContext(), std::move(data)));
@@ -152,7 +152,7 @@ namespace RNSkia
152
152
 
153
153
  if (glyphs.size() > positions.size())
154
154
  {
155
- jsi::detail::throwJSError(runtime, "Not enough x,y position pairs for glyphs");
155
+ throw jsi::JSError(runtime, "Not enough x,y position pairs for glyphs");
156
156
  return jsi::Value::null();
157
157
  }
158
158
  auto sects = getObject()->getIntercepts(glyphs.data(), SkToInt(glyphs.size()), positions.data(), top, bottom);
@@ -41,7 +41,7 @@ public:
41
41
  SkPath result;
42
42
 
43
43
  if (!SkParsePath::FromSVGString(svgString.c_str(), &result)) {
44
- jsi::detail::throwJSError(runtime, "Could not parse Svg path");
44
+ throw jsi::JSError(runtime, "Could not parse Svg path");
45
45
  return jsi::Value(nullptr);
46
46
  }
47
47
 
@@ -22,7 +22,7 @@ class JsiSkPictureFactory : public JsiSkHostObject {
22
22
  public:
23
23
  JSI_HOST_FUNCTION(MakePicture) {
24
24
  if(!arguments[0].isObject()) {
25
- jsi::detail::throwJSError(runtime, "Expected arraybuffer as first parameter");
25
+ throw jsi::JSError(runtime, "Expected arraybuffer as first parameter");
26
26
  }
27
27
  auto array = arguments[0].asObject(runtime);
28
28
  jsi::ArrayBuffer buffer = array
@@ -35,7 +35,7 @@ namespace RNSkia
35
35
  : public JsiSkWrappingSkPtrHostObject<SkRuntimeEffect>
36
36
  {
37
37
  public:
38
-
38
+
39
39
  static sk_sp<SkRuntimeEffect> fromValue(jsi::Runtime &runtime, const jsi::Value &obj) {
40
40
  const auto& object = obj.asObject(runtime);
41
41
  return object.asHostObject<JsiSkRuntimeEffect>(runtime)->getObject();
@@ -44,7 +44,7 @@ namespace RNSkia
44
44
  JSI_HOST_FUNCTION(makeShader)
45
45
  {
46
46
  auto uniforms = castUniforms(runtime, arguments[0]);
47
-
47
+
48
48
  auto matrix = count >= 2 && !arguments[1].isUndefined() && !arguments[1].isNull() ? JsiSkMatrix::fromValue(runtime, arguments[1]).get() : nullptr;
49
49
 
50
50
  // Create and return shader as host object
@@ -57,7 +57,7 @@ namespace RNSkia
57
57
  JSI_HOST_FUNCTION(makeShaderWithChildren)
58
58
  {
59
59
  auto uniforms = castUniforms(runtime, arguments[0]);
60
-
60
+
61
61
  // Children
62
62
  std::vector<sk_sp<SkShader>> children;
63
63
  auto jsiChildren = arguments[1].asObject(runtime).asArray(runtime);
@@ -96,7 +96,7 @@ namespace RNSkia
96
96
  {
97
97
  auto i = static_cast<int>(arguments[0].asNumber());
98
98
  if (i < 0 || i >= getObject()->uniforms().size()) {
99
- jsi::detail::throwJSError(runtime, "invalid uniform index");
99
+ throw jsi::JSError(runtime, "invalid uniform index");
100
100
  }
101
101
  auto it = getObject()->uniforms().begin() + i;
102
102
  return jsi::String::createFromAscii(runtime, it->name.c_str());
@@ -106,7 +106,7 @@ namespace RNSkia
106
106
  {
107
107
  auto i = static_cast<int>(arguments[0].asNumber());
108
108
  if (i < 0 || i >= getObject()->uniforms().size()) {
109
- jsi::detail::throwJSError(runtime, "invalid uniform index");
109
+ throw jsi::JSError(runtime, "invalid uniform index");
110
110
  }
111
111
  auto it = getObject()->uniforms().begin() + i;
112
112
  auto result = jsi::Object(runtime);
@@ -144,7 +144,7 @@ namespace RNSkia
144
144
  std::to_string(jsiUniformsSize) +
145
145
  " expected " +
146
146
  std::to_string(getObject()->uniformSize() / sizeof(float));
147
- jsi::detail::throwJSError(runtime, msg.c_str());
147
+ throw jsi::JSError(runtime, msg.c_str());
148
148
  }
149
149
 
150
150
  auto uniforms = SkData::MakeUninitialized(getObject()->uniformSize());
@@ -21,7 +21,7 @@ public:
21
21
  auto effect = result.effect;
22
22
  auto errorText = result.errorText;
23
23
  if (!effect) {
24
- jsi::detail::throwJSError(
24
+ throw jsi::JSError(
25
25
  runtime,
26
26
  std::string("Error in sksl:\n" + std::string(errorText.c_str()))
27
27
  .c_str());
@@ -7,26 +7,26 @@ namespace RNJsi
7
7
  {
8
8
  using namespace facebook;
9
9
 
10
- enum JsiWrapperValueType
10
+ /**
11
+ Implements a simple wrapper class for JSI primitives like numbers and boolean values. Objects,
12
+ strings and arrays are stored as values inside a property holder. The class also provides a method
13
+ for comparing values that will compare numbers, booleans and strings.
14
+ */
15
+ class JsiSimpleValueWrapper
11
16
  {
17
+ private:
18
+ enum ValueType {
12
19
  NonInitialized,
13
20
  Undefined,
14
21
  Null,
15
22
  Bool,
16
23
  Number,
17
24
  JsiValue
18
- };
25
+ };
19
26
 
20
- /**
21
- Implements a simple wrapper class for JSI primitives like numbers and boolean values. Objects,
22
- strings and arrays are stored as values inside a property holder. The class also provides a method
23
- for comparing values that will compare numbers, booleans and strings.
24
- */
25
- class JsiSimpleValueWrapper
26
- {
27
27
  public:
28
28
  JsiSimpleValueWrapper(jsi::Runtime& runtime) :
29
- _type(JsiWrapperValueType::NonInitialized),
29
+ _type(ValueType::NonInitialized),
30
30
  _propNameId(jsi::PropNameID::forUtf8(runtime, "value"))
31
31
  {}
32
32
 
@@ -34,17 +34,17 @@ public:
34
34
  {
35
35
  switch (_type)
36
36
  {
37
- case JsiWrapperValueType::NonInitialized:
37
+ case ValueType::NonInitialized:
38
38
  return nullptr;
39
- case JsiWrapperValueType::Undefined:
39
+ case ValueType::Undefined:
40
40
  return jsi::Value::undefined();
41
- case JsiWrapperValueType::Null:
41
+ case ValueType::Null:
42
42
  return jsi::Value::null();
43
- case JsiWrapperValueType::Bool:
43
+ case ValueType::Bool:
44
44
  return _boolValue;
45
- case JsiWrapperValueType::Number:
45
+ case ValueType::Number:
46
46
  return _numberValue;
47
- case JsiWrapperValueType::JsiValue:
47
+ case ValueType::JsiValue:
48
48
  if (_valueHolder == nullptr) {
49
49
  return jsi::Value::undefined();
50
50
  }
@@ -55,17 +55,17 @@ public:
55
55
  void setCurrent(jsi::Runtime &runtime, const jsi::Value &value)
56
56
  {
57
57
  if(value.isNumber()) {
58
- _type = JsiWrapperValueType::Number;
58
+ _type = ValueType::Number;
59
59
  _numberValue = value.asNumber();
60
60
  } else if(value.isBool()) {
61
- _type = JsiWrapperValueType::Bool;
61
+ _type = ValueType::Bool;
62
62
  _boolValue = value.getBool();
63
63
  } else if(value.isUndefined()) {
64
- _type = JsiWrapperValueType::Undefined;
64
+ _type = ValueType::Undefined;
65
65
  } else if(value.isNull()) {
66
- _type = JsiWrapperValueType::Null;
66
+ _type = ValueType::Null;
67
67
  } else {
68
- _type = JsiWrapperValueType::JsiValue;
68
+ _type = ValueType::JsiValue;
69
69
  // Save as javascript object - we don't want to have to copy strings, objects and values
70
70
  if(_valueHolder == nullptr) {
71
71
  _valueHolder = std::make_shared<jsi::Object>(runtime);
@@ -75,17 +75,17 @@ public:
75
75
  }
76
76
 
77
77
  bool equals(jsi::Runtime& runtime, const jsi::Value &value) {
78
- if (_type == JsiWrapperValueType::NonInitialized) {
78
+ if (_type == ValueType::NonInitialized) {
79
79
  return false;
80
80
  }
81
- if(value.isNumber() && _type == JsiWrapperValueType::Number) {
81
+ if(value.isNumber() && _type == ValueType::Number) {
82
82
  return _numberValue == value.asNumber();
83
- } else if(value.isBool() && _type == JsiWrapperValueType::Bool) {
83
+ } else if(value.isBool() && _type == ValueType::Bool) {
84
84
  return _boolValue == value.getBool();
85
85
  } else if(value.isUndefined()) {
86
- return _type == JsiWrapperValueType::Undefined;
86
+ return _type == ValueType::Undefined;
87
87
  } else if(value.isNull()) {
88
- return _type == JsiWrapperValueType::Null;
88
+ return _type == ValueType::Null;
89
89
  } else if(value.isString()) {
90
90
  auto current = getCurrent(runtime);
91
91
  if (current.isString()) {
@@ -103,6 +103,6 @@ private:
103
103
  bool _boolValue;
104
104
  double _numberValue;
105
105
 
106
- JsiWrapperValueType _type;
106
+ ValueType _type;
107
107
  };
108
108
  }
@@ -0,0 +1,127 @@
1
+
2
+ #pragma once
3
+
4
+ #include <jsi/jsi.h>
5
+
6
+ namespace RNJsi
7
+ {
8
+ using namespace facebook;
9
+
10
+ enum JsiWrapperValueType
11
+ {
12
+ NonInitialized,
13
+ Undefined,
14
+ Null,
15
+ Bool,
16
+ Number,
17
+ String,
18
+ Object,
19
+ Function,
20
+ Array,
21
+ Unknown
22
+ };
23
+
24
+ /**
25
+ Implements a simple wrapper class for JSI values where the value can be read without asking the runtime for any assistance
26
+ Meaning that we can access members without being on the JS thread.
27
+ */
28
+ class JsiValueWrapper
29
+ {
30
+ public:
31
+ JsiValueWrapper(jsi::Runtime& runtime) :
32
+ _type(JsiWrapperValueType::NonInitialized)
33
+ {}
34
+
35
+ JsiValueWrapper(jsi::Runtime& runtime, const jsi::Value &value) :
36
+ _type(JsiWrapperValueType::NonInitialized)
37
+ {
38
+ setCurrent(runtime, value);
39
+ }
40
+
41
+ void setCurrent(jsi::Runtime &runtime, const jsi::Value &value)
42
+ {
43
+ if (value.isNumber()) {
44
+ _type = JsiWrapperValueType::Number;
45
+ _numberValue = value.asNumber();
46
+ } else if (value.isBool()) {
47
+ _type = JsiWrapperValueType::Bool;
48
+ _boolValue = value.getBool();
49
+ } else if (value.isString()) {
50
+ _type = JsiWrapperValueType::String;
51
+ _stringValue = value.asString(runtime).utf8(runtime);
52
+ } else if (value.isUndefined()) {
53
+ _type = JsiWrapperValueType::Undefined;
54
+ } else if (value.isNull()) {
55
+ _type = JsiWrapperValueType::Null;
56
+ } else if (value.isObject()) {
57
+ _type = JsiWrapperValueType::Object;
58
+ _objectValue = std::make_shared<jsi::Object>(value.asObject(runtime));
59
+ if (_objectValue->isFunction(runtime)) {
60
+ _type = JsiWrapperValueType::Function;
61
+ _functionValue = std::make_shared<jsi::Function>(_objectValue->asFunction(runtime));
62
+ _objectValue = nullptr;
63
+ } else if (_objectValue->isArray(runtime)) {
64
+ _type = JsiWrapperValueType::Array;
65
+ _arrayValue = std::make_shared<jsi::Array>(_objectValue->asArray(runtime));
66
+ _objectValue = nullptr;
67
+ }
68
+ } else {
69
+ throw std::runtime_error("Could not store jsi::Value of provided type");
70
+ }
71
+ // Save in value holder as well so that we can return current
72
+ if(_valueHolder == nullptr) {
73
+ _valueHolder = std::make_shared<jsi::Object>(runtime);
74
+ }
75
+ _valueHolder->setProperty(runtime, "current", value);
76
+ }
77
+
78
+ bool isUndefinedOrNull() {
79
+ return _type == JsiWrapperValueType::Undefined ||
80
+ _type == JsiWrapperValueType::Null;
81
+ }
82
+
83
+ bool getAsBool() {
84
+ assert(_type == JsiWrapperValueType::Bool);
85
+ return _boolValue;
86
+ }
87
+
88
+ double getAsNumber() {
89
+ assert(_type == JsiWrapperValueType::Number);
90
+ return _numberValue;
91
+ }
92
+
93
+ const std::string& getAsString() {
94
+ assert(_type == JsiWrapperValueType::String);
95
+ return _stringValue;
96
+ }
97
+
98
+ std::shared_ptr<jsi::Function> getAsFunction() {
99
+ assert(_type == JsiWrapperValueType::Function);
100
+ return _functionValue;
101
+ }
102
+
103
+ std::shared_ptr<jsi::Array> getAsArray() {
104
+ assert(_type == JsiWrapperValueType::Array);
105
+ return _arrayValue;
106
+ }
107
+
108
+ std::shared_ptr<jsi::Object> getAsObject() {
109
+ assert(_type == JsiWrapperValueType::Object);
110
+ return _objectValue;
111
+ }
112
+
113
+ JsiWrapperValueType getType() { return _type; }
114
+
115
+ private:
116
+ std::shared_ptr<jsi::Object> _valueHolder;
117
+
118
+ bool _boolValue;
119
+ double _numberValue;
120
+ std::string _stringValue;
121
+ std::shared_ptr<jsi::Object> _objectValue;
122
+ std::shared_ptr<jsi::Function> _functionValue;
123
+ std::shared_ptr<jsi::Array> _arrayValue;
124
+
125
+ JsiWrapperValueType _type;
126
+ };
127
+ }
@@ -49,12 +49,52 @@ RNSkDrawView::~RNSkDrawView() {
49
49
  endDrawingLoop();
50
50
  }
51
51
 
52
+ void RNSkDrawView::setJsiProperties(std::unordered_map<std::string, JsiValueWrapper> &props) {
53
+ for(auto& prop: props) {
54
+ if(prop.first == "drawCallback") {
55
+ if(prop.second.isUndefinedOrNull()) {
56
+ // Clear drawcallback
57
+ _drawCallback = nullptr;
58
+ // We can just reset everything - this is a signal that we're done.
59
+ endDrawingLoop();
60
+ return;
61
+ } else if (prop.second.getType() != JsiWrapperValueType::Function) {
62
+ // We expect a function for the draw callback custom property
63
+ throw std::runtime_error("Expected a function for the drawCallback custom property.");
64
+ }
65
+
66
+ // Save callback
67
+ _drawCallback = prop.second.getAsFunction();
68
+
69
+ // Request redraw
70
+ requestRedraw();
71
+
72
+ } else {
73
+ throw std::runtime_error("Property " + prop.first + " not found.");
74
+ }
75
+ }
76
+ }
77
+
78
+ jsi::Value RNSkDrawView::callJsiMethod(jsi::Runtime& runtime,
79
+ const std::string& name,
80
+ const jsi::Value *arguments,
81
+ size_t count) {
82
+
83
+ // This subclass doesn't support any jsi methods at the moment, but
84
+ // new subclasses created in the future will.
85
+ throw std::runtime_error("RNSkDrawView does not support any JSI methods. Method " + name + "() not found.");
86
+ return jsi::Value::undefined();
87
+ }
88
+
52
89
  void RNSkDrawView::setNativeId(size_t nativeId) {
53
90
  _nativeId = nativeId;
54
91
  beginDrawingLoop();
55
92
  }
56
93
 
57
- void RNSkDrawView::callJsDrawCallback(std::shared_ptr<JsiSkCanvas> canvas, int width, int height, double timestamp) {
94
+ void RNSkDrawView::callJsDrawCallback(std::shared_ptr<JsiSkCanvas> canvas,
95
+ int width,
96
+ int height,
97
+ double timestamp) {
58
98
  if(_drawCallback == nullptr) {
59
99
  return;
60
100
  }
@@ -110,22 +150,6 @@ void RNSkDrawView::callJsDrawCallback(std::shared_ptr<JsiSkCanvas> canvas, int w
110
150
  }
111
151
  }
112
152
 
113
- void RNSkDrawView::setDrawCallback(std::shared_ptr<FunctionWrapper> callback) {
114
-
115
- if (callback == nullptr) {
116
- _drawCallback = nullptr;
117
- // We can just reset everything - this is a signal that we're done.
118
- endDrawingLoop();
119
- return;
120
- }
121
-
122
- // Save callback
123
- _drawCallback = callback;
124
-
125
- // Request redraw
126
- requestRedraw();
127
- }
128
-
129
153
  void RNSkDrawView::drawInCanvas(std::shared_ptr<JsiSkCanvas> canvas,
130
154
  int width,
131
155
  int height,
@@ -8,6 +8,8 @@
8
8
 
9
9
  #include <jsi/jsi.h>
10
10
 
11
+ #include <JsiValueWrapper.h>
12
+
11
13
  #include <RNSkInfoParameter.h>
12
14
  #include <RNSkPlatformContext.h>
13
15
  #include <RNSkTimingInfo.h>
@@ -27,22 +29,9 @@ class SkImage;
27
29
  namespace RNSkia {
28
30
  class JsiSkCanvas;
29
31
  using namespace facebook;
30
- using RNSkDrawCallback =
31
- std::function<void(std::shared_ptr<JsiSkCanvas>, int, int, double,
32
- std::shared_ptr<RNSkPlatformContext>)>;
33
32
 
34
33
  enum RNSkDrawingMode { Default, Continuous };
35
34
 
36
- class FunctionWrapper {
37
- public:
38
- FunctionWrapper(jsi::Function &&func): _func(std::move(func)) {}
39
- jsi::Value call(jsi::Runtime& runtime, const jsi::Value* args, size_t count) {
40
- return _func.call(runtime, args, count);
41
- }
42
- private:
43
- jsi::Function _func;
44
- };
45
-
46
35
  class RNSkDrawView: public std::enable_shared_from_this<RNSkDrawView> {
47
36
  public:
48
37
  /**
@@ -54,6 +43,20 @@ public:
54
43
  Destructor
55
44
  */
56
45
  virtual ~RNSkDrawView();
46
+
47
+ /**
48
+ Sets custom properties. Custom properties are properties that are set directly from Javascript without having
49
+ to go through the async bridge.
50
+ */
51
+ void setJsiProperties(std::unordered_map<std::string, JsiValueWrapper> &props);
52
+
53
+ /**
54
+ Calls a custom action.
55
+ */
56
+ jsi::Value callJsiMethod(jsi::Runtime& runtime,
57
+ const std::string& name,
58
+ const jsi::Value *arguments,
59
+ size_t count);
57
60
 
58
61
  /**
59
62
  * Repaints the Skia view using the underlying context and the drawcallback.
@@ -66,11 +69,6 @@ public:
66
69
  Calls the drawing callback on the javascript thread
67
70
  */
68
71
  void performDraw();
69
-
70
- /**
71
- * Installs the draw callback for the view
72
- */
73
- void setDrawCallback(std::shared_ptr<FunctionWrapper> callback);
74
72
 
75
73
  /**
76
74
  Sets the native id of the view
@@ -159,7 +157,7 @@ private:
159
157
  /**
160
158
  * Stores the draw drawCallback
161
159
  */
162
- std::shared_ptr<FunctionWrapper> _drawCallback;
160
+ std::shared_ptr<jsi::Function> _drawCallback;
163
161
 
164
162
  /**
165
163
  * Stores a pointer to the jsi wrapper for the canvas. The reason for