Skip to content

Commit

Permalink
WPF Providers
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Jan 6, 2024
1 parent edf8ee6 commit 75923d1
Show file tree
Hide file tree
Showing 15 changed files with 382 additions and 147 deletions.
9 changes: 8 additions & 1 deletion R3.sln
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{C7327A31-4
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "R3.WPF", "src\R3.WPF\R3.WPF.csproj", "{57AC0130-0D5F-489A-A565-B41EF9928085}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R3.WPF", "src\R3.WPF\R3.WPF.csproj", "{57AC0130-0D5F-489A-A565-B41EF9928085}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApp1", "sandbox\WpfApp1\WpfApp1.csproj", "{BA40E541-3BCD-438A-B966-2FC7BE80AB80}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -46,6 +48,10 @@ Global
{57AC0130-0D5F-489A-A565-B41EF9928085}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57AC0130-0D5F-489A-A565-B41EF9928085}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57AC0130-0D5F-489A-A565-B41EF9928085}.Release|Any CPU.Build.0 = Release|Any CPU
{BA40E541-3BCD-438A-B966-2FC7BE80AB80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA40E541-3BCD-438A-B966-2FC7BE80AB80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA40E541-3BCD-438A-B966-2FC7BE80AB80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA40E541-3BCD-438A-B966-2FC7BE80AB80}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -55,6 +61,7 @@ Global
{72DE3CB9-195E-4740-9416-5960D75ED795} = {FAB2137C-1DBA-4F2F-8E22-DF3521C9B365}
{42F7C4F7-3BB3-4DC8-8285-9DFF7E93BC4B} = {0544806B-3BB4-43CF-8277-BC612F32208D}
{57AC0130-0D5F-489A-A565-B41EF9928085} = {9FA6D327-728B-4436-AE3A-9E46D8FEF591}
{BA40E541-3BCD-438A-B966-2FC7BE80AB80} = {FAB2137C-1DBA-4F2F-8E22-DF3521C9B365}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {84B77761-6B9E-46BA-B132-6C77B0B6E4FA}
Expand Down
9 changes: 9 additions & 0 deletions sandbox/WpfApp1/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
StartupUri="MainWindow.xaml">
<Application.Resources>

</Application.Resources>
</Application>
12 changes: 12 additions & 0 deletions sandbox/WpfApp1/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Configuration;
using System.Data;
using System.Windows;

namespace WpfApp1;
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}

10 changes: 10 additions & 0 deletions sandbox/WpfApp1/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
12 changes: 12 additions & 0 deletions sandbox/WpfApp1/MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBlock Name="textBlock" HorizontalAlignment="Left" Margin="108,131,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="50" Width="292"/>
</Grid>
</Window>
49 changes: 49 additions & 0 deletions sandbox/WpfApp1/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using R3;
using R3.WPF;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfApp1;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();



//Dispatcher.Yield(DispatcherPriority.Input);



R3.WPF.WpfProviderInitializer.SetDefaultProviders();




//var sw = Stopwatch.StartNew();
//Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5)).Subscribe(_ =>
//{
// textBlock.Text = "Hello World:" + sw.Elapsed;
//});

Observable.TimerFrame(50, 100).Subscribe(_ =>
{
textBlock.Text = "Hello World:" + ObservableSystem.DefaultFrameProvider.GetFrameCount();
});
}
}
16 changes: 16 additions & 0 deletions sandbox/WpfApp1/WpfApp1.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\R3.WPF\R3.WPF.csproj" />
<ProjectReference Include="..\..\src\R3\R3.csproj" />
</ItemGroup>

</Project>
27 changes: 0 additions & 27 deletions src/R3.WPF/DispatcherFrameProvider.cs

This file was deleted.

77 changes: 0 additions & 77 deletions src/R3.WPF/DispatcherTimerProvider.cs

This file was deleted.

119 changes: 119 additions & 0 deletions src/R3.WPF/WpfDispatcherTimerProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System.Windows.Threading;

namespace R3.WPF;

public sealed class WpfDispatcherTimerProvider : TimeProvider
{
readonly DispatcherPriority? priority;
readonly Dispatcher? dispatcher;

public WpfDispatcherTimerProvider()
{
this.priority = null;
this.dispatcher = null;
}

public WpfDispatcherTimerProvider(DispatcherPriority priority)
{
this.priority = priority;
this.dispatcher = null;
}

public WpfDispatcherTimerProvider(DispatcherPriority priority, Dispatcher dispatcher)
{
this.priority = priority;
this.dispatcher = dispatcher;
}

public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period)
{
return new WpfDispatcherTimerProviderTimer(priority, dispatcher, callback, state, dueTime, period);
}
}

internal sealed class WpfDispatcherTimerProviderTimer : ITimer
{
DispatcherTimer? timer;
TimerCallback callback;
object? state;
EventHandler timerTick;
TimeSpan? period;

public WpfDispatcherTimerProviderTimer(DispatcherPriority? priority, Dispatcher? dispatcher, TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period)
{
this.timerTick = Timer_Tick;
this.callback = callback;
this.state = state;
if (priority == null && dispatcher == null)
{
this.timer = new DispatcherTimer();
}
if (dispatcher == null) // priority is not null
{
this.timer = new DispatcherTimer(priority!.Value);
}
else
{
this.timer = new DispatcherTimer(priority!.Value, dispatcher);
}

timer.Tick += timerTick;

if (dueTime != Timeout.InfiniteTimeSpan)
{
Change(dueTime, period);
}
}

public bool Change(TimeSpan dueTime, TimeSpan period)
{
if (timer != null)
{
timer.Stop();

this.period = period;
timer.Interval = dueTime;

timer.Start();
return true;
}
return false;
}

void Timer_Tick(object? sender, EventArgs e)
{
callback(state);

if (timer != null && period != null)
{
timer.Stop();

if (period.Value == Timeout.InfiniteTimeSpan)
{
period = null;
}
else
{
timer.Interval = period.Value;
period = null;
timer.Start();
}
}
}

public void Dispose()
{
if (timer != null)
{
timer.Stop();
timer.Tick -= timerTick;
timer = null;
}
}

public ValueTask DisposeAsync()
{
Dispose();
return default;
}
}
24 changes: 24 additions & 0 deletions src/R3.WPF/WpfProviderInitializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Windows.Threading;

namespace R3.WPF;

public static class WpfProviderInitializer
{
public static void SetDefaultProviders()
{
ObservableSystem.DefaultTimeProvider = new WpfDispatcherTimerProvider();
ObservableSystem.DefaultFrameProvider = new WpfRenderingFrameProvider();
}

public static void SetDefaultProviders(DispatcherPriority priority)
{
ObservableSystem.DefaultTimeProvider = new WpfDispatcherTimerProvider(priority);
ObservableSystem.DefaultFrameProvider = new WpfRenderingFrameProvider();
}

public static void SetDefaultProviders(DispatcherPriority priority, Dispatcher dispatcher)
{
ObservableSystem.DefaultTimeProvider = new WpfDispatcherTimerProvider(priority, dispatcher);
ObservableSystem.DefaultFrameProvider = new WpfRenderingFrameProvider();
}
}
Loading

0 comments on commit 75923d1

Please sign in to comment.