From 5579a810d2ecf53f2d0706d9b49a6254c6c6ef8f Mon Sep 17 00:00:00 2001 From: William Candillon Date: Mon, 22 Sep 2025 09:30:47 +0200 Subject: [PATCH] :wrench: --- apps/example/ios/Podfile.lock | 114 ++++---- packages/skia/cpp/api/JsiArgumentParser.h | 290 +++++++++++++++++++++ packages/skia/cpp/api/JsiSkCanvas.h | 49 ++-- packages/skia/cpp/api/JsiTypeTraits.h | 19 ++ packages/skia/cpp/api/recorder/Convertor.h | 14 +- 5 files changed, 387 insertions(+), 99 deletions(-) create mode 100644 packages/skia/cpp/api/JsiArgumentParser.h create mode 100644 packages/skia/cpp/api/JsiTypeTraits.h diff --git a/apps/example/ios/Podfile.lock b/apps/example/ios/Podfile.lock index e84916c103..66198b1fb4 100644 --- a/apps/example/ios/Podfile.lock +++ b/apps/example/ios/Podfile.lock @@ -2162,77 +2162,77 @@ SPEC CHECKSUMS: fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: eb93e2f488219332457c3c4eafd2738ddc7e80b8 hermes-engine: b417d2b2aee3b89b58e63e23a51e02be91dc876d - RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809 + RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82 RCTDeprecation: b2eecf2d60216df56bc5e6be5f063826d3c1ee35 RCTRequired: 78522de7dc73b81f3ed7890d145fa341f5bb32ea RCTTypeSafety: c135dd2bf50402d87fd12884cbad5d5e64850edd React: b229c49ed5898dab46d60f61ed5a0bfa2ee2fadb React-callinvoker: 2ac508e92c8bd9cf834cc7d7787d94352e4af58f - React-Core: 13cdd1558d0b3f6d9d5a22e14d89150280e79f02 - React-CoreModules: b07a6744f48305405e67c845ebf481b6551b712a - React-cxxreact: 1055a86c66ac35b4e80bd5fb766aed5f494dfff4 + React-Core: 325b4f6d9162ae8b9a6ff42fe78e260eb124180d + React-CoreModules: 558041e5258f70cd1092f82778d07b8b2ff01897 + React-cxxreact: 8fff17cbe76e6a8f9991b59552e1235429f9c74b React-debug: 0a5fcdbacc6becba0521e910c1bcfdb20f32a3f6 - React-defaultsnativemodule: 4bb28fc97fee5be63a9ebf8f7a435cfe8ba69459 - React-domnativemodule: b36a11c2597243d7563985028c51ece988d8ae33 - React-Fabric: afc561718f25b2cd800b709d934101afe376a12c - React-FabricComponents: f4e0a4e18a27bf6d39cbf2a0b42f37a92fa4e37f - React-FabricImage: 37d8e8b672eda68a19d71143eb65148084efb325 + React-defaultsnativemodule: 618dc50a0fad41b489997c3eb7aba3a74479fd14 + React-domnativemodule: 7ba599afb6c2a7ec3eb6450153e2efe0b8747e9a + React-Fabric: 252112089d2c63308f4cbfade4010b6606db67d1 + React-FabricComponents: 3c0f75321680d14d124438ab279c64ec2a3d13c4 + React-FabricImage: 728b8061cdec2857ca885fd605ee03ad43ffca98 React-featureflags: 19682e02ef5861d96b992af16a19109c3dfc1200 - React-featureflagsnativemodule: d7cddf6d907b4e5ab84f9e744b7e88461656e48c - React-graphics: b0f78580cdaf5800d25437e3d41cc6c3d83b7aea - React-hermes: 71186f872c932e4574d5feb3ed754dda63a0b3bd - React-idlecallbacksnativemodule: dd2af19cdd3bc55149d17a2409ed72b694dfbe9c - React-ImageManager: a77dde8d5aa6a2b6962c702bf3a47695ef0aa32b - React-jserrorhandler: 9c14e89f12d5904257a79aaf84a70cd2e5ac07ba - React-jsi: 0775a66820496769ad83e629f0f5cce621a57fc7 - React-jsiexecutor: 2cf5ba481386803f3c88b85c63fa102cba5d769e - React-jsinspector: 8052d532bb7a98b6e021755674659802fb140cc5 - React-jsinspectortracing: bdd8fd0adcb4813663562e7874c5842449df6d8a - React-jsitracing: 2bab3bf55de3d04baf205def375fa6643c47c794 - React-logger: 795cd5055782db394f187f9db0477d4b25b44291 - React-Mapbuffer: 0502faf46cab8fb89cfc7bf3e6c6109b6ef9b5de - React-microtasksnativemodule: 663bc64e3a96c5fc91081923ae7481adc1359a78 - react-native-safe-area-context: 286b3e7b5589795bb85ffc38faf4c0706c48a092 - react-native-skia: 6be4bd020c4c2489aed4b2b24f9548e56b143d48 - react-native-slider: 27263d134d55db948a4706f1e47d0ec88fb354dd - React-NativeModulesApple: 16fbd5b040ff6c492dacc361d49e63cba7a6a7a1 - React-perflogger: ab51b7592532a0ea45bf6eed7e6cae14a368b678 - React-performancetimeline: bc2e48198ec814d578ac8401f65d78a574358203 + React-featureflagsnativemodule: 23528c7e7d50782b7ef0804168ba40bbaf1e86ab + React-graphics: fefe48f71bfe6f48fd037f59e8277b12e91b6be1 + React-hermes: a9a0c8377627b5506ef9a7b6f60a805c306e3f51 + React-idlecallbacksnativemodule: 7e2b6a3b70e042f89cd91dbd73c479bb39a72a7e + React-ImageManager: e3300996ac2e2914bf821f71e2f2c92ae6e62ae2 + React-jserrorhandler: fa75876c662e5d7e79d6efc763fc9f4c88e26986 + React-jsi: f3f51595cc4c089037b536368f016d4742bf9cf7 + React-jsiexecutor: cca6c232db461e2fd213a11e9364cfa6fdaa20eb + React-jsinspector: 2bd4c9fddf189d6ec2abf4948461060502582bef + React-jsinspectortracing: a417d8a0ad481edaa415734b4dac81e3e5ee7dc6 + React-jsitracing: 1ff7172c5b0522cbf6c98d82bdbb160e49b5804e + React-logger: 018826bfd51b9f18e87f67db1590bc510ad20664 + React-Mapbuffer: 3c11cee7737609275c7b66bd0b1de475f094cedf + React-microtasksnativemodule: 843f352b32aacbe13a9c750190d34df44c3e6c2c + react-native-safe-area-context: 0f14bce545abcdfbff79ce2e3c78c109f0be283e + react-native-skia: 30909a8b54c5d383b5c424468e9824372199116e + react-native-slider: 310d3f89edd6ca8344a974bfe83a29a3fbb60e5a + React-NativeModulesApple: 88433b6946778bea9c153e27b671de15411bf225 + React-perflogger: 9e8d3c0dc0194eb932162812a168aa5dc662f418 + React-performancetimeline: 5a2d6efef52bdcefac079c7baa30934978acd023 React-RCTActionSheet: 592674cf61142497e0e820688f5a696e41bf16dd - React-RCTAnimation: 8fbb8dba757b49c78f4db403133ab6399a4ce952 - React-RCTAppDelegate: 7f88baa8cb4e5d6c38bb4d84339925c70c9ac864 - React-RCTBlob: f89b162d0fe6b570a18e755eb16cbe356d3c6d17 - React-RCTFabric: 8ad6d875abe6e87312cef90e4b15ef7f6bed72e6 - React-RCTFBReactNativeSpec: 8c29630c2f379c729300e4c1e540f3d1b78d1936 - React-RCTImage: ccac9969940f170503857733f9a5f63578e106e1 - React-RCTLinking: d82427bbf18415a3732105383dff119131cadd90 - React-RCTNetwork: 12ad4d0fbde939e00251ca5ca890da2e6825cc3c - React-RCTSettings: e7865bf9f455abf427da349c855f8644b5c39afa - React-RCTText: 2cdfd88745059ec3202a0842ea75a956c7d6f27d - React-RCTVibration: a3a1458e6230dfd64b3768ebc0a4aac430d9d508 + React-RCTAnimation: e6d669872f9b3b4ab9527aab283b7c49283236b7 + React-RCTAppDelegate: de2343fe08be4c945d57e0ecce44afcc7dd8fc03 + React-RCTBlob: 3e2dce94c56218becc4b32b627fc2293149f798d + React-RCTFabric: cac2c033381d79a5956e08550b0220cb2d78ea93 + React-RCTFBReactNativeSpec: d10ca5e0ccbfeac8c047361fedf8e4ac653887b6 + React-RCTImage: dc04b176c022d12a8f55ae7a7279b1e091066ae0 + React-RCTLinking: 88f5e37fe4f26fbc80791aa2a5f01baf9b9a3fd5 + React-RCTNetwork: f213693565efbd698b8e9c18d700a514b49c0c8e + React-RCTSettings: a2d32a90c45a3575568cad850abc45924999b8a5 + React-RCTText: 54cdcd1cbf6f6a91dc6317f5d2c2b7fc3f6bf7a0 + React-RCTVibration: 11dae0e7f577b5807bb7d31e2e881eb46f854fd4 React-rendererconsistency: 64e897e00d2568fd8dfe31e2496f80e85c0aaad1 - React-rendererdebug: a3f6d3ae7d2fa0035885026756281c07ee32479e + React-rendererdebug: 41ce452460c44bba715d9e41d5493a96de277764 React-rncore: 58748c2aa445f56b99e5118dad0aedb51c40ce9f - React-RuntimeApple: f0fda7bacabd32daa099cfda8f07466c30acd149 - React-RuntimeCore: 683ee0b6a76d4b4bf6fbf83a541895b4887cc636 + React-RuntimeApple: 7785ed0d8ae54da65a88736bb63ca97608a6d933 + React-RuntimeCore: 6029ea70bc77f98cfd43ebe69217f14e93ba1f12 React-runtimeexecutor: a188df372373baf5066e6e229177836488799f80 - React-RuntimeHermes: 907c8e9bec13ea6466b94828c088c24590d4d0b6 - React-runtimescheduler: a2e2a39125dd6426b5d8b773f689d660cd7c5f60 + React-RuntimeHermes: a264609c28b796edfffc8ae4cb8fad1773ab948b + React-runtimescheduler: 23ec3a1e0fb1ec752d1a9c1fb15258c30bfc7222 React-timing: bb220a53a795ed57976a4855c521f3de2f298fe5 - React-utils: 300d8bbb6555dcffaca71e7a0663201b5c7edbbc - ReactAppDependencyProvider: f2e81d80afd71a8058589e19d8a134243fa53f17 - ReactCodegen: 50b6e45bbbef9b39d9798820cdbe87bfc7922e22 - ReactCommon: 3d39389f8e2a2157d5c999f8fba57bd1c8f226f0 - ReactNativeHost: e96154926221741f253f2c1ded13c6959c5c3d43 - ReactTestApp-DevSupport: 6994b53b5b81139a8ce63e0776c726c95de079a1 + React-utils: 3b054aaebe658fc710a8d239d0e4b9fd3e0b78f9 + ReactAppDependencyProvider: a1fb08dfdc7ebc387b2e54cfc9decd283ed821d8 + ReactCodegen: e232f8db3a40721044ec81b9388f95a7afaad36a + ReactCommon: 0c097b53f03d6bf166edbcd0915da32f3015dd90 + ReactNativeHost: 1b6ccdcfc87bb31e772a5b3c3ca3b09c90954328 + ReactTestApp-DevSupport: ea18f446cff64b6c9a3e28788600c82ecf51bde6 ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf - RNGestureHandler: 66e593addd8952725107cfaa4f5e3378e946b541 - RNReanimated: 858fe25904af44131b8b608a5005b64778609a6a - RNScreens: 0f01bbed9bd8045a8d58e4b46993c28c7f498f3c - RNSVG: 8588ee1ca9b2e6fd2c99466e35b3db0e9f81bb40 + RNGestureHandler: dcb1b1db024f3744b03af56d132f4f72c4c27195 + RNReanimated: d5f33d14a4d1da33a02d89124de233a64b3aaeaa + RNScreens: 790123c4a28783d80a342ce42e8c7381bed62db1 + RNSVG: 8126581b369adf6a0004b6a6cab1a55e3002d5b0 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Yoga: 9b7fb56e7b08cde60e2153344fa6afbd88e5d99f + Yoga: afd04ff05ebe0121a00c468a8a3c8080221cb14c PODFILE CHECKSUM: 87506345285a0371afb28b9c3e6daaa999c214f3 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/packages/skia/cpp/api/JsiArgumentParser.h b/packages/skia/cpp/api/JsiArgumentParser.h new file mode 100644 index 0000000000..449d4b1bc8 --- /dev/null +++ b/packages/skia/cpp/api/JsiArgumentParser.h @@ -0,0 +1,290 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "JsiTypeTraits.h" + +namespace RNSkia { +namespace jsi = facebook::jsi; + +// Forward declarations for Skia JSI objects +class JsiSkPaint; +class JsiSkRect; +class JsiSkImage; +class JsiSkPath; +class JsiSkPoint; +class JsiSkRRect; +class JsiSkFont; +class JsiSkImageFilter; +class JsiSkMatrix; +class JsiSkColor; + +// Type traits for JSI type detection +template struct is_vector : std::false_type {}; +template struct is_vector> : std::true_type {}; + +// Note: is_optional and unwrap_optional are defined in JsiTypeTraits.h + +// Base argument extraction trait +template +struct ArgumentExtractor { + static T extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index); +}; + +// Specializations for primitive types +template<> +struct ArgumentExtractor { + static float extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (!value.isNumber()) { + throw std::runtime_error("Expected number at argument " + std::to_string(index)); + } + return static_cast(value.asNumber()); + } +}; + +template<> +struct ArgumentExtractor { + static double extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (!value.isNumber()) { + throw std::runtime_error("Expected number at argument " + std::to_string(index)); + } + return value.asNumber(); + } +}; + +template<> +struct ArgumentExtractor { + static int extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (!value.isNumber()) { + throw std::runtime_error("Expected number at argument " + std::to_string(index)); + } + return static_cast(value.asNumber()); + } +}; + +template<> +struct ArgumentExtractor { + static uint32_t extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (!value.isNumber()) { + throw std::runtime_error("Expected number at argument " + std::to_string(index)); + } + return static_cast(value.asNumber()); + } +}; + +template<> +struct ArgumentExtractor { + static bool extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (!value.isBool()) { + throw std::runtime_error("Expected boolean at argument " + std::to_string(index)); + } + return value.getBool(); + } +}; + +template<> +struct ArgumentExtractor { + static std::string extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (!value.isString()) { + throw std::runtime_error("Expected string at argument " + std::to_string(index)); + } + return value.asString(runtime).utf8(runtime); + } +}; + +// Note: SkScalar is typedef'd as float, so it uses the float specialization + +// Specialization for optional types +template +struct ArgumentExtractor> { + static std::optional extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (value.isNull() || value.isUndefined()) { + return std::nullopt; + } + return ArgumentExtractor::extract(runtime, value, index); + } +}; + +// Specialization for vectors/arrays +template +struct ArgumentExtractor> { + static std::vector extract(jsi::Runtime& runtime, const jsi::Value& value, size_t index) { + if (!value.isObject()) { + throw std::runtime_error("Expected array at argument " + std::to_string(index)); + } + + auto obj = value.asObject(runtime); + if (!obj.isArray(runtime)) { + throw std::runtime_error("Expected array at argument " + std::to_string(index)); + } + + auto arr = obj.asArray(runtime); + size_t size = arr.size(runtime); + std::vector result; + result.reserve(size); + + for (size_t i = 0; i < size; i++) { + auto element = arr.getValueAtIndex(runtime, i); + result.push_back(ArgumentExtractor::extract(runtime, element, index)); + } + return result; + } +}; + +// Main ArgumentParser class +class ArgumentParser { +private: + jsi::Runtime& runtime; + const jsi::Value* arguments; + size_t count; + size_t current_index = 0; + +public: + ArgumentParser(jsi::Runtime& rt, const jsi::Value* args, size_t cnt) + : runtime(rt), arguments(args), count(cnt) {} + + // Get required argument + template + T get() { + if (current_index >= count) { + if constexpr (is_optional::value) { + // If it's optional and we're out of args, return nullopt + current_index++; + return std::nullopt; + } else { + throw std::runtime_error("Not enough arguments provided. Expected argument at index " + + std::to_string(current_index)); + } + } + auto result = ArgumentExtractor::extract(runtime, arguments[current_index], current_index); + current_index++; + return result; + } + + // Get optional argument (explicit method for clarity) + template + std::optional optional() { + if (current_index >= count) { + return std::nullopt; + } + auto result = ArgumentExtractor>::extract(runtime, arguments[current_index], current_index); + current_index++; + return result; + } + + // Get argument with default value + template + T get_or(const T& default_value) { + if (current_index >= count) { + return default_value; + } + auto result = ArgumentExtractor::extract(runtime, arguments[current_index], current_index); + current_index++; + return result; + } + + // Multi-argument extraction using tuple + template + std::tuple get_args() { + return std::make_tuple(get()...); + } + + // Remaining arguments as vector + template + std::vector remaining() { + std::vector result; + while (current_index < count) { + result.push_back(get()); + } + return result; + } + + // Peek at next argument without consuming it + template + T peek() const { + if (current_index >= count) { + throw std::runtime_error("No more arguments to peek at"); + } + return ArgumentExtractor::extract(runtime, arguments[current_index], current_index); + } + + // Skip argument (useful for overloads) + void skip() { + if (current_index >= count) { + throw std::runtime_error("No argument to skip at index " + std::to_string(current_index)); + } + current_index++; + } + + // Check if next argument is of specific type + template + bool next_is() const { + if (current_index >= count) { + return false; + } + try { + ArgumentExtractor::extract(runtime, arguments[current_index], current_index); + return true; + } catch (...) { + return false; + } + } + + // Utility methods + size_t remaining_count() const { return count - current_index; } + bool has_more() const { return current_index < count; } + size_t total_count() const { return count; } + size_t current_position() const { return current_index; } + + // Reset parser to beginning + void reset() { current_index = 0; } + + // Validate minimum number of arguments + void require_min(size_t min_args) const { + if (count < min_args) { + throw std::runtime_error("Expected at least " + std::to_string(min_args) + + " arguments, got " + std::to_string(count)); + } + } + + // Validate exact number of arguments + void require_exact(size_t exact_args) const { + if (count != exact_args) { + throw std::runtime_error("Expected exactly " + std::to_string(exact_args) + + " arguments, got " + std::to_string(count)); + } + } + + // Validate argument range + void require_range(size_t min_args, size_t max_args) const { + if (count < min_args || count > max_args) { + throw std::runtime_error("Expected " + std::to_string(min_args) + "-" + + std::to_string(max_args) + " arguments, got " + std::to_string(count)); + } + } +}; + +// Convenience macro for creating argument parsers +#define PARSE_ARGS() ArgumentParser parser(runtime, arguments, count) + +// Convenience macro for argument validation +#define REQUIRE_ARGS(n) do { \ + if (count < (n)) { \ + throw std::runtime_error("Expected at least " + std::to_string(n) + " arguments, got " + std::to_string(count)); \ + } \ +} while(0) + +#define REQUIRE_EXACT_ARGS(n) do { \ + if (count != (n)) { \ + throw std::runtime_error("Expected exactly " + std::to_string(n) + " arguments, got " + std::to_string(count)); \ + } \ +} while(0) + +} // namespace RNSkia diff --git a/packages/skia/cpp/api/JsiSkCanvas.h b/packages/skia/cpp/api/JsiSkCanvas.h index c010abf0b8..e65e2a37ed 100644 --- a/packages/skia/cpp/api/JsiSkCanvas.h +++ b/packages/skia/cpp/api/JsiSkCanvas.h @@ -20,6 +20,7 @@ #include "JsiSkVertices.h" #include "RNSkTypedArray.h" +#include "JsiArgumentParserSkia.h" #include @@ -50,31 +51,27 @@ class JsiSkCanvas : public JsiSkHostObject { } JSI_HOST_FUNCTION(drawLine) { - SkScalar x1 = arguments[0].asNumber(); - SkScalar y1 = arguments[1].asNumber(); - SkScalar x2 = arguments[2].asNumber(); - SkScalar y2 = arguments[3].asNumber(); - auto paint = JsiSkPaint::fromValue(runtime, arguments[4]); + PARSE_ARGS_EXACT(5); + auto [x1, y1, x2, y2] = parser.get_args(); + auto paint = parser.get>(); _canvas->drawLine(x1, y1, x2, y2, *paint); return jsi::Value::undefined(); } JSI_HOST_FUNCTION(drawRect) { - auto rect = JsiSkRect::fromValue(runtime, arguments[0]); - auto paint = JsiSkPaint::fromValue(runtime, arguments[1]); + PARSE_ARGS_EXACT(2); + auto rect = parser.get>(); + auto paint = parser.get>(); _canvas->drawRect(*rect, *paint); return jsi::Value::undefined(); } JSI_HOST_FUNCTION(drawImage) { - auto image = JsiSkImage::fromValue(runtime, arguments[0]); - auto x = arguments[1].asNumber(); - auto y = arguments[2].asNumber(); - std::shared_ptr paint; - if (count == 4) { - paint = JsiSkPaint::fromValue(runtime, arguments[3]); - } - _canvas->drawImage(image, x, y, SkSamplingOptions(), paint.get()); + PARSE_ARGS_RANGE(3, 4); + auto image = parser.get>(); + auto [x, y] = parser.get_args(); + auto paint = parser.optional>(); + _canvas->drawImage(image.get(), x, y, SkSamplingOptions(), paint ? paint->get() : nullptr); return jsi::Value::undefined(); } @@ -176,26 +173,20 @@ class JsiSkCanvas : public JsiSkHostObject { } JSI_HOST_FUNCTION(drawCircle) { - SkScalar cx = arguments[0].asNumber(); - SkScalar cy = arguments[1].asNumber(); - SkScalar radius = arguments[2].asNumber(); - - auto paint = JsiSkPaint::fromValue(runtime, arguments[3]); + PARSE_ARGS_EXACT(4); + auto [cx, cy, radius] = parser.get_args(); + auto paint = parser.get>(); _canvas->drawCircle(cx, cy, radius, *paint); - return jsi::Value::undefined(); } JSI_HOST_FUNCTION(drawArc) { - auto oval = JsiSkRect::fromValue(runtime, arguments[0]); - - SkScalar startAngle = arguments[1].asNumber(); - SkScalar sweepAngle = arguments[2].asNumber(); - bool useCenter = arguments[3].getBool(); - - auto paint = JsiSkPaint::fromValue(runtime, arguments[4]); + PARSE_ARGS_EXACT(5); + auto oval = parser.get>(); + auto [startAngle, sweepAngle] = parser.get_args(); + auto useCenter = parser.get(); + auto paint = parser.get>(); _canvas->drawArc(*oval, startAngle, sweepAngle, useCenter, *paint); - return jsi::Value::undefined(); } diff --git a/packages/skia/cpp/api/JsiTypeTraits.h b/packages/skia/cpp/api/JsiTypeTraits.h new file mode 100644 index 0000000000..43f1c128ff --- /dev/null +++ b/packages/skia/cpp/api/JsiTypeTraits.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace RNSkia { + +// Common type traits used across JSI argument parsing and conversion systems +template struct is_optional : std::false_type {}; +template struct is_optional> : std::true_type {}; + +template struct unwrap_optional { + using type = T; +}; + +template struct unwrap_optional> { + using type = T; +}; + +} // namespace RNSkia \ No newline at end of file diff --git a/packages/skia/cpp/api/recorder/Convertor.h b/packages/skia/cpp/api/recorder/Convertor.h index 799f29a453..1f7d22d98f 100644 --- a/packages/skia/cpp/api/recorder/Convertor.h +++ b/packages/skia/cpp/api/recorder/Convertor.h @@ -18,6 +18,7 @@ #include "third_party/CSSColorParser.h" #include "DataTypes.h" +#include "../JsiTypeTraits.h" #include @@ -51,19 +52,6 @@ bool isSharedValue(jsi::Runtime &runtime, const jsi::Value &value) { .asBool() == true; } -// Helper type traits -template struct is_optional : std::false_type {}; - -template struct is_optional> : std::true_type {}; - -template struct unwrap_optional { - using type = T; -}; - -template struct unwrap_optional> { - using type = T; -}; - // Property value getter declarations template T getPropertyValue(jsi::Runtime &runtime, const jsi::Value &value);