Fix crash when SVG is unloaded by XAML (#2195)

XAML may unload the root SVG panel, which will trigger a recursive unload. For GroupView, this unload will clear the child collection. However, active operations on the SVG from the React Native UIManager may still be in flight, in which case we may attempt to remove a child that has already been cleared by the root unload.
This commit is contained in:
Eric Rozell
2024-01-03 09:48:22 -05:00
committed by GitHub
parent d1b02154e3
commit 07b9ca53f4
4 changed files with 13 additions and 6 deletions

View File

@@ -71,11 +71,13 @@ void GroupViewManager::RemoveAllChildren(FrameworkElement const &parent) {
void GroupViewManager::RemoveChildAt(FrameworkElement const &parent, int64_t index) {
if (auto const &groupView{parent.try_as<RNSVG::GroupView>()}) {
if (!groupView.IsUnloaded()) {
auto const &child{groupView.Children().GetAt(static_cast<uint32_t>(index))};
child.Unload();
child.SvgParent(nullptr);
groupView.Children().RemoveAt(static_cast<uint32_t>(index));
}
if (auto const &root{groupView.SvgRoot()}) {
root.Invalidate();

View File

@@ -358,6 +358,7 @@ void RenderableView::Unload() {
m_propList.clear();
m_propSetMap.clear();
m_strokeDashArray.Clear();
m_isUnloaded = true;
}
RNSVG::IRenderable RenderableView::HitTest(Point const &point) {

View File

@@ -25,6 +25,8 @@ struct RenderableView : RenderableViewT<RenderableView> {
bool IsResponsible() { return m_isResponsible; }
void IsResponsible(bool isResponsible) { m_isResponsible = isResponsible; }
bool IsUnloaded() { return m_isUnloaded; }
hstring FillBrushId() { return m_fillBrushId; }
Windows::UI::Color Fill() { return m_fill; }
float FillOpacity() { return m_fillOpacity; }
@@ -73,6 +75,7 @@ struct RenderableView : RenderableViewT<RenderableView> {
RNSVG::D2DGeometry m_geometry{nullptr};
bool m_recreateResources{true};
bool m_isResponsible{false};
bool m_isUnloaded{false};
hstring m_id{L""};
hstring m_clipPathId{L""};

View File

@@ -38,6 +38,7 @@ namespace RNSVG
{
RenderableView(Microsoft.ReactNative.IReactContext context);
SvgView SvgRoot{ get; };
Boolean IsUnloaded { get; };
String Id{ get; };
Windows.Foundation.Numerics.Matrix3x2 SvgTransform{ get; };