Skip to content

Commit

Permalink
[UWP] Fix circular reference in ImageOpened lambda for Auto sized ima…
Browse files Browse the repository at this point in the history
…ge handling (#3507)
  • Loading branch information
RebeccaAnne authored Oct 9, 2019
1 parent 441c1d6 commit 8058022
Showing 1 changed file with 48 additions and 15 deletions.
63 changes: 48 additions & 15 deletions source/uwp/Renderer/lib/AdaptiveImageRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,17 +697,33 @@ namespace AdaptiveNamespace
THROW_IF_FAILED(ellipseAsUIElement->put_Visibility(Visibility::Visibility_Collapsed));
// Handle ImageOpened event so we can check the imageSource's size to determine if it fits in its parent
EventRegistrationToken eventToken;
ComPtr<IInspectable> strongParentElement(parentElement);
ComPtr<IInspectable> localParentElement(parentElement);

// Take weak references to the ellipse and parent to avoid circular references between this lambda and
// its parents (Parent->Ellipse->ImageBrush->Lambda->(Parent and Ellipse))
WeakRef weakParent;
THROW_IF_FAILED(localParentElement.AsWeak(&weakParent));

WeakRef weakEllipse;
THROW_IF_FAILED(ellipseAsUIElement.AsWeak(&weakEllipse));
THROW_IF_FAILED(brushAsImageBrush->add_ImageOpened(
Callback<IRoutedEventHandler>([ellipseAsUIElement, ellipseAsFrameworkElement, imageSourceAsBitmap, strongParentElement, isVisible](
Callback<IRoutedEventHandler>([weakEllipse, imageSourceAsBitmap, weakParent, isVisible](
IInspectable* /*sender*/, IRoutedEventArgs * /*args*/) -> HRESULT {
if (isVisible)
{
RETURN_IF_FAILED(ellipseAsUIElement->put_Visibility(Visibility::Visibility_Visible));
RETURN_IF_FAILED(XamlHelpers::SetAutoImageSize(ellipseAsFrameworkElement.Get(),
strongParentElement.Get(),
imageSourceAsBitmap.Get(),
isVisible));
ComPtr<IFrameworkElement> lambdaEllipseAsFrameworkElement;
RETURN_IF_FAILED(weakEllipse.As(&lambdaEllipseAsFrameworkElement));

ComPtr<IInspectable> lambdaParentElement;
RETURN_IF_FAILED(weakParent.As(&lambdaParentElement));

if (lambdaEllipseAsFrameworkElement && lambdaParentElement)
{
RETURN_IF_FAILED(XamlHelpers::SetAutoImageSize(lambdaEllipseAsFrameworkElement.Get(),
lambdaParentElement.Get(),
imageSourceAsBitmap.Get(),
isVisible));
}
}
return S_OK;
}).Get(),
Expand Down Expand Up @@ -743,16 +759,33 @@ namespace AdaptiveNamespace
THROW_IF_FAILED(imageAsUIElement->put_Visibility(Visibility::Visibility_Collapsed));

// Handle ImageOpened event so we can check the imageSource's size to determine if it fits in its parent
ComPtr<IInspectable> strongParentElement(parentElement);
ComPtr<IInspectable> localParentElement(parentElement);

// Take weak references to the image and parent to avoid circular references between this lambda and
// its parents (Parent->Image->Lambda->(Parent and Image))
WeakRef weakParent;
THROW_IF_FAILED(localParentElement.AsWeak(&weakParent));

WeakRef weakImage;
THROW_IF_FAILED(imageAsFrameworkElement.AsWeak(&weakImage));
EventRegistrationToken eventToken;
THROW_IF_FAILED(xamlImage->add_ImageOpened(
Callback<IRoutedEventHandler>([imageAsFrameworkElement, strongParentElement, imageSourceAsBitmap, isVisible](
IInspectable* /*sender*/, IRoutedEventArgs *
/*args*/) -> HRESULT {
return XamlHelpers::SetAutoImageSize(imageAsFrameworkElement.Get(),
strongParentElement.Get(),
imageSourceAsBitmap.Get(),
isVisible);
Callback<IRoutedEventHandler>([weakImage, weakParent, imageSourceAsBitmap, isVisible](IInspectable* /*sender*/, IRoutedEventArgs *
/*args*/) -> HRESULT {
ComPtr<IFrameworkElement> lambdaImageAsFrameworkElement;
RETURN_IF_FAILED(weakImage.As(&lambdaImageAsFrameworkElement));

ComPtr<IInspectable> lambdaParentElement;
RETURN_IF_FAILED(weakParent.As(&lambdaParentElement));

if (lambdaImageAsFrameworkElement && lambdaParentElement)
{
RETURN_IF_FAILED(XamlHelpers::SetAutoImageSize(lambdaImageAsFrameworkElement.Get(),
lambdaParentElement.Get(),
imageSourceAsBitmap.Get(),
isVisible));
}
return S_OK;
}).Get(),
&eventToken));
}
Expand Down

0 comments on commit 8058022

Please sign in to comment.