Skip to content

Fix crash on some cases of path groups. - #379

Merged
simeoncran merged 5 commits into
masterfrom
PathCrash
Nov 13, 2020
Merged

simeoncran merged 5 commits into
masterfrom
PathCrash

Conversation

@simeoncran

Copy link
Copy Markdown
Contributor

As a result of looking again at the algorithm that we use to combine animated paths I decided it needed a lot more documentation and to be rewritten to make sure that we handle all cases.

As a result of looking again at the algorithm that we use to combine animated paths I decided it needed a lot more documentation and to be rewritten to make sure that we handle all cases.
@simeoncran
simeoncran requested a review from a team as a code owner November 4, 2020 22:51
// Get enumerators for the key frames in each of the Animatable<PathGeometry>s.
var enumerators = pathData.Select(EnumerateKeyFrames).ToArray();

// Start enumerating.

@derobinsMSFT derobinsMSFT Nov 6, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Start enumerating. [](start = 12, length = 21)

Why are we skipping the first keyframe in each path? Is it because we don't need the starting values if the path is animated? #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not skipping anything. We are simply moving to the first item in the enumeration. Enumerators have to have MoveNext() called on them to get to the first item. If it didn't work that way there would be no way to handle empty enumerations.


In reply to: 518930487 [](ancestors = 518930487)

for (var i = 0; i < enumerators.Length; i++)
{
var enumerator = enumerators[i];
if (!enumerator.Current.isCompleted &&

@simeoncran simeoncran Nov 6, 2020 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!enumerator.Current.isCompleted && [](start = 24, length = 34)

I don't think this is necessary - the enumerators will happily output forever. #Closed

var frames = groupsByFrame.OrderBy(kvp => kvp.Key).Select(kvp => (frame: kvp.Key, geometries: kvp.Value)).ToArray();
var previousGeometries = frames[0].geometries;
var success = true;
result =

@derobinsMSFT derobinsMSFT Nov 6, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result = [](start = 12, length = 8)

Add comment explaining what this assignment is doing. #Closed

if (frameIndex > 0)
{
previousKeyFrame = records[frameIndex - 1].Geometries[pathIndex];
}

@derobinsMSFT derobinsMSFT Nov 9, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add another comment here explaining why we only look back one frame for the "previous" key frame but might look ahead by multiple frames for the "next" one-- just for extra clarity. #Closed


// Fill in the null with the value from the closest key frame.
records[frameIndex].Geometries[pathIndex] =
new KeyFrame<PathGeometry>(currentFrameNumber, closestKeyFrame.Value, HoldEasing.Instance);

@derobinsMSFT derobinsMSFT Nov 9, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HoldEasing.Instance [](start = 98, length = 19)

Should this be whatever the preferred easing of the record is instead? #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the easing doesn't matter here - the KeyFrame is just a convenient way to store a frame number an PathGeometry. When we create the Animatable we'll use the PreferredEasing only.


In reply to: 520098584 [](ancestors = 520098584)

/// Takes a group of possibly-animated paths and returns an animatable
/// of PathGeometryGroups. Returns true if it succeeds without issues.
/// Even if false is returned a best-effort animatable is returned.</summary>
/// <returns><c>true</c> iff the grouping worked perfectly.</returns>

@patrickeganMSFT patrickeganMSFT Nov 10, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it's worth it to add something about returning false in the return section? Not sure how likely it would be that someone would read only the return section and not the summary, but worth considering. #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The renaming of the method will fix this.


In reply to: 520757936 [](ancestors = 520757936)

derobinsMSFT
derobinsMSFT previously approved these changes Nov 10, 2020

@derobinsMSFT derobinsMSFT left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

foreach (var (frame, geometries) in frames.Skip(1))
/// <summary>
/// From a list of animatable paths, produce a record for each distinct key frame number.
/// Each record consists of the frame number a list of geometries for that frame number

@benwestprog benwestprog Nov 11, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

number [](start = 46, length = 6)

number, #Closed

success = false;
indices[i] = -1;
}
}

@benwestprog benwestprog Nov 11, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used anywhere? #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Called from line 93


In reply to: 520956036 [](ancestors = 520956036)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you mean indices... Ooops. Old code.


In reply to: 522427828 [](ancestors = 522427828,520956036)

/// of PathGeometryGroups. Returns true if it succeeds without issues.
/// Even if false is returned a best-effort animatable is returned.</summary>
/// <returns><c>true</c> iff the grouping worked perfectly.</returns>
internal static bool TryGroupPaths(

@benwestprog benwestprog Nov 11, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TryGroupPaths [](start = 29, length = 13)

The naming here threw me until I read the comments, expected null with a false return to match other common "Try" methods. Not sure what the local idiom is, but if this isn't consistent consider a more suggestive name, maybe leave out the "Try"? Or make the bool an out param with a helpful name? #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestion.


In reply to: 520959164 [](ancestors = 520959164)

// Get the key frame for the current frame number.
var keyFrame = records[frameIndex].Geometries[pathIndex];
if (keyFrame is null)
{

@benwestprog benwestprog Nov 11, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving this block into its own method, to make this one more readable. It's over three screens in my CodeFlow view. #Closed

benwestprog
benwestprog previously approved these changes Nov 11, 2020

@benwestprog benwestprog left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@simeoncran
simeoncran dismissed stale reviews from benwestprog and derobinsMSFT via ecb9169 November 12, 2020 21:33

@benwestprog benwestprog left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@derobinsMSFT derobinsMSFT left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@simeoncran
simeoncran merged commit 078ad23 into master Nov 13, 2020
@delete-merged-branch
delete-merged-branch Bot deleted the PathCrash branch November 13, 2020 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants