Skip to content

Commit bd033e8

Browse files
authored
Merge branch 'master' into improvement/dispatcher-queue-helper
2 parents 92b4fca + 43693f8 commit bd033e8

File tree

285 files changed

+22093
-7124
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

285 files changed

+22093
-7124
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,25 @@ assignees: ''
77

88
---
99

10-
<!--
11-
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
12-
ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
13-
-->
10+
<!-- 🚨 Please Do Not skip any instructions and information mentioned below as they are all required and essential to investigate the issue. Issues with missing information may be closed without investigation 🚨 -->
1411

1512
## Describe the bug
1613
A clear and concise description of what the bug is.
1714

1815
- [ ] Is this bug a regression in the toolkit? If so, what toolkit version did you last see it work:
1916

2017
## Steps to Reproduce
18+
19+
- [ ] Can this be reproduced in the Sample App? (Either in a sample as-is or with new XAML pasted in the editor.) If so, please provide custom XAML or steps to reproduce. If not, let us know why it can't be reproduced (e.g. more complex setup, environment, dependencies, etc...) <!-- Being able to reproduce the problem in the sample app, really stream-lines the whole process in being able to discover, resolve, and validate bug fixes. -->
20+
2121
Steps to reproduce the behavior:
22-
1. Go to '...'
23-
2. Click on '....'
24-
3. Scroll down to '....'
25-
4. See error
22+
1. Given the following environment (Sample App w/ XAML, Project with Isolated setup, etc...)
23+
2. Go to '...'
24+
3. Click on '....'
25+
4. Scroll down to '....'
26+
5. See error
27+
28+
<!-- Provide as many code-snippets or XAML snippets where appropriate. -->
2629

2730
## Expected behavior
2831
A clear and concise description of what you expected to happen.

.github/ISSUE_TEMPLATE/feature_request.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ assignees: ''
77

88
---
99

10+
<!-- 🚨 Please provide detailed information and Do Not skip any instructions as they are all required and essential to help us understand the feature 🚨 -->
11+
1012
## Describe the problem this feature would solve
1113
<!-- Please describe or link to any existing issues or discussions.
1214
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->

.github/ISSUE_TEMPLATE/question.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Hi!
1313
We try and keep our GitHub issue list for bugs and features.
1414
1515
Ideally, it'd be great to post your question on Stack Overflow using the 'windows-community-toolkit' tag here: https://stackoverflow.com/questions/tagged/windows-community-toolkit
16+
🚨 Please provide detailed information that includes examples, screenshots, and relevant issues if possible 🚨
1617
1718
If this is more about a scenario that you think is missing documentation, please file an issue instead at https://github.com/MicrosoftDocs/WindowsCommunityToolkitDocs/issues/new
1819

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
<!-- 🚨 Please Do Not skip any instructions and information mentioned below as they are all required and essential to evaluate and test the PR. By fulfilling all the required information you will be able to reduce the volume of questions and most likely help merge the PR faster 🚨 -->
2+
13
## Fixes #
24
<!-- Add the relevant issue number after the "#" mentioned above (for ex: Fixes #1234) which will automatically close the issue once the PR is merged. -->
35

@@ -38,7 +40,7 @@ Please check if your PR fulfills the following requirements:
3840
- [ ] Contains **NO** breaking changes
3941

4042
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below.
41-
Please note that breaking changes are likely to be rejected. -->
43+
Please note that breaking changes are likely to be rejected within minor release cycles or held until major versions. -->
4244

4345

4446
## Other information

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,8 @@ msbuild.binlog
227227
!/build/tools/packages.config
228228

229229
# Generated file from .ttinclude
230-
**/Generated/TypeInfo.g.cs
230+
**/Generated/TypeInfo.g.cs
231+
232+
# TAEF Log output
233+
WexLogFileOutput
234+
*.wtl

GazeInputTest/GazeInputTest.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@
157157
</PackageReference>
158158
</ItemGroup>
159159
<ItemGroup>
160-
<ProjectReference Include="..\Microsoft.Toolkit.UWP.Input.GazeInteraction\Microsoft.Toolkit.Uwp.Input.GazeInteraction.vcxproj">
161-
<Project>{a5e98964-45b1-442d-a07a-298a3221d81e}</Project>
160+
<ProjectReference Include="..\Microsoft.Toolkit.Uwp.Input.GazeInteraction\Microsoft.Toolkit.Uwp.Input.GazeInteraction.csproj">
161+
<Project>{5bf75694-798a-43a0-8150-415de195359c}</Project>
162162
<Name>Microsoft.Toolkit.Uwp.Input.GazeInteraction</Name>
163163
</ProjectReference>
164164
</ItemGroup>

GazeInputTest/Properties/AssemblyInfo.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using System.Reflection;
66
using System.Runtime.InteropServices;
77

8-
// General Information about an assembly is controlled through the following
8+
// General Information about an assembly is controlled through the following
99
// set of attributes. Change these attribute values to modify the information
1010
// associated with an assembly.
1111
[assembly: AssemblyTitle("GazeInputTest")]
@@ -20,13 +20,13 @@
2020
// Version information for an assembly consists of the following four values:
2121
//
2222
// Major Version
23-
// Minor Version
23+
// Minor Version
2424
// Build Number
2525
// Revision
2626
//
27-
// You can specify all the values or you can default the Build and Revision Numbers
27+
// You can specify all the values or you can default the Build and Revision Numbers
2828
// by using the '*' as shown below:
2929
// [assembly: AssemblyVersion("1.0.*")]
30-
//[assembly: AssemblyVersion("1.0.0.0")]
31-
//[assembly: AssemblyFileVersion("1.0.0.0")]
30+
// [assembly: AssemblyVersion("1.0.0.0")]
31+
// [assembly: AssemblyFileVersion("1.0.0.0")]
3232
[assembly: ComVisible(false)]

Microsoft.Toolkit.HighPerformance/Box{T}.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public static bool TryGetFrom(object obj, [NotNullWhen(true)] out Box<T>? box)
125125
[MethodImpl(MethodImplOptions.AggressiveInlining)]
126126
public static implicit operator T(Box<T> box)
127127
{
128-
return Unsafe.Unbox<T>(box);
128+
return (T)(object)box;
129129
}
130130

131131
/// <summary>
@@ -180,7 +180,6 @@ public override int GetHashCode()
180180
/// <summary>
181181
/// Throws an <see cref="InvalidCastException"/> when a cast from an invalid <see cref="object"/> is attempted.
182182
/// </summary>
183-
[MethodImpl(MethodImplOptions.NoInlining)]
184183
private static void ThrowInvalidCastExceptionForGetFrom()
185184
{
186185
throw new InvalidCastException($"Can't cast the input object to the type Box<{typeof(T)}>");

Microsoft.Toolkit.HighPerformance/Buffers/ArrayPoolBufferWriter{T}.cs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Microsoft.Toolkit.HighPerformance.Buffers
2424
/// the arrays in use are rented from the shared <see cref="ArrayPool{T}"/> instance,
2525
/// and that <see cref="ArrayPoolBufferWriter{T}"/> is also available on .NET Standard 2.0.
2626
/// </remarks>
27-
[DebuggerTypeProxy(typeof(ArrayPoolBufferWriterDebugView<>))]
27+
[DebuggerTypeProxy(typeof(MemoryDebugView<>))]
2828
[DebuggerDisplay("{ToString(),raw}")]
2929
public sealed class ArrayPoolBufferWriter<T> : IBuffer<T>, IMemoryOwner<T>
3030
{
@@ -33,6 +33,11 @@ public sealed class ArrayPoolBufferWriter<T> : IBuffer<T>, IMemoryOwner<T>
3333
/// </summary>
3434
private const int DefaultInitialBufferSize = 256;
3535

36+
/// <summary>
37+
/// The <see cref="ArrayPool{T}"/> instance used to rent <see cref="array"/>.
38+
/// </summary>
39+
private readonly ArrayPool<T> pool;
40+
3641
/// <summary>
3742
/// The underlying <typeparamref name="T"/> array.
3843
/// </summary>
@@ -49,36 +54,52 @@ public sealed class ArrayPoolBufferWriter<T> : IBuffer<T>, IMemoryOwner<T>
4954
/// Initializes a new instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
5055
/// </summary>
5156
public ArrayPoolBufferWriter()
57+
: this(ArrayPool<T>.Shared, DefaultInitialBufferSize)
58+
{
59+
}
60+
61+
/// <summary>
62+
/// Initializes a new instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
63+
/// </summary>
64+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance to use.</param>
65+
public ArrayPoolBufferWriter(ArrayPool<T> pool)
66+
: this(pool, DefaultInitialBufferSize)
5267
{
53-
// Since we're using pooled arrays, we can rent the buffer with the
54-
// default size immediately, we don't need to use lazy initialization
55-
// to save unnecessary memory allocations in this case.
56-
this.array = ArrayPool<T>.Shared.Rent(DefaultInitialBufferSize);
57-
this.index = 0;
5868
}
5969

6070
/// <summary>
6171
/// Initializes a new instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
6272
/// </summary>
6373
/// <param name="initialCapacity">The minimum capacity with which to initialize the underlying buffer.</param>
64-
/// <exception cref="ArgumentException">
65-
/// Thrown when <paramref name="initialCapacity"/> is not positive (i.e. less than or equal to 0).
66-
/// </exception>
74+
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="initialCapacity"/> is not valid.</exception>
6775
public ArrayPoolBufferWriter(int initialCapacity)
76+
: this(ArrayPool<T>.Shared, initialCapacity)
6877
{
69-
if (initialCapacity <= 0)
70-
{
71-
ThrowArgumentOutOfRangeExceptionForInitialCapacity();
72-
}
78+
}
7379

74-
this.array = ArrayPool<T>.Shared.Rent(initialCapacity);
80+
/// <summary>
81+
/// Initializes a new instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
82+
/// </summary>
83+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance to use.</param>
84+
/// <param name="initialCapacity">The minimum capacity with which to initialize the underlying buffer.</param>
85+
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="initialCapacity"/> is not valid.</exception>
86+
public ArrayPoolBufferWriter(ArrayPool<T> pool, int initialCapacity)
87+
{
88+
// Since we're using pooled arrays, we can rent the buffer with the
89+
// default size immediately, we don't need to use lazy initialization
90+
// to save unnecessary memory allocations in this case.
91+
// Additionally, we don't need to manually throw the exception if
92+
// the requested size is not valid, as that'll be thrown automatically
93+
// by the array pool in use when we try to rent an array with that size.
94+
this.pool = pool;
95+
this.array = pool.Rent(initialCapacity);
7596
this.index = 0;
7697
}
7798

7899
/// <summary>
79100
/// Finalizes an instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
80101
/// </summary>
81-
~ArrayPoolBufferWriter() => this.Dispose();
102+
~ArrayPoolBufferWriter() => Dispose();
82103

83104
/// <inheritdoc/>
84105
Memory<T> IMemoryOwner<T>.Memory
@@ -182,6 +203,7 @@ public void Clear()
182203
}
183204

184205
array.AsSpan(0, this.index).Clear();
206+
185207
this.index = 0;
186208
}
187209

@@ -250,7 +272,7 @@ private void CheckAndResizeBuffer(int sizeHint)
250272
{
251273
int minimumSize = this.index + sizeHint;
252274

253-
ArrayPool<T>.Shared.Resize(ref this.array, minimumSize);
275+
this.pool.Resize(ref this.array, minimumSize);
254276
}
255277
}
256278

@@ -268,7 +290,7 @@ public void Dispose()
268290

269291
this.array = null;
270292

271-
ArrayPool<T>.Shared.Return(array);
293+
this.pool.Return(array);
272294
}
273295

274296
/// <inheritdoc/>
@@ -286,19 +308,9 @@ public override string ToString()
286308
return $"Microsoft.Toolkit.HighPerformance.Buffers.ArrayPoolBufferWriter<{typeof(T)}>[{this.index}]";
287309
}
288310

289-
/// <summary>
290-
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the initial capacity is invalid.
291-
/// </summary>
292-
[MethodImpl(MethodImplOptions.NoInlining)]
293-
private static void ThrowArgumentOutOfRangeExceptionForInitialCapacity()
294-
{
295-
throw new ArgumentOutOfRangeException("initialCapacity", "The initial capacity must be a positive value");
296-
}
297-
298311
/// <summary>
299312
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the requested count is negative.
300313
/// </summary>
301-
[MethodImpl(MethodImplOptions.NoInlining)]
302314
private static void ThrowArgumentOutOfRangeExceptionForNegativeCount()
303315
{
304316
throw new ArgumentOutOfRangeException("count", "The count can't be a negative value");
@@ -307,7 +319,6 @@ private static void ThrowArgumentOutOfRangeExceptionForNegativeCount()
307319
/// <summary>
308320
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the size hint is negative.
309321
/// </summary>
310-
[MethodImpl(MethodImplOptions.NoInlining)]
311322
private static void ThrowArgumentOutOfRangeExceptionForNegativeSizeHint()
312323
{
313324
throw new ArgumentOutOfRangeException("sizeHint", "The size hint can't be a negative value");
@@ -316,7 +327,6 @@ private static void ThrowArgumentOutOfRangeExceptionForNegativeSizeHint()
316327
/// <summary>
317328
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the requested count is negative.
318329
/// </summary>
319-
[MethodImpl(MethodImplOptions.NoInlining)]
320330
private static void ThrowArgumentExceptionForAdvancedTooFar()
321331
{
322332
throw new ArgumentException("The buffer writer has advanced too far");
@@ -325,7 +335,6 @@ private static void ThrowArgumentExceptionForAdvancedTooFar()
325335
/// <summary>
326336
/// Throws an <see cref="ObjectDisposedException"/> when <see cref="array"/> is <see langword="null"/>.
327337
/// </summary>
328-
[MethodImpl(MethodImplOptions.NoInlining)]
329338
private static void ThrowObjectDisposedException()
330339
{
331340
throw new ObjectDisposedException("The current buffer has already been disposed");
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
#if SPAN_RUNTIME_SUPPORT
6+
7+
using System;
8+
using System.Buffers;
9+
using System.Runtime.CompilerServices;
10+
using System.Runtime.InteropServices;
11+
using Microsoft.Toolkit.HighPerformance.Extensions;
12+
13+
namespace Microsoft.Toolkit.HighPerformance.Buffers.Internals
14+
{
15+
/// <summary>
16+
/// A custom <see cref="MemoryManager{T}"/> that can wrap arbitrary <see cref="object"/> instances.
17+
/// </summary>
18+
/// <typeparam name="T">The type of elements in the target memory area.</typeparam>
19+
internal sealed class RawObjectMemoryManager<T> : MemoryManager<T>
20+
{
21+
/// <summary>
22+
/// The target <see cref="object"/> instance.
23+
/// </summary>
24+
private readonly object instance;
25+
26+
/// <summary>
27+
/// The initial offset within <see cref="instance"/>.
28+
/// </summary>
29+
private readonly IntPtr offset;
30+
31+
/// <summary>
32+
/// The length of the target memory area.
33+
/// </summary>
34+
private readonly int length;
35+
36+
/// <summary>
37+
/// Initializes a new instance of the <see cref="RawObjectMemoryManager{T}"/> class.
38+
/// </summary>
39+
/// <param name="instance">The target <see cref="object"/> instance.</param>
40+
/// <param name="offset">The starting offset within <paramref name="instance"/>.</param>
41+
/// <param name="length">The usable length within <paramref name="instance"/>.</param>
42+
public RawObjectMemoryManager(object instance, IntPtr offset, int length)
43+
{
44+
this.instance = instance;
45+
this.offset = offset;
46+
this.length = length;
47+
}
48+
49+
/// <inheritdoc/>
50+
public override Span<T> GetSpan()
51+
{
52+
ref T r0 = ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset);
53+
54+
return MemoryMarshal.CreateSpan(ref r0, this.length);
55+
}
56+
57+
/// <inheritdoc/>
58+
public override unsafe MemoryHandle Pin(int elementIndex = 0)
59+
{
60+
if ((uint)elementIndex >= (uint)this.length)
61+
{
62+
ThrowArgumentOutOfRangeExceptionForInvalidElementIndex();
63+
}
64+
65+
// Allocating a pinned handle for the array with fail and throw an exception
66+
// if the array contains non blittable data. This is the expected behavior and
67+
// the same happens when trying to pin a Memory<T> instance obtained through
68+
// traditional means (eg. via the implicit T[] array conversion), if T is a
69+
// reference type or a type containing some references.
70+
GCHandle handle = GCHandle.Alloc(this.instance, GCHandleType.Pinned);
71+
ref T r0 = ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset);
72+
ref T r1 = ref Unsafe.Add(ref r0, (nint)(uint)elementIndex);
73+
void* p = Unsafe.AsPointer(ref r1);
74+
75+
return new MemoryHandle(p, handle);
76+
}
77+
78+
/// <inheritdoc/>
79+
public override void Unpin()
80+
{
81+
}
82+
83+
/// <inheritdoc/>
84+
protected override void Dispose(bool disposing)
85+
{
86+
}
87+
88+
/// <summary>
89+
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the input index for <see cref="Pin"/> is not valid.
90+
/// </summary>
91+
private static void ThrowArgumentOutOfRangeExceptionForInvalidElementIndex()
92+
{
93+
throw new ArgumentOutOfRangeException("elementIndex", "The input element index was not in the valid range");
94+
}
95+
}
96+
}
97+
98+
#endif

0 commit comments

Comments
 (0)