diff --git a/Kits/ATGTK/PerformanceTimersXbox.cpp b/Kits/ATGTK/PerformanceTimersXbox.cpp index 35add49f..b0ad06a3 100644 --- a/Kits/ATGTK/PerformanceTimersXbox.cpp +++ b/Kits/ATGTK/PerformanceTimersXbox.cpp @@ -330,7 +330,7 @@ void GPUCommandListTimer::Frame::EndFrame(_In_ t_CommandList* /*c } template -void GPUCommandListTimer::Frame::ComputeFrame(_In_ t_CommandList* commandList, _Out_writes_(c_maxTimers) float* lastUpdatedValues) +void GPUCommandListTimer::Frame::ComputeFrame(_In_ t_CommandList* commandList, _Inout_updates_(c_maxTimers) float* lastUpdatedValues) { #if defined(_DEBUG) || defined(PROFILE) bool blocked = false; @@ -341,7 +341,6 @@ void GPUCommandListTimer::Frame::ComputeFrame(_In_ t_CommandList* if (!m_used[j]) { m_timing[j] = 0.f; - lastUpdatedValues[j] = 0.f; continue; } diff --git a/Kits/ATGTK/PerformanceTimersXbox.h b/Kits/ATGTK/PerformanceTimersXbox.h index 6b10b214..dc87f21c 100644 --- a/Kits/ATGTK/PerformanceTimersXbox.h +++ b/Kits/ATGTK/PerformanceTimersXbox.h @@ -144,7 +144,7 @@ namespace DX void BeginFrame(_In_ t_CommandList* commandList); void EndFrame(_In_ t_CommandList* commandList); - void ComputeFrame(_In_ t_CommandList* commandList, _Out_writes_(c_maxTimers) float* lastUpdatedValues); + void ComputeFrame(_In_ t_CommandList* commandList, _Inout_updates_(c_maxTimers) float* lastUpdatedValues); void Start(_In_ t_CommandList* commandList, uint32_t timerid = 0); void Stop(_In_ t_CommandList* commandList, uint32_t timerid = 0); diff --git a/README.md b/README.md index 14897720..48668aba 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,12 @@ This repo contains game development samples written by the Microsoft Xbox Advanc * [Unity](gdk-samples-list.md#Unity) * [xCloud](gdk-samples-list.md#xCloud) +## Other Samples + +For more samples, see [XBOX-Godot-NetRumble](https://github.com/microsoft/XBOX-Godot-NetRumble), and [XBOX-Godot-Sample](https://github.com/microsoft/XBOX-Godot-Sample). + +Legacy samples are also available at [DirectML Samples](https://github.com/microsoft/DirectML), [PlayFab-Samples](https://github.com/PlayFab/PlayFab-Samples), [Xbox-ATG-Samples](https://github.com/microsoft/Xbox-ATG-Samples), and [Xbox-LIVE-Samples](https://github.com/microsoft/xbox-live-samples). + # Requirements * Visual Studio 2022 or later @@ -64,10 +70,6 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies. -## Other Samples - -For more ATG samples, see [DirectML Samples](https://github.com/microsoft/DirectML), [PlayFab-Samples](https://github.com/PlayFab/PlayFab-Samples), [Xbox-ATG-Samples](https://github.com/microsoft/Xbox-ATG-Samples), and [Xbox-LIVE-Samples](https://github.com/microsoft/xbox-live-samples). - ## Samples list by category [Samples List](gdk-samples-list.md) diff --git a/Samples/Audio/SimplePlay3DSound/SimplePlay3DSound.h b/Samples/Audio/SimplePlay3DSound/SimplePlay3DSound.h index 454887f0..4c3eecab 100644 --- a/Samples/Audio/SimplePlay3DSound/SimplePlay3DSound.h +++ b/Samples/Audio/SimplePlay3DSound/SimplePlay3DSound.h @@ -18,7 +18,7 @@ class Sample final : public IXAudio2EngineCallback public: Sample() noexcept(false); - virtual ~Sample(); + ~Sample(); Sample(Sample&&) = delete; Sample& operator= (Sample&&) = delete; diff --git a/Samples/Audio/SimplePlaySound/SimplePlaySound.h b/Samples/Audio/SimplePlaySound/SimplePlaySound.h index f5ce0eae..45310237 100644 --- a/Samples/Audio/SimplePlaySound/SimplePlaySound.h +++ b/Samples/Audio/SimplePlaySound/SimplePlaySound.h @@ -18,7 +18,7 @@ class Sample final : public IXAudio2EngineCallback public: Sample() noexcept(false); - virtual ~Sample(); + ~Sample(); Sample(Sample&&) = delete; Sample& operator= (Sample&&) = delete; diff --git a/Samples/Audio/SimplePlaySoundStream/SimplePlaySoundStream.h b/Samples/Audio/SimplePlaySoundStream/SimplePlaySoundStream.h index 18e964be..4b81d826 100644 --- a/Samples/Audio/SimplePlaySoundStream/SimplePlaySoundStream.h +++ b/Samples/Audio/SimplePlaySoundStream/SimplePlaySoundStream.h @@ -63,7 +63,7 @@ class Sample final : public IXAudio2EngineCallback public: Sample() noexcept(false); - virtual ~Sample(); + ~Sample(); Sample(Sample&&) = delete; Sample& operator= (Sample&&) = delete; diff --git a/Samples/Tools/RemoteIterationToolsSample/CopySearchOptions.cs b/Samples/Tools/RemoteIterationToolsSample/CopySearchOptions.cs index 98e7fe0b..a4d70423 100644 --- a/Samples/Tools/RemoteIterationToolsSample/CopySearchOptions.cs +++ b/Samples/Tools/RemoteIterationToolsSample/CopySearchOptions.cs @@ -5,7 +5,9 @@ public class CopySearchOptions public string? IncludeFilePattern { get; set; } public string? ExcludeFilePattern { get; set; } public string? ExcludeDirPattern { get; set; } - public ulong IncludeFileAttributes { get; set; } - public ulong ExcludeFileAttributes { get; set; } + public uint IncludeFileAttributes { get; set; } + public uint ExcludeFileAttributes { get; set; } + public uint IncludeDirectoryAttributes { get; set; } + public uint ExcludeDirectoryAttributes { get; set; } } } diff --git a/Samples/Tools/RemoteIterationToolsSample/DeleteOptions.cs b/Samples/Tools/RemoteIterationToolsSample/DeleteOptions.cs new file mode 100644 index 00000000..8c047634 --- /dev/null +++ b/Samples/Tools/RemoteIterationToolsSample/DeleteOptions.cs @@ -0,0 +1,8 @@ +namespace RemoteIterationToolsSample +{ + public class DeleteOptions + { + public string? CommonRootAlias { get; init; } + public bool DeleteRootFolder { get; init; } + } +} diff --git a/Samples/Tools/RemoteIterationToolsSample/DeleteSearchOptions.cs b/Samples/Tools/RemoteIterationToolsSample/DeleteSearchOptions.cs new file mode 100644 index 00000000..666e97a1 --- /dev/null +++ b/Samples/Tools/RemoteIterationToolsSample/DeleteSearchOptions.cs @@ -0,0 +1,13 @@ +namespace RemoteIterationToolsSample +{ + public class DeleteSearchOptions + { + public string? IncludeFilePattern { get; init; } + public string? ExcludeFilePattern { get; init; } + public string? ExcludeDirPattern { get; init; } + public ulong IncludeFileAttributes { get; init; } + public ulong ExcludeFileAttributes { get; init; } + public ulong IncludeDirAttributes { get; init; } + public ulong ExcludeDirAttributes { get; init; } + } +} diff --git a/Samples/Tools/RemoteIterationToolsSample/FileAttributeSelector.xaml b/Samples/Tools/RemoteIterationToolsSample/FileAttributeSelector.xaml new file mode 100644 index 00000000..b6c12477 --- /dev/null +++ b/Samples/Tools/RemoteIterationToolsSample/FileAttributeSelector.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/Samples/Tools/RemoteIterationToolsSample/FileAttributeSelector.xaml.cs b/Samples/Tools/RemoteIterationToolsSample/FileAttributeSelector.xaml.cs new file mode 100644 index 00000000..e7e583ea --- /dev/null +++ b/Samples/Tools/RemoteIterationToolsSample/FileAttributeSelector.xaml.cs @@ -0,0 +1,40 @@ +using System.IO; +using System.Windows; + +namespace RemoteIterationToolsSample +{ + public partial class FileAttributeSelector : System.Windows.Controls.UserControl + { + public static readonly DependencyProperty LabelProperty = + DependencyProperty.Register(nameof(Label), typeof(string), typeof(FileAttributeSelector), new PropertyMetadata("")); + + public string Label + { + get => (string)GetValue(LabelProperty); + set => SetValue(LabelProperty, value); + } + + public FileAttributeSelector() + { + InitializeComponent(); + } + + public uint Mask + { + get + { + // These four Windows flags are the subset supported by the RIT filters. + FileAttributes attributes = 0; + if (ReadOnlyCheckBox.IsChecked == true) + attributes |= FileAttributes.ReadOnly; + if (HiddenCheckBox.IsChecked == true) + attributes |= FileAttributes.Hidden; + if (SystemCheckBox.IsChecked == true) + attributes |= FileAttributes.System; + if (ArchiveCheckBox.IsChecked == true) + attributes |= FileAttributes.Archive; + return (uint)attributes; + } + } + } +} diff --git a/Samples/Tools/RemoteIterationToolsSample/MainWindow.Delete.xaml.cs b/Samples/Tools/RemoteIterationToolsSample/MainWindow.Delete.xaml.cs new file mode 100644 index 00000000..21962da5 --- /dev/null +++ b/Samples/Tools/RemoteIterationToolsSample/MainWindow.Delete.xaml.cs @@ -0,0 +1,140 @@ +using System.Windows; +using Windows.Win32.Foundation; + +namespace RemoteIterationToolsSample +{ + public partial class MainWindow + { + private async void Delete_Click(object sender, RoutedEventArgs e) + { + if (_activeOperation != null) + return; + + string device = DeviceIpTextBox.Text.Trim(); + string path = DeleteRemotePathTextBox.Text.Trim(); + if (string.IsNullOrWhiteSpace(device) || string.IsNullOrWhiteSpace(path)) + { + System.Windows.MessageBox.Show("Enter a device and a remote path.", "Delete inputs required"); + return; + } + + var options = new DeleteOptions + { + CommonRootAlias = DeleteCommonRootAliasTextBox.Text.Trim(), + DeleteRootFolder = DeleteRootFolderCheckBox.IsChecked == true + }; + var filters = new DeleteSearchOptions + { + IncludeFilePattern = DeleteIncludeFilePatternTextBox.Text.Trim(), + ExcludeFilePattern = DeleteExcludeFilePatternTextBox.Text.Trim(), + ExcludeDirPattern = DeleteExcludeDirPatternTextBox.Text.Trim(), + IncludeFileAttributes = DeleteIncludeFileAttributesSelector.Mask, + ExcludeFileAttributes = DeleteExcludeFileAttributesSelector.Mask, + IncludeDirAttributes = DeleteIncludeDirAttributesSelector.Mask, + ExcludeDirAttributes = DeleteExcludeDirAttributesSelector.Mask + }; + string confirmation = DescribeDeleteRequest(device, path, options, filters); + if (System.Windows.MessageBox.Show(this, confirmation + "\n\nDelete matching content?", + "Confirm remote deletion", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No) != MessageBoxResult.Yes) + return; + + var operation = new OperationState("Delete", device, path) + { + DeleteOptions = options, + DeleteSearchOptions = filters + }; + if (!BeginOperation(operation)) + return; + + try + { + AppendOutput("> Remote delete request\n" + confirmation + "\n\n"); + operation.CreateCancellationHandle(); + operation.DeleteActive = true; + StopWaitingDeleteButton.IsEnabled = true; + DeleteProgressBar.IsIndeterminate = true; + DeleteStatusText.Text = "Deleting..."; + HRESULT hr = await RemoteIteration.DeleteAsync( + operation.Device, operation.RemotePath, operation.DeleteOptions, operation.DeleteSearchOptions, operation.CancellationHandle); + + operation.DeleteActive = false; + StopWaitingDeleteButton.IsEnabled = false; + DeleteStatusText.Text = DescribeDeleteResult(hr, operation.StopWaitingRequested); + AppendOutput($"\nDelete returned HRESULT 0x{hr.Value:X8}. {DeleteStatusText.Text}\n"); + } + catch (Exception ex) + { + ShowOperationFailure(operation, ex); + DeleteStatusText.Text = DescribeDeleteResult(new HRESULT(ex.HResult), operation.StopWaitingRequested); + } + finally + { + operation.DeleteActive = false; + DeleteProgressBar.IsIndeterminate = false; + EndOperation(operation); + } + } + + private static string DescribeDeleteRequest(string device, string path, DeleteOptions options, DeleteSearchOptions filters) + { + var activeFilters = new List(); + if (!string.IsNullOrEmpty(filters.IncludeFilePattern)) + activeFilters.Add($"Include files: {filters.IncludeFilePattern}"); + if (!string.IsNullOrEmpty(filters.ExcludeFilePattern)) + activeFilters.Add($"Exclude files: {filters.ExcludeFilePattern}"); + if (!string.IsNullOrEmpty(filters.ExcludeDirPattern)) + activeFilters.Add($"Exclude directories: {filters.ExcludeDirPattern}"); + if (filters.IncludeFileAttributes != 0) + activeFilters.Add($"Include file attributes: {filters.IncludeFileAttributes}"); + if (filters.ExcludeFileAttributes != 0) + activeFilters.Add($"Exclude file attributes: {filters.ExcludeFileAttributes}"); + if (filters.IncludeDirAttributes != 0) + activeFilters.Add($"Include directory attributes: {filters.IncludeDirAttributes}"); + if (filters.ExcludeDirAttributes != 0) + activeFilters.Add($"Exclude directory attributes: {filters.ExcludeDirAttributes}"); + + return $"Device: {device}\nPath: {path}\n" + + $"Common Root alias: {(string.IsNullOrEmpty(options.CommonRootAlias) ? "(default)" : options.CommonRootAlias)}\n" + + $"Remove root folder: {(options.DeleteRootFolder ? "If empty" : "No")}\n" + + (activeFilters.Count == 0 ? "Filters: none" : "Folder filters:\n" + string.Join("\n", activeFilters)); + } + + private static string DescribeDeleteResult(HRESULT hr, bool stopWaitingRequested) + { + if (hr.Failed) + return "Delete request failed." + (stopWaitingRequested ? " Remote deletion may continue." : ""); + + // Normal completion and an observed stop-wait signal can both return S_OK. + return stopWaitingRequested + ? "Stopped waiting. Remote deletion may continue." + : "Delete request completed; some items may remain."; + } + + private void StopWaitingDelete_Click(object sender, RoutedEventArgs e) + { + OperationState? operation = _activeOperation; + if (operation == null || !operation.DeleteActive || operation.StopWaitingRequested || operation.CancellationHandle == null) + return; + + operation.StopWaitingRequested = true; + StopWaitingDeleteButton.IsEnabled = false; + DeleteStatusText.Text = "Stopping wait..."; + try + { + // The nonblocking UI-thread signal cannot race the awaited call's handle disposal. + HRESULT hr = RemoteIteration.RequestDeleteStopWaiting(operation.CancellationHandle); + AppendOutput($"Stop-wait signal returned HRESULT 0x{hr.Value:X8}.\n"); + if (hr.Failed) + { + DeleteStatusText.Text = "Stop-wait signal failed; the client may still be waiting."; + AppendOutput(DeleteStatusText.Text + "\n"); + } + } + catch (Exception ex) + { + AppendOutput($"Stop-wait signal failed: {ex.Message} (HRESULT 0x{ex.HResult:X8}).\n"); + DeleteStatusText.Text = "Stop-wait signal failed; the client may still be waiting."; + } + } + } +} diff --git a/Samples/Tools/RemoteIterationToolsSample/MainWindow.xaml b/Samples/Tools/RemoteIterationToolsSample/MainWindow.xaml index ba21f09b..b7756368 100644 --- a/Samples/Tools/RemoteIterationToolsSample/MainWindow.xaml +++ b/Samples/Tools/RemoteIterationToolsSample/MainWindow.xaml @@ -3,15 +3,28 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:RemoteIterationToolsSample" mc:Ignorable="d" Title="Remote Deployment" Height="961" Width="752" - Background="#FF1E1E24" WindowStartupLocation="CenterScreen"> + Background="#FF1E1E24" WindowStartupLocation="CenterScreen" Closing="Window_Closing"> + + - + + - + @@ -117,92 +131,190 @@ - - - + + + + + - - - - -