#pragma once #include #include #include #include #include #include #include #include "JsiValueWrapper.h" #include "RNSkView.h" #include "JsiDomRenderNode.h" #include "RNSkInfoParameter.h" #include "RNSkLog.h" #include "RNSkPlatformContext.h" #include "RNSkTimingInfo.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" #include "SkBBHFactory.h" #include "SkCanvas.h" #include "SkPictureRecorder.h" #pragma clang diagnostic pop class SkPicture; class SkRect; class SkImage; namespace RNSkia { class JsiSkCanvas; namespace jsi = facebook::jsi; class RNSkDomRenderer : public RNSkRenderer, public std::enable_shared_from_this { public: RNSkDomRenderer(std::function requestRedraw, std::shared_ptr context); ~RNSkDomRenderer(); bool tryRender(std::shared_ptr canvasProvider) override; void renderImmediate(std::shared_ptr canvasProvider) override; void setRoot(std::shared_ptr node); void setOnTouchCallback(std::shared_ptr onTouchCallback); void updateTouches(std::vector &touches); private: void callOnTouch(); void renderCanvas(SkCanvas *canvas, float scaledWidth, float scaledHeight); void renderDebugOverlays(SkCanvas *canvas); std::shared_ptr _platformContext; std::shared_ptr _touchCallback; std::shared_ptr _renderLock; std::shared_ptr _touchCallbackLock; std::shared_ptr _root; std::shared_ptr _drawingContext; RNSkTimingInfo _renderTimingInfo; std::mutex _touchMutex; std::vector> _currentTouches; std::vector> _touchesCache; std::mutex _rootLock; }; class RNSkDomView : public RNSkView { public: /** * Constructor */ RNSkDomView(std::shared_ptr context, std::shared_ptr canvasProvider) : RNSkView(context, canvasProvider, std::make_shared( std::bind(&RNSkView::requestRedraw, this), context)) {} void updateTouchState(std::vector &touches) override { std::static_pointer_cast(getRenderer()) ->updateTouches(touches); RNSkView::updateTouchState(touches); } void setJsiProperties( std::unordered_map &props) override { RNSkView::setJsiProperties(props); for (auto &prop : props) { if (prop.first == "onTouch") { if (prop.second.isUndefinedOrNull()) { // Clear touchCallback std::static_pointer_cast(getRenderer()) ->setOnTouchCallback(nullptr); requestRedraw(); continue; } else if (prop.second.getType() != JsiWrapperValueType::Function) { // We expect a function for the draw callback custom property throw std::runtime_error( "Expected a function for the onTouch property."); } // Save callback std::static_pointer_cast(getRenderer()) ->setOnTouchCallback(prop.second.getAsFunction()); // Request redraw requestRedraw(); } else if (prop.first == "root") { // Save root if (prop.second.isUndefined() || prop.second.isNull()) { std::static_pointer_cast(getRenderer()) ->setRoot(nullptr); } else { std::static_pointer_cast(getRenderer()) ->setRoot(std::dynamic_pointer_cast( prop.second.getAsHostObject())); } // Request redraw requestRedraw(); } } } }; } // namespace RNSkia