// // JSITypedArray.h // VisionCamera // // Created by Marc Rousavy on 21.02.23. // Copyright © 2023 mrousavy. All rights reserved. // // Copied & Adapted from // https://github.com/expo/expo/blob/main/packages/expo-gl/common/EXTypedArrayApi.h Credits to Expo #pragma once #include #include #include namespace jsi = facebook::jsi; namespace vision { enum class TypedArrayKind { Int8Array, Int16Array, Int32Array, Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array, Float32Array, Float64Array, }; template class TypedArray; template struct typedArrayTypeMap; template <> struct typedArrayTypeMap { typedef int8_t type; }; template <> struct typedArrayTypeMap { typedef int16_t type; }; template <> struct typedArrayTypeMap { typedef int32_t type; }; template <> struct typedArrayTypeMap { typedef uint8_t type; }; template <> struct typedArrayTypeMap { typedef uint8_t type; }; template <> struct typedArrayTypeMap { typedef uint16_t type; }; template <> struct typedArrayTypeMap { typedef uint32_t type; }; template <> struct typedArrayTypeMap { typedef float type; }; template <> struct typedArrayTypeMap { typedef double type; }; void invalidateArrayBufferCache(jsi::Runtime& runtime); class TypedArrayBase : public jsi::Object { public: template using ContentType = typename typedArrayTypeMap::type; TypedArrayBase(jsi::Runtime&, size_t, TypedArrayKind); TypedArrayBase(jsi::Runtime&, const jsi::Object&); TypedArrayBase(TypedArrayBase&&) = default; TypedArrayBase& operator=(TypedArrayBase&&) = default; TypedArrayKind getKind(jsi::Runtime& runtime) const; template TypedArray get(jsi::Runtime& runtime) const&; template TypedArray get(jsi::Runtime& runtime) &&; template TypedArray as(jsi::Runtime& runtime) const&; template TypedArray as(jsi::Runtime& runtime) &&; size_t size(jsi::Runtime& runtime) const; size_t length(jsi::Runtime& runtime) const; size_t byteLength(jsi::Runtime& runtime) const; size_t byteOffset(jsi::Runtime& runtime) const; bool hasBuffer(jsi::Runtime& runtime) const; std::vector toVector(jsi::Runtime& runtime); jsi::ArrayBuffer getBuffer(jsi::Runtime& runtime) const; private: template friend class TypedArray; }; bool isTypedArray(jsi::Runtime& runtime, const jsi::Object& jsObj); TypedArrayBase getTypedArray(jsi::Runtime& runtime, const jsi::Object& jsObj); std::vector arrayBufferToVector(jsi::Runtime& runtime, jsi::Object& jsObj); void arrayBufferUpdate(jsi::Runtime& runtime, jsi::ArrayBuffer& buffer, std::vector data, size_t offset); template class TypedArray : public TypedArrayBase { public: explicit TypedArray(TypedArrayBase&& base); TypedArray(jsi::Runtime& runtime, size_t size); TypedArray(jsi::Runtime& runtime, std::vector> data); TypedArray(TypedArray&&) = default; TypedArray& operator=(TypedArray&&) = default; std::vector> toVector(jsi::Runtime& runtime); void update(jsi::Runtime& runtime, const std::vector>& data); void updateUnsafe(jsi::Runtime& runtime, ContentType* data, size_t length); uint8_t* data(jsi::Runtime& runtime); }; template TypedArray TypedArrayBase::get(jsi::Runtime& runtime) const& { assert(getKind(runtime) == T); (void)runtime; // when assert is disabled we need to mark this as used return TypedArray(jsi::Value(runtime, jsi::Value(runtime, *this).asObject(runtime))); } template TypedArray TypedArrayBase::get(jsi::Runtime& runtime) && { assert(getKind(runtime) == T); (void)runtime; // when assert is disabled we need to mark this as used return TypedArray(std::move(*this)); } template TypedArray TypedArrayBase::as(jsi::Runtime& runtime) const& { if (getKind(runtime) != T) { throw jsi::JSError(runtime, "Object is not a TypedArray"); } return get(runtime); } template TypedArray TypedArrayBase::as(jsi::Runtime& runtime) && { if (getKind(runtime) != T) { throw jsi::JSError(runtime, "Object is not a TypedArray"); } return std::move(*this).get(runtime); } } // namespace vision