Browse Source

Merge branch 'master' into dockpanel-simplification

pull/209/head
Steven Kirk 11 years ago
parent
commit
6d89f78a98
  1. 9
      Perspex.sln
  2. 1
      nuget/build-version.ps1
  3. 2
      readme.md
  4. 4
      samples/TestApplication/App.config
  5. 3
      samples/TestApplication/TestApplication.csproj
  6. 15
      samples/TestApplication/packages.config
  7. 11
      samples/XamlTestApplication/XamlTestApplication.csproj
  8. 2
      samples/XamlTestApplication/packages.config
  9. 7
      src/Gtk/Perspex.Cairo/CairoPlatform.cs
  10. 1
      src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
  11. 24
      src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs
  12. 1
      src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs
  13. 3
      src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj
  14. 7
      src/Gtk/Perspex.Cairo/packages.config
  15. 20
      src/Gtk/Perspex.Gtk/GtkPlatform.cs
  16. 26
      src/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
  17. 4
      src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj
  18. 57
      src/Gtk/Perspex.Gtk/SystemDialogImpl.cs
  19. 6
      src/Gtk/Perspex.Gtk/WindowImpl.cs
  20. 7
      src/Gtk/Perspex.Gtk/packages.config
  21. 3
      src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs
  22. 2
      src/Markup/Perspex.Markup.Xaml/OmniXAML
  23. 5
      src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj
  24. 19
      src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs
  25. 1
      src/Markup/Perspex.Markup.Xaml/packages.config
  26. 19
      src/NGenerics/Constants.cs
  27. 80
      src/NGenerics/DataStructures/Comparers/ComparisonComparer.cs
  28. 93
      src/NGenerics/DataStructures/Comparers/KeyValuePairComparer.cs
  29. 84
      src/NGenerics/DataStructures/Comparers/ReverseComparer.cs
  30. 405
      src/NGenerics/DataStructures/General/Heap.cs
  31. 32
      src/NGenerics/DataStructures/General/HeapType.cs
  32. 44
      src/NGenerics/DataStructures/General/IHeap.cs
  33. 46
      src/NGenerics/DataStructures/Queues/IQueue.cs
  34. 556
      src/NGenerics/DataStructures/Queues/PriorityQueue.cs
  35. 30
      src/NGenerics/DataStructures/Queues/PriorityQueueType.cs
  36. 529
      src/NGenerics/DataStructures/Trees/BinarySearchTreeBase.cs
  37. 674
      src/NGenerics/DataStructures/Trees/BinaryTree.cs
  38. 68
      src/NGenerics/DataStructures/Trees/ISearchTree.cs
  39. 82
      src/NGenerics/DataStructures/Trees/ITree.cs
  40. 21
      src/NGenerics/DataStructures/Trees/NodeColor.cs
  41. 291
      src/NGenerics/DataStructures/Trees/RedBlackTree.cs
  42. 251
      src/NGenerics/DataStructures/Trees/RedBlackTreeDictionary.cs
  43. 232
      src/NGenerics/DataStructures/Trees/RedBlackTreeList.cs
  44. 107
      src/NGenerics/DataStructures/Trees/RedBlackTreeNode.cs
  45. 76
      src/NGenerics/NGenerics.csproj
  46. 34
      src/NGenerics/Patterns/Visitor/IVisitor.cs
  47. 51
      src/NGenerics/Patterns/Visitor/InOrderVisitor.cs
  48. 65
      src/NGenerics/Patterns/Visitor/KeyTrackingVisitor.cs
  49. 102
      src/NGenerics/Patterns/Visitor/OrderedVisitor.cs
  50. 65
      src/NGenerics/Patterns/Visitor/TrackingVisitor.cs
  51. 66
      src/NGenerics/Patterns/Visitor/ValueTrackingVisitor.cs
  52. 33
      src/NGenerics/Properties/AssemblyInfo.cs
  53. 59
      src/NGenerics/Util/Guard.cs
  54. 22
      src/Perspex.Application/Application.cs
  55. 3
      src/Perspex.Application/Perspex.Application.csproj
  56. 7
      src/Perspex.Application/Platform/IAssetLoader.cs
  57. 1
      src/Perspex.Application/packages.config
  58. 10
      src/Perspex.Base/Perspex.Base.csproj
  59. 120
      src/Perspex.Base/PerspexLocator.cs
  60. 5
      src/Perspex.Base/Threading/DispatcherTimer.cs
  61. 11
      src/Perspex.Base/Threading/MainLoop.cs
  62. 1
      src/Perspex.Base/packages.config
  63. 3
      src/Perspex.Controls/Control.cs
  64. 18
      src/Perspex.Controls/MenuItem.cs
  65. 16
      src/Perspex.Controls/Perspex.Controls.csproj
  66. 14
      src/Perspex.Controls/Platform/ISystemDialogImpl.cs
  67. 13
      src/Perspex.Controls/Presenters/TextPresenter.cs
  68. 3
      src/Perspex.Controls/Primitives/Popup.cs
  69. 5
      src/Perspex.Controls/Primitives/PopupRoot.cs
  70. 44
      src/Perspex.Controls/SystemDialog.cs
  71. 3
      src/Perspex.Controls/Templates/DataTemplateExtensions.cs
  72. 5
      src/Perspex.Controls/TextBox.cs
  73. 11
      src/Perspex.Controls/TopLevel.cs
  74. 3
      src/Perspex.Controls/Window.cs
  75. 1
      src/Perspex.Controls/packages.config
  76. 3
      src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs
  77. 3
      src/Perspex.HtmlRenderer/Perspex.HtmlRenderer.csproj
  78. 1
      src/Perspex.HtmlRenderer/packages.config
  79. 3
      src/Perspex.Input/Cursors.cs
  80. 3
      src/Perspex.Input/FocusManager.cs
  81. 3
      src/Perspex.Input/InputManager.cs
  82. 7
      src/Perspex.Input/KeyboardDevice.cs
  83. 9
      src/Perspex.Input/MouseDevice.cs
  84. 3
      src/Perspex.Input/Perspex.Input.csproj
  85. 1
      src/Perspex.Input/packages.config
  86. 3
      src/Perspex.Interactivity/Perspex.Interactivity.csproj
  87. 1
      src/Perspex.Interactivity/packages.config
  88. 16
      src/Perspex.Layout/LayoutManager.cs
  89. 7
      src/Perspex.Layout/Perspex.Layout.csproj
  90. 1
      src/Perspex.Layout/packages.config
  91. 3
      src/Perspex.SceneGraph/Media/EllipseGeometry.cs
  92. 3
      src/Perspex.SceneGraph/Media/FormattedText.cs
  93. 7
      src/Perspex.SceneGraph/Media/Imaging/Bitmap.cs
  94. 3
      src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs
  95. 3
      src/Perspex.SceneGraph/Media/RectangleGeometry.cs
  96. 3
      src/Perspex.SceneGraph/Media/StreamGeometry.cs
  97. 3
      src/Perspex.SceneGraph/Perspex.SceneGraph.csproj
  98. 1
      src/Perspex.SceneGraph/packages.config
  99. 3
      src/Perspex.Styling/Perspex.Styling.csproj
  100. 3
      src/Perspex.Styling/Styling/Styler.cs

9
Perspex.sln

@ -31,10 +31,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Application", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Diagnostics", "src\Perspex.Diagnostics\Perspex.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{2BAFBE53-7FA4-4BB9-976F-9AFCC4F9847D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NGenerics", "src\NGenerics\NGenerics.csproj", "{415E048E-4611-4815-9CF2-D774E29079AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Animation", "src\Perspex.Animation\Perspex.Animation.csproj", "{D211E587-D8BC-45B9-95A4-F297C8FA5200}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}"
@ -163,10 +159,6 @@ Global
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.Build.0 = Release|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.Build.0 = Release|Any CPU
{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -251,7 +243,6 @@ Global
{811A76CF-1CF6-440F-963B-BBE31BD72A82} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{EC42600F-049B-43FF-AED1-8314D61B2749} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{415E048E-4611-4815-9CF2-D774E29079AC} = {2BAFBE53-7FA4-4BB9-976F-9AFCC4F9847D}
{47ECDF59-DEF8-4C53-87B1-2098A3429059} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{5CCB5571-7C30-4E7D-967D-0E2158EBD91F} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{76716382-3159-460E-BDA6-C5715CF606D7} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}

1
nuget/build-version.ps1

@ -32,7 +32,6 @@ Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.dll
Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.xml $lib
Copy-Item ..\src\Perspex.HtmlRenderer\bin\Release\Perspex.HtmlRenderer.dll $lib
Copy-Item ..\src\Perspex.ReactiveUI\bin\Release\Perspex.ReactiveUI.dll $lib
Copy-Item ..\src\NGenerics\bin\Release\NGenerics.dll $lib
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\Perspex.Direct2D1.dll $build
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.dll $build

2
readme.md

@ -12,7 +12,7 @@ A multi-platform .NET UI framework.
## NuGet
Perspex is delivered as a NuGet package.
You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Perspex/), [nightly](https://www.myget.org/F/perspex-nightly/api/v2/Packages))
You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Perspex/), [nightly](https://github.com/Perspex/Perspex/wiki/Using-nightly-build-feed))
You can install the package like this:
`Install-Package Perspex -Pre`

4
samples/TestApplication/App.config

@ -21,6 +21,10 @@
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.3.0" newVersion="2.6.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

3
samples/TestApplication/TestApplication.csproj

@ -66,9 +66,6 @@
<Reference Include="Serilog.FullNetFx, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10">
<HintPath>..\..\packages\Serilog.1.5.9\lib\net45\Serilog.FullNetFx.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="App.cs" />

15
samples/TestApplication/packages.config

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Rx-Core" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-Main" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-XAML" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Serilog" version="1.5.9" targetFramework="net45" userInstalled="true" />
<package id="Splat" version="1.6.2" targetFramework="net45" userInstalled="true" />
<package id="Rx-Core" version="2.2.5" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net45" />
<package id="Rx-Main" version="2.2.5" targetFramework="net45" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net45" />
<package id="Rx-XAML" version="2.2.5" targetFramework="net45" />
<package id="Serilog" version="1.5.9" targetFramework="net45" />
</packages>

11
samples/XamlTestApplication/XamlTestApplication.csproj

@ -36,6 +36,10 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
@ -55,9 +59,6 @@
<Reference Include="Serilog.FullNetFx, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10">
<HintPath>..\..\packages\Serilog.1.5.9\lib\net45\Serilog.FullNetFx.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="Sprache, Version=2.0.0.47, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Sprache.2.0.0.47\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid1+MonoTouch1\Sprache.dll</HintPath>
</Reference>
@ -85,10 +86,6 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Perspex.Animation\Perspex.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Perspex.Animation</Name>

2
samples/XamlTestApplication/packages.config

@ -7,6 +7,6 @@
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net46" />
<package id="Rx-XAML" version="2.2.5" targetFramework="net46" />
<package id="Serilog" version="1.5.9" targetFramework="net46" />
<package id="Splat" version="1.6.2" targetFramework="net46" />
<package id="Splat" version="1.6.2" targetFramework="net45" />
<package id="Sprache" version="2.0.0.47" targetFramework="net451" />
</packages>

7
src/Gtk/Perspex.Cairo/CairoPlatform.cs

@ -6,7 +6,6 @@ using Perspex.Cairo.Media;
using Perspex.Cairo.Media.Imaging;
using Perspex.Media;
using Perspex.Platform;
using Splat;
namespace Perspex.Cairo
{
@ -19,11 +18,7 @@ namespace Perspex.Cairo
private static Pango.Context s_pangoContext = CreatePangoContext();
public static void Initialize()
{
var locator = Locator.CurrentMutable;
locator.Register(() => s_instance, typeof(IPlatformRenderInterface));
}
public static void Initialize() => PerspexLocator.CurrentMutable.Bind<IPlatformRenderInterface>().ToConstant(s_instance);
public IBitmapImpl CreateBitmap(int width, int height)
{

1
src/Gtk/Perspex.Cairo/Media/DrawingContext.cs

@ -287,6 +287,7 @@ namespace Perspex.Cairo.Media
_context.SetSource(impl.PlatformBrush);
return Disposable.Create(() =>
{
impl.Dispose();
_context.Restore();
});
}

24
src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs

@ -4,15 +4,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Perspex.Media;
using Perspex.Platform;
using Splat;
namespace Perspex.Cairo.Media
{
public class FormattedTextImpl : IFormattedTextImpl
{
private Size _size;
private string _text;
public FormattedTextImpl(
Pango.Context context,
@ -26,6 +27,7 @@ namespace Perspex.Cairo.Media
Contract.Requires<NullReferenceException>(context != null);
Layout = new Pango.Layout(context);
_text = text;
Layout.SetText(text);
Layout.FontDescription = new Pango.FontDescription
{
@ -49,7 +51,7 @@ namespace Perspex.Cairo.Media
set
{
_size = value;
Layout.Width = double.IsPositiveInfinity(value.Width) ?
Layout.Width = double.IsPositiveInfinity(value.Width) ?
-1 : Pango.Units.FromDouble(value.Width);
}
}
@ -80,6 +82,8 @@ namespace Perspex.Cairo.Media
out textPosition,
out trailing);
textPosition = PangoIndexToTextIndex(textPosition);
return new TextHitTestResult
{
IsInside = isInside,
@ -88,9 +92,19 @@ namespace Perspex.Cairo.Media
};
}
int PangoIndexToTextIndex(int pangoIndex)
{
return Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(_text), 0, Math.Min(pangoIndex, _text.Length)).Length;
}
public Rect HitTestTextPosition(int index)
{
return Layout.IndexToPos(index).ToPerspex();
return Layout.IndexToPos(TextIndexToPangoIndex(index)).ToPerspex();
}
int TextIndexToPangoIndex(int textIndex)
{
return Encoding.UTF8.GetByteCount(textIndex < _text.Length ? _text.Remove(textIndex) : _text);
}
public IEnumerable<Rect> HitTestTextRange(int index, int length)
@ -124,8 +138,8 @@ namespace Perspex.Cairo.Media
color.Parse(string.Format("#{0}", scb.Color.ToString().Substring(3)));
var brushAttr = new Pango.AttrForeground(color);
brushAttr.StartIndex = (uint)startIndex;
brushAttr.EndIndex = (uint)(startIndex + count);
brushAttr.StartIndex = (uint)TextIndexToPangoIndex(startIndex);
brushAttr.EndIndex = (uint)TextIndexToPangoIndex(startIndex + count);
Layout.Attributes.Insert(brushAttr);
}

1
src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs

@ -4,7 +4,6 @@
using System;
using Perspex.Media;
using Perspex.Platform;
using Splat;
using System.Collections.Generic;
namespace Perspex.Cairo.Media

3
src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj

@ -51,9 +51,6 @@
<HintPath>..\..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CairoPlatform.cs" />

7
src/Gtk/Perspex.Cairo/packages.config

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Rx-Core" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Splat" version="1.6.2" targetFramework="net45" userInstalled="true" />
</packages>
<package id="Rx-Core" version="2.2.5" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
</packages>

20
src/Gtk/Perspex.Gtk/GtkPlatform.cs

@ -3,11 +3,11 @@
using System;
using System.Reactive.Disposables;
using Perspex.Controls.Platform;
using Perspex.Input.Platform;
using Perspex.Input;
using Perspex.Platform;
using Perspex.Shared.PlatformSupport;
using Splat;
namespace Perspex.Gtk
{
@ -28,14 +28,16 @@ namespace Perspex.Gtk
public static void Initialize()
{
var locator = Locator.CurrentMutable;
locator.Register(() => new WindowImpl(), typeof(IWindowImpl));
locator.Register(() => new PopupImpl(), typeof(IPopupImpl));
locator.Register(() => new ClipboardImpl(), typeof(IClipboard));
locator.Register(() => CursorFactory.Instance, typeof(IStandardCursorFactory));
locator.Register(() => GtkKeyboardDevice.Instance, typeof(IKeyboardDevice));
locator.Register(() => s_instance, typeof(IPlatformSettings));
locator.Register(() => s_instance, typeof(IPlatformThreadingInterface));
PerspexLocator.CurrentMutable
.Bind<IWindowImpl>().ToTransient<WindowImpl>()
.Bind<IPopupImpl>().ToTransient<PopupImpl>()
.Bind<IClipboard>().ToSingleton<ClipboardImpl>()
.Bind<IStandardCursorFactory>().ToConstant(CursorFactory.Instance)
.Bind<IKeyboardDevice>().ToConstant(GtkKeyboardDevice.Instance)
.Bind<IMouseDevice>().ToConstant(GtkMouseDevice.Instance)
.Bind<IPlatformSettings>().ToConstant(s_instance)
.Bind<IPlatformThreadingInterface>().ToConstant(s_instance)
.Bind<ISystemDialogImpl>().ToSingleton<SystemDialogImpl>();
SharedPlatform.Register();
}

26
src/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs

@ -83,6 +83,32 @@ namespace Perspex.Gtk
{ Gdk.Key.X, Key.X },
{ Gdk.Key.Y, Key.Y },
{ Gdk.Key.Z, Key.Z },
{ Gdk.Key.a, Key.A },
{ Gdk.Key.b, Key.B },
{ Gdk.Key.c, Key.C },
{ Gdk.Key.d, Key.D },
{ Gdk.Key.e, Key.E },
{ Gdk.Key.f, Key.F },
{ Gdk.Key.g, Key.G },
{ Gdk.Key.h, Key.H },
{ Gdk.Key.i, Key.I },
{ Gdk.Key.j, Key.J },
{ Gdk.Key.k, Key.K },
{ Gdk.Key.l, Key.L },
{ Gdk.Key.m, Key.M },
{ Gdk.Key.n, Key.N },
{ Gdk.Key.o, Key.O },
{ Gdk.Key.p, Key.P },
{ Gdk.Key.q, Key.Q },
{ Gdk.Key.r, Key.R },
{ Gdk.Key.s, Key.S },
{ Gdk.Key.t, Key.T },
{ Gdk.Key.u, Key.U },
{ Gdk.Key.v, Key.V },
{ Gdk.Key.w, Key.W },
{ Gdk.Key.x, Key.X },
{ Gdk.Key.y, Key.Y },
{ Gdk.Key.z, Key.Z },
//{ Gdk.Key.?, Key.LWin }
//{ Gdk.Key.?, Key.RWin }
//{ Gdk.Key.?, Key.Apps }

4
src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj

@ -44,12 +44,10 @@
<HintPath>..\..\..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference>
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ClipboardImpl.cs" />
<Compile Include="SystemDialogImpl.cs" />
<Compile Include="CursorFactory.cs" />
<Compile Include="GtkExtensions.cs" />
<Compile Include="PopupImpl.cs" />

57
src/Gtk/Perspex.Gtk/SystemDialogImpl.cs

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Controls;
using Perspex.Controls.Platform;
using Perspex.Platform;
namespace Perspex.Gtk
{
using global::Gtk;
class SystemDialogImpl : ISystemDialogImpl
{
public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent)
{
var tcs = new TaskCompletionSource<string[]>();
var dlg = new global::Gtk.FileChooserDialog(dialog.Title, ((WindowImpl) parent),
dialog is OpenFileDialog
? FileChooserAction.Open
: FileChooserAction.Save,
"Cancel", ResponseType.Cancel,
"Open", ResponseType.Accept)
{
SelectMultiple = (dialog as OpenFileDialog)?.AllowMultiple ?? false,
};
foreach (var filter in dialog.Filters)
{
var ffilter = new FileFilter()
{
Name = filter.Name + " (" + string.Join(";", filter.Extensions.Select(e => "*." + e)) + ")"
};
foreach (var ext in filter.Extensions)
ffilter.AddPattern("*." + ext);
dlg.AddFilter(ffilter);
}
dlg.SetFilename(dialog.InitialFileName);
dlg.Modal = true;
dlg.Response += (_, args) =>
{
if (args.ResponseId == ResponseType.Accept)
tcs.TrySetResult(dlg.Filenames);
dlg.Hide();
dlg.Dispose();
};
dlg.Close += delegate
{
tcs.TrySetResult(null);
dlg.Dispose();
};
dlg.Show();
return tcs.Task;
}
}
}

6
src/Gtk/Perspex.Gtk/WindowImpl.cs

@ -51,6 +51,12 @@ namespace Perspex.Gtk
_imContext.Commit += ImContext_Commit;
}
protected override void OnRealized ()
{
base.OnRealized ();
_imContext.ClientWindow = this.GdkWindow;
}
public Size ClientSize
{
get;

7
src/Gtk/Perspex.Gtk/packages.config

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Rx-Core" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net45" userInstalled="true" />
<package id="Splat" version="1.6.2" targetFramework="net45" userInstalled="true" />
<package id="Rx-Core" version="2.2.5" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net45" />
</packages>

3
src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs

@ -20,7 +20,6 @@ using Perspex.Media.Imaging;
using Perspex.Metadata;
using Perspex.Platform;
using Perspex.Styling;
using Splat;
namespace Perspex.Markup.Xaml.Context
{
@ -52,7 +51,7 @@ namespace Perspex.Markup.Xaml.Context
foreach (var nsa in
forcedAssemblies
.Concat(Locator.Current.GetService<IPclPlatformWrapper>().GetLoadedAssemblies())
.Concat(PerspexLocator.Current.GetService<IPclPlatformWrapper>().GetLoadedAssemblies())
.Distinct()
.SelectMany(asm
=> asm.GetCustomAttributes<XmlnsDefinitionAttribute>().Select(attr => new {asm, attr}))

2
src/Markup/Perspex.Markup.Xaml/OmniXAML

@ -1 +1 @@
Subproject commit 586e2e521c85a4b111c394e8aee178bbdfc9c1df
Subproject commit 1461be589a5d39d378fd177648c61a780271c742

5
src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj

@ -194,6 +194,7 @@
<Compile Include="OmniXAML\Source\OmniXaml\Typing\IXamlNamespaceRegistry.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\IXamlTypeRepository.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\MemberValuePlugin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\Metadata.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\MutableXamlMember.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\Namespace.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\PrefixRegistration.cs" />
@ -207,6 +208,7 @@
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlType.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlTypeName.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlTypeRepository.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Typing\XamlTypeRepositoryMixin.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\ValueConversionException.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Visualization\IVisitor.cs" />
<Compile Include="OmniXAML\Source\OmniXaml\Visualization\NodeType.cs" />
@ -289,9 +291,6 @@
<Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10">
<HintPath>..\..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
<Reference Include="Sprache, Version=2.0.0.47, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\packages\Sprache.2.0.0.47\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid1+MonoTouch1\Sprache.dll</HintPath>
</Reference>

19
src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs

@ -8,7 +8,6 @@ using System.Reflection;
using OmniXaml;
using Perspex.Markup.Xaml.Context;
using Perspex.Platform;
using Splat;
namespace Perspex.Markup.Xaml
{
@ -57,7 +56,7 @@ namespace Perspex.Markup.Xaml
// HACK: Currently Visual Studio is forcing us to change the extension of xaml files
// in certain situations, so we try to load .xaml and if that's not found we try .paml.
// Ideally we'd be able to use .xaml everywhere
var assetLocator = Locator.Current.GetService<IAssetLoader>();
var assetLocator = PerspexLocator.Current.GetService<IAssetLoader>();
if (assetLocator == null)
{
throw new InvalidOperationException(
@ -65,17 +64,13 @@ namespace Perspex.Markup.Xaml
}
foreach (var uri in GetUrisFor(type))
{
Stream stream;
try
if (assetLocator.Exists(uri))
{
stream= assetLocator.Open(uri);
using (var stream = assetLocator.Open(uri))
{
return Load(stream, rootInstance);
}
}
catch (FileNotFoundException)
{
continue;
}
using (stream)
return Load(stream, rootInstance);
}
throw new FileNotFoundException("Unable to find view for " + type.FullName);
}
@ -90,7 +85,7 @@ namespace Perspex.Markup.Xaml
/// <returns>The loaded object.</returns>
public object Load(Uri uri, object rootInstance = null)
{
var assetLocator = Locator.Current.GetService<IAssetLoader>();
var assetLocator = PerspexLocator.Current.GetService<IAssetLoader>();
if (assetLocator == null)
{

1
src/Markup/Perspex.Markup.Xaml/packages.config

@ -6,6 +6,5 @@
<package id="Rx-Main" version="2.2.5" targetFramework="portable46-net451+win81" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable46-net451+win81" />
<package id="Serilog" version="1.5.9" targetFramework="portable46-net451+win81" />
<package id="Splat" version="1.6.2" targetFramework="portable46-net451+win81" />
<package id="Sprache" version="2.0.0.47" targetFramework="portable45-net45+win8" />
</packages>

19
src/NGenerics/Constants.cs

@ -1,19 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics
{
internal static class Constants
{
public const string NotEnoughSpaceInTheTargetArray = "Not enough space in the target array.";
}
}

80
src/NGenerics/DataStructures/Comparers/ComparisonComparer.cs

@ -1,80 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using NGenerics.Util;
namespace NGenerics.Comparers
{
/// <summary>
/// A Comparer using a Comparison delegate for comparisons between items.
/// </summary>
/// <typeparam name="T">The type of the objects to compare.</typeparam>
//[Serializable]
public sealed class ComparisonComparer<T> : IComparer<T>
{
#region Globals
private Comparison<T> _comparison;
#endregion
#region Construction
/// <param name="comparison">The comparison.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparison"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public ComparisonComparer(Comparison<T> comparison)
{
Guard.ArgumentNotNull(comparison, "comparison");
_comparison = comparison;
}
#endregion
#region Public Members
/// <summary>
/// Gets or sets the comparison used in this comparer.
/// </summary>
/// <value>The comparison used in this comparer.</value>
/// <exception cref="ArgumentNullException"><paramref name="value"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public Comparison<T> Comparison
{
get
{
return _comparison;
}
set
{
Guard.ArgumentNotNull(value, "value");
_comparison = value;
}
}
#endregion
#region IComparer<T> Members
/// <inheritdoc />
public int Compare(T x, T y)
{
return _comparison(x, y);
}
#endregion
}
}

93
src/NGenerics/DataStructures/Comparers/KeyValuePairComparer.cs

@ -1,93 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
namespace NGenerics.Comparers
{
/// <summary>
/// A comparer for comparing keys for the KeyValuePair class.
/// </summary>
/// <typeparam name="TKey">The key type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
//[Serializable]
public class KeyValuePairComparer<TKey, TValue> : IComparer<KeyValuePair<TKey, TValue>>
{
#region Globals
private readonly IComparer<TKey> _comparer;
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="KeyValuePairComparer&lt;TKey, TValue&gt;"/> class.
/// </summary>
public KeyValuePairComparer()
{
_comparer = Comparer<TKey>.Default;
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyValuePairComparer&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <param name="comparer">The comparer.</param>
public KeyValuePairComparer(IComparer<TKey> comparer)
{
if (comparer == null)
{
throw new ArgumentNullException("comparer");
}
_comparer = comparer;
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyValuePairComparer&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <param name="comparison">The comparison.</param>
public KeyValuePairComparer(Comparison<TKey> comparison)
{
if (comparison == null)
{
throw new ArgumentNullException("comparison");
}
_comparer = new ComparisonComparer<TKey>(comparison);
}
#endregion
#region IComparer<KeyValuePairComparer<TKey,TValue>> Members
/// <inheritdoc />
public int Compare(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
{
return _comparer.Compare(x.Key, y.Key);
}
#endregion
#region IComparer<TKey> Members
/// <inheritdoc />
public int Compare(TKey x, TKey y)
{
return _comparer.Compare(x, y);
}
#endregion
}
}

84
src/NGenerics/DataStructures/Comparers/ReverseComparer.cs

@ -1,84 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using NGenerics.Util;
namespace NGenerics.Comparers
{
/// <summary>
/// A comparer that wraps the IComparable interface to reproduce the opposite comparison result.
/// </summary>
/// <typeparam name="T">The type of the objects to compare.</typeparam>
//[Serializable]
public sealed class ReverseComparer<T> : IComparer<T>
{
#region Globals
private IComparer<T> _comparerToUse;
#endregion
#region Construction
/// <inheritdoc />
public ReverseComparer()
{
_comparerToUse = Comparer<T>.Default;
}
/// <param name="comparer">The comparer to reverse.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public ReverseComparer(IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
_comparerToUse = comparer;
}
#endregion
#region IComparer<T> Members
/// <inheritdoc />
public int Compare(T x, T y)
{
return (_comparerToUse.Compare(y, x));
}
#endregion
#region Public Members
/// <summary>
/// Gets or sets the comparer used in this instance.
/// </summary>
/// <value>The comparer.</value>
/// <exception cref="ArgumentNullException"><paramref name="value"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public IComparer<T> Comparer
{
get
{
return _comparerToUse;
}
set
{
Guard.ArgumentNotNull(value, "value");
_comparerToUse = value;
}
}
#endregion
}
}

405
src/NGenerics/DataStructures/General/Heap.cs

@ -1,405 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using NGenerics.Comparers;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Util;
namespace NGenerics.DataStructures.General
{
/// <summary>
/// An implementation of a Heap data structure.
/// </summary>
/// <typeparam name="T">The type of item stored in the <see cref="Heap{T}"/>.</typeparam>
//[Serializable]
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
public class Heap<T> : ICollection<T>, IHeap<T>
{
#region Globals
private const string heapIsEmpty = "The heap is empty.";
private readonly List<T> _data;
private readonly IComparer<T> _comparerToUse;
private readonly HeapType _thisType;
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of Heap to create.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Constructor" lang="cs" title="The following example shows how to use the default constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Constructor" lang="vbnet" title="The following example shows how to use the default constructor."/>
/// </example>
public Heap(HeapType type) : this(type, Comparer<T>.Default) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of heap.</param>
/// <param name="capacity">The capacity.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>
/// .
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="ConstructorCapacity" lang="cs" title="The following example shows how to use the capacity constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="ConstructorCapacity" lang="vbnet" title="The following example shows how to use the capacity constructor."/>
/// </example>
public Heap(HeapType type, int capacity) : this(type, capacity, Comparer<T>.Default) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of heap.</param>
/// <param name="comparer">The comparer.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
public Heap(HeapType type, Comparison<T> comparer) : this(type, new ComparisonComparer<T>(comparer)) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of heap.</param>
/// <param name="capacity">The capacity of the heap to start with.</param>
/// <param name="comparer">The comparer.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>
public Heap(HeapType type, int capacity, Comparison<T> comparer) : this(type, capacity, new ComparisonComparer<T>(comparer)) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of Heap to create.</param>
/// <param name="comparer">The comparer to use.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="ConstructorComparer" lang="cs" title="The following example shows how to use the comparer constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="ConstructorComparer" lang="vbnet" title="The following example shows how to use the comparer constructor."/>
/// </example>
public Heap(HeapType type, IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
if ((type != HeapType.Minimum) && (type != HeapType.Maximum))
{
throw new ArgumentOutOfRangeException("type");
}
_thisType = type;
_data = new List<T> { default(T) };
_comparerToUse = type == HeapType.Minimum ? comparer : new ReverseComparer<T>(comparer);
}
/// <param name="type">The type of heap.</param>
/// <param name="capacity">The initial capacity of the Heap.</param>
/// <param name="comparer">The comparer to use.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>.
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
public Heap(HeapType type, int capacity, IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
if ((type != HeapType.Minimum) && (type != HeapType.Maximum))
{
throw new ArgumentOutOfRangeException("type");
}
_thisType = type;
_data = new List<T>(capacity) { default(T) };
_comparerToUse = type == HeapType.Minimum ? comparer : new ReverseComparer<T>(comparer);
}
#endregion
#region Public Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Root" lang="cs" title="The following example shows how to use the Root property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Root" lang="vbnet" title="The following example shows how to use the Root property."/>
/// </example>
public T Root
{
get
{
#region Validation
if (Count == 0)
{
throw new InvalidOperationException(heapIsEmpty);
}
#endregion
return _data[1];
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="RemoveRoot" lang="cs" title="The following example shows how to use the RemoveRoot method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="RemoveRoot" lang="vbnet" title="The following example shows how to use the RemoveRoot method."/>
/// </example>
public T RemoveRoot()
{
#region Validation
if (Count == 0)
{
throw new InvalidOperationException(heapIsEmpty);
}
#endregion
// The minimum item to return.
var minimum = _data[1];
RemoveRootItem(minimum);
return minimum;
}
/// <summary>
/// Removes the root item.
/// </summary>
/// <param name="item">The item.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="RemoveRoot"/> method.
/// </remarks>
protected virtual void RemoveRootItem(T item)
{
// The last item in the heap
var last = _data[Count];
_data.RemoveAt(Count);
// If there's still items left in this heap, re-heapify it.
if (Count > 0)
{
// Re-heapify the binary tree to conform to the heap property
var counter = 1;
while ((counter * 2) < (_data.Count))
{
var child = counter * 2;
if (((child + 1) < (_data.Count)) &&
(_comparerToUse.Compare(_data[child + 1], _data[child]) < 0))
{
child++;
}
if (_comparerToUse.Compare(last, _data[child]) <= 0)
{
break;
}
_data[counter] = _data[child];
counter = child;
}
_data[counter] = last;
}
}
/// <summary>
/// Gets the type of heap represented by this instance.
/// </summary>
/// <value>The type of heap.</value>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Type" lang="cs" title="The following example shows how to use the Type property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Type" lang="vbnet" title="The following example shows how to use the Type property."/>
/// </example>
[SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
public HeapType Type => _thisType;
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="IsEmpty" lang="cs" title="The following example shows how to use the IsEmpty property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="IsEmpty" lang="vbnet" title="The following example shows how to use the IsEmpty property."/>
/// </example>
public bool IsEmpty => Count == 0;
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public bool Contains(T item)
{
return _data.Contains(item);
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="CopyTo" lang="cs" title="The following example shows how to use the CopyTo method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="CopyTo" lang="vbnet" title="The following example shows how to use the CopyTo method."/>
/// </example>
public void CopyTo(T[] array, int arrayIndex)
{
#region Validation
Guard.ArgumentNotNull(array, "array");
if ((array.Length - arrayIndex) < Count)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
for (var i = 1; i < _data.Count; i++)
{
array[arrayIndex++] = _data[i];
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Count" lang="cs" title="The following example shows how to use the Count property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Count" lang="vbnet" title="The following example shows how to use the Count property."/>
/// </example>
public int Count => _data.Count - 1;
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Add" lang="cs" title="The following example shows how to use the Add method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Add" lang="vbnet" title="The following example shows how to use the Add method."/>
/// </example>
public void Add(T item)
{
AddItem(item);
}
/// <summary>
/// Adds the item.
/// </summary>
/// <param name="item">The item to add.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Add"/> method.
/// </remarks>
protected virtual void AddItem(T item)
{
// Add a dummy to the end of the list (it will be replaced)
_data.Add(default(T));
var counter = _data.Count - 1;
while ((counter > 1) && (_comparerToUse.Compare(_data[counter / 2], item) > 0))
{
_data[counter] = _data[counter / 2];
counter = counter / 2;
}
_data[counter] = item;
}
/// <inheritdoc />
/// <exception cref="NotSupportedException">Always.</exception>
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="GetEnumerator" lang="cs" title="The following example shows how to use the GetEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="GetEnumerator" lang="vbnet" title="The following example shows how to use the GetEnumerator method."/>
/// </example>
public IEnumerator<T> GetEnumerator()
{
for (var i = 1; i < _data.Count; i++)
{
yield return _data[i];
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Clear" lang="cs" title="The following example shows how to use the Clear method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Clear" lang="vbnet" title="The following example shows how to use the Clear method."/>
/// </example>
public void Clear()
{
ClearItems();
}
/// <summary>
/// Clears all the objects in this instance.
/// </summary>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void ClearItems()
{
_data.RemoveRange(1, _data.Count - 1); // Clears all objects in this instance except the first dummy one.
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="IsReadOnly" lang="cs" title="The following example shows how to use the IsReadOnly property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="IsReadOnly" lang="vbnet" title="The following example shows how to use the IsReadOnly property."/>
/// </example>
public bool IsReadOnly => false;
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}

32
src/NGenerics/DataStructures/General/HeapType.cs

@ -1,32 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.DataStructures.General
{
/// <summary>
/// The type of <see cref="Heap{T}"/> to implemented.
/// </summary>
public enum HeapType
{
/// <summary>
/// Makes the heap a Minimum-Heap - the smallest item is kept in the root of the <see cref="Heap{T}"/>.
/// </summary>
Minimum,
/// <summary>
/// Makes the heap a Maximum-Heap - the largest item is kept in the root of the <see cref="Heap{T}"/>.
/// </summary>
Maximum
}
}

44
src/NGenerics/DataStructures/General/IHeap.cs

@ -1,44 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
namespace NGenerics.DataStructures.General
{
/// <summary>
/// An interface for the <see cref="Heap{T}"/> data structure.
/// </summary>
/// <typeparam name="T">The type of elements in the heap.</typeparam>
public interface IHeap<T>
{
/// <summary>
/// Adds the specified item.
/// </summary>
/// <param name="item">The item.</param>
void Add(T item);
/// <summary>
/// Removes the root and returns it.
/// </summary>
/// <returns>The root of the <see cref="Heap{T}"/>.</returns>
/// <exception cref="InvalidOperationException">The <see cref="Graph{T}"/> is empty.</exception>
T RemoveRoot();
/// <summary>
/// Gets the root.
/// </summary>
/// <value>The root.</value>
/// <exception cref="InvalidOperationException">The <see cref="Heap{T}"/> is empty.</exception>
T Root { get; }
}
}

46
src/NGenerics/DataStructures/Queues/IQueue.cs

@ -1,46 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Queues
{
/// <summary>
/// A queue interface.
/// </summary>
/// <typeparam name="T">The type of the elements in the queue.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
public interface IQueue<T>
{
/// <summary>
/// Enqueues the item at the back of the queue.
/// </summary>
/// <param name="item">The item.</param>
void Enqueue(T item);
/// <summary>
/// Dequeues the item at the front of the queue.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <exception cref="InvalidOperationException">The <see cref="Deque{T}"/> is empty.</exception>
T Dequeue();
/// <summary>
/// Peeks at the item in the front of the queue, without removing it.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <exception cref="InvalidOperationException">The <see cref="Deque{T}"/> is empty.</exception>
T Peek();
}
}

556
src/NGenerics/DataStructures/Queues/PriorityQueue.cs

@ -1,556 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
Community contributions :
- TKey Peek(out TPriority) contributed by Karl Shulze (http://www.karlschulze.com/).</remarks>
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Comparers;
using NGenerics.DataStructures.Trees;
using NGenerics.Util;
namespace NGenerics.DataStructures.Queues
{
/// <summary>
/// An implementation of a Priority Queue (can be <see cref="PriorityQueueType.Minimum"/> or <see cref="PriorityQueueType.Maximum"/>).
/// </summary>
/// <typeparam name="TPriority">The type of the priority in the <see cref="PriorityQueue{TPriority, TValue}"/>.</typeparam>
/// <typeparam name="TValue">The type of the elements in the <see cref="PriorityQueue{TPriority, TValue}"/>.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
//[Serializable]
public class PriorityQueue<TValue, TPriority> : ICollection<TValue>, IQueue<TValue>
{
#region Globals
private readonly RedBlackTreeList<TPriority, TValue> _tree;
private TPriority _defaultPriority;
private readonly PriorityQueueType _queueType;
#endregion
#region Construction
/// <param name="queueType">Type of the queue.</param>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Constructor" lang="cs" title="The following example shows how to use the default constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Constructor" lang="vbnet" title="The following example shows how to use the default constructor."/>
/// </example>
public PriorityQueue(PriorityQueueType queueType) :
this(queueType, Comparer<TPriority>.Default)
{
}
/// <inheritdoc/>
public PriorityQueue(PriorityQueueType queueType, IComparer<TPriority> comparer)
{
if ((queueType != PriorityQueueType.Minimum) && (queueType != PriorityQueueType.Maximum))
{
throw new ArgumentOutOfRangeException("queueType");
}
_queueType = queueType;
_tree = new RedBlackTreeList<TPriority, TValue>(comparer);
}
/// <summary>
/// Initializes a new instance of the <see cref="PriorityQueue&lt;TValue, TPriority&gt;"/> class.
/// </summary>
/// <param name="queueType">Type of the queue.</param>
/// <param name="comparison">The comparison.</param>
/// <inheritdoc/>
public PriorityQueue(PriorityQueueType queueType, Comparison<TPriority> comparison) :
this(queueType, new ComparisonComparer<TPriority>(comparison))
{
}
#endregion
#region IQueue<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Enqueue" lang="cs" title="The following example shows how to use the Enqueue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Enqueue" lang="vbnet" title="The following example shows how to use the Enqueue method."/>
/// </example>
public void Enqueue(TValue item)
{
Add(item);
}
/// <summary>
/// Enqueues the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="priority">The priority.</param>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="EnqueuePriority" lang="cs" title="The following example shows how to use the Enqueue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="EnqueuePriority" lang="vbnet" title="The following example shows how to use the Enqueue method."/>
/// </example>
public void Enqueue(TValue item, TPriority priority)
{
Add(item, priority);
}
/// <summary>
/// Dequeues the item at the front of the queue.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Dequeue" lang="cs" title="The following example shows how to use the Dequeue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Dequeue" lang="vbnet" title="The following example shows how to use the Dequeue method."/>
/// </example>
public TValue Dequeue()
{
TPriority priority;
return Dequeue(out priority);
}
/// <summary>
/// Peeks at the item in the front of the queue, without removing it.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Peek" lang="cs" title="The following example shows how to use the Peek method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Peek" lang="vbnet" title="The following example shows how to use the Peek method."/>
/// </example>
public TValue Peek()
{
var association = GetNextItem();
// Always dequeue in FIFO manner
return association.Value.First.Value;
}
/// <summary>
/// Peeks at the item in the front of the queue, without removing it.
/// </summary>
/// <param name="priority">The priority of the item.</param>
/// <returns>The item at the front of the queue.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="PeekPriority" lang="cs" title="The following example shows how to use the Peek method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="PeekPriority" lang="vbnet" title="The following example shows how to use the Peek method."/>
/// </example>
public TValue Peek(out TPriority priority)
{
var association = GetNextItem();
var item = association.Value.First.Value;
priority = association.Key;
return item;
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="IsReadOnly" lang="cs" title="The following example shows how to use the IsReadOnly property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="IsReadOnly" lang="vbnet" title="The following example shows how to use the IsReadOnly property."/>
/// </example>
public bool IsReadOnly => false;
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="GetEnumerator" lang="cs" title="The following example shows how to use the GetEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="GetEnumerator" lang="vbnet" title="The following example shows how to use the GetEnumerator method."/>
/// </example>
public IEnumerator<TValue> GetEnumerator()
{
return _tree.GetValueEnumerator();
}
#endregion
#region Public Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Count" lang="cs" title="The following example shows how to use the Count property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Count" lang="vbnet" title="The following example shows how to use the Count property."/>
/// </example>
public int Count { get; private set; }
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public bool Contains(TValue item)
{
return _tree.ContainsValue(item);
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="CopyTo" lang="cs" title="The following example shows how to use the CopyTo method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="CopyTo" lang="vbnet" title="The following example shows how to use the CopyTo method."/>
/// </example>
public void CopyTo(TValue[] array, int arrayIndex)
{
#region Validation
Guard.ArgumentNotNull(array, "array");
if ((array.Length - arrayIndex) < Count)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
foreach (var association in _tree)
{
var items = association.Value;
foreach (var item in items)
{
array.SetValue(item, arrayIndex++);
}
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Add" lang="cs" title="The following example shows how to use the Add method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Add" lang="vbnet" title="The following example shows how to use the Add method."/>
/// </example>
public void Add(TValue item)
{
Add(item, _defaultPriority);
}
/// <summary>
/// Adds an item to the <see cref="ICollection{T}"/>.
/// </summary>
/// <param name="item">The object to add to the <see cref="ICollection{T}"/>.</param>
/// <param name="priority">The priority of the item.</param>
/// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only.</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="AddPriority" lang="cs" title="The following example shows how to use the Add method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="AddPriority" lang="vbnet" title="The following example shows how to use the Add method."/>
/// </example>
public void Add(TValue item, TPriority priority)
{
AddItem(item, priority);
}
/// <inheritdoc />
public bool Remove(TValue item)
{
TPriority priority;
return Remove(item, out priority);
}
/// <summary>
/// Returns an enumerator that iterates through the keys in the collection.
/// </summary>
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the keys in the collection.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="GetKeyEnumerator" lang="cs" title="The following example shows how to use the GetKeyEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="GetKeyEnumerator" lang="vbnet" title="The following example shows how to use the GetKeyEnumerator method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IEnumerator<KeyValuePair<TPriority, TValue>> GetKeyEnumerator()
{
return _tree.GetKeyEnumerator();
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Clear" lang="cs" title="The following example shows how to use the Clear method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Clear" lang="vbnet" title="The following example shows how to use the Clear method."/>
/// </example>
public void Clear()
{
ClearItems();
}
/// <summary>
/// Dequeues the item from the head of the queue.
/// </summary>
/// <param name="priority">The priority of the item to dequeue.</param>
/// <returns>The item at the head of the queue.</returns>
/// <exception cref="InvalidOperationException">The <see cref="PriorityQueue{TValue, TPriority}"/> is empty.</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="DequeueWithPriority" lang="cs" title="The following example shows how to use the Dequeue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="DequeueWithPriority" lang="vbnet" title="The following example shows how to use the Dequeue method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
public TValue Dequeue(out TPriority priority)
{
return DequeueItem(out priority);
}
/// <summary>
/// Dequeues the item at the front of the queue.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Dequeue()"/> or <see cref="Dequeue(out TPriority)"/> methods.
/// </remarks>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
protected virtual TValue DequeueItem(out TPriority priority)
{
var association = GetNextItem();
var item = association.Value.First.Value;
association.Value.RemoveFirst();
var key = association.Key;
if (association.Value.Count == 0)
{
_tree.Remove(association.Key);
}
Count--;
priority = key;
return item;
}
/// <summary>
/// Gets or sets the default priority.
/// </summary>
/// <value>The default priority.</value>
public TPriority DefaultPriority
{
get
{
return _defaultPriority;
}
set
{
_defaultPriority = value;
}
}
/// <summary>
/// Removes the first occurrence of the specified item from the property queue.
/// </summary>
/// <param name="item">The item to remove.</param>
/// <param name="priority">The priority associated with the item.</param>
/// <returns><c>true</c> if the item exists in the <see cref="PriorityQueue{TValue, TPriority}"/> and has been removed; otherwise <c>false</c>.</returns>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")]
public bool Remove(TValue item, out TPriority priority)
{
return RemoveItem(item, out priority);
}
/// <summary>
/// Removes the item.
/// </summary>
/// <param name="item">The item to remove</param>
/// <param name="priority">The priority of the item that was removed.</param>
/// <returns>An indication of whether the item was found, and removed.</returns>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Remove(TValue,out TPriority)"/> method.
/// </remarks>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")]
protected virtual bool RemoveItem(TValue item, out TPriority priority)
{
var removed = _tree.Remove(item, out priority);
if (removed)
{
Count--;
}
return removed;
}
/// <summary>
/// Removes the items with the specified priority.
/// </summary>
/// <param name="priority">The priority.</param>
/// <returns><c>true</c> if the priority exists in the <see cref="PriorityQueue{TValue, TPriority}"/> and has been removed; otherwise <c>false</c>.</returns>
public bool RemovePriorityGroup(TPriority priority)
{
return RemoveItems(priority);
}
/// <summary>
/// Removes the items from the collection with the specified priority.
/// </summary>
/// <param name="priority">The priority to search for.</param>
/// <returns>An indication of whether items were found having the specified priority.</returns>
protected virtual bool RemoveItems(TPriority priority)
{
LinkedList<TValue> items;
if (_tree.TryGetValue(priority, out items))
{
_tree.Remove(priority);
Count -= items.Count;
return true;
}
return false;
}
/// <summary>
/// Removes the items with the specified priority.
/// </summary>
/// <param name="priority">The priority.</param>
/// <returns>The items with the specified priority.</returns>
public IList<TValue> GetPriorityGroup(TPriority priority)
{
LinkedList<TValue> items;
return _tree.TryGetValue(priority, out items) ? new List<TValue>(items) : new List<TValue>();
}
/// <summary>
/// Adds the specified items to the priority queue with the specified priority.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="priority">The priority.</param>
/// <exception cref="ArgumentNullException"><paramref name="items"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public void AddPriorityGroup(IList<TValue> items, TPriority priority)
{
#region Validation
Guard.ArgumentNotNull(items, "items");
#endregion
AddPriorityGroupItem(items, priority);
}
/// <summary>
/// Adds the specified items to the priority queue with the specified priority.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="priority">The priority.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="AddPriorityGroup"/> method.
/// </remarks>
protected virtual void AddPriorityGroupItem(IList<TValue> items, TPriority priority)
{
LinkedList<TValue> currentValues;
if (_tree.TryGetValue(priority, out currentValues))
{
for (var i = 0; i < items.Count; i++)
{
currentValues.AddLast(items[i]);
}
}
else
{
currentValues = new LinkedList<TValue>(items);
_tree.Add(priority, currentValues);
}
}
#endregion
#region Protected Members
/// <summary>
/// Adds the item to the queue.
/// </summary>
/// <param name="item">The item to add.</param>
/// <param name="priority">The priority of the item.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Add(TValue,TPriority)"/> method.
/// </remarks>
protected virtual void AddItem(TValue item, TPriority priority)
{
LinkedList<TValue> list;
if (_tree.TryGetValue(priority, out list))
{
list.AddLast(item);
}
else
{
list = new LinkedList<TValue>();
list.AddLast(item);
_tree.Add(priority, list);
}
Count++;
}
/// <summary>
/// Clears all the objects in this instance.
/// </summary>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void ClearItems()
{
_tree.Clear();
Count = 0;
}
#endregion
#region Private Members
/// <summary>
/// Checks if the list is not empty, and if it is, throw an exception.
/// </summary>
private void CheckTreeNotEmpty()
{
if (_tree.Count == 0)
{
throw new InvalidOperationException("The Priority Queue is empty.");
}
}
/// <summary>
/// Gets the next item.
/// </summary>
private KeyValuePair<TPriority, LinkedList<TValue>> GetNextItem()
{
#region Validation
CheckTreeNotEmpty();
#endregion
return _queueType == PriorityQueueType.Maximum ? _tree.Maximum : _tree.Minimum;
}
#endregion
}
}

30
src/NGenerics/DataStructures/Queues/PriorityQueueType.cs

@ -1,30 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.DataStructures.Queues
{
/// <summary>
/// Specifies the Priority Queue type (min or max).
/// </summary>
public enum PriorityQueueType
{
/// <summary>
/// Specify a Minimum <see cref="PriorityQueue{TValue, TPriority}"/>.
/// </summary>
Minimum = 0,
/// <summary>
/// Specify a Maximum <see cref="PriorityQueue{TValue, TPriority}"/>.
/// </summary>
Maximum = 1
}
}

529
src/NGenerics/DataStructures/Trees/BinarySearchTreeBase.cs

@ -1,529 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Comparers;
using NGenerics.Patterns.Visitor;
using NGenerics.Util;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// A base class for Binary Search Trees that store a single value in each node.
/// </summary>
/// <typeparam name="T"></typeparam>
//[Serializable]
public abstract class BinarySearchTreeBase<T> : ISearchTree<T>
{
#region Globals
internal const string alreadyContainedInTheTree = "The item is already contained in the tree.";
private BinaryTree<T> _tree;
private readonly IComparer<T> _comparer;
#endregion
#region Delegates
/// <summary>
/// A custom comparison between some search value and the type of item that is kept in the tree.
/// </summary>
/// <typeparam name="TSearch">The type of the search.</typeparam>
protected delegate int CustomComparison<TSearch>(TSearch value, T item);
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="BinarySearchTreeBase{T}"/> class.
/// </summary>
protected BinarySearchTreeBase()
{
_comparer = Comparer<T>.Default;
}
/// <summary>
/// Initializes a new instance of the <see cref="BinarySearchTreeBase{T}"/> class.
/// </summary>
/// <param name="comparer">The comparer to use when comparing items.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
protected BinarySearchTreeBase(IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
_comparer = comparer;
}
/// <summary>
/// Initializes a new instance of the <see cref="BinarySearchTreeBase&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <param name="comparison">The comparison.</param>
protected BinarySearchTreeBase(Comparison<T> comparison)
{
Guard.ArgumentNotNull(comparison, "comparison");
_comparer = new ComparisonComparer<T>(comparison);
}
#endregion
#region Public Members
/// <summary>
/// Gets the comparer.
/// </summary>
/// <value>The comparer.</value>
public IComparer<T> Comparer => _comparer;
#endregion
#region Protected Members
/// <summary>
/// Finds the node containing the specified data key.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>
/// The node with the specified key if found. If the key is not in the tree, this method returns null.
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected virtual BinaryTree<T> FindNode(T item)
{
if (_tree == null)
{
return null;
}
var currentNode = _tree;
while (currentNode != null)
{
var nodeResult = _comparer.Compare(item, currentNode.Data);
if (nodeResult == 0)
{
return currentNode;
}
currentNode = nodeResult < 0 ? currentNode.Left : currentNode.Right;
}
return null;
}
/// <summary>
/// Finds the node that matches the custom delegate.
/// </summary>
/// <typeparam name="TSearch">The type of the search.</typeparam>
/// <param name="value">The value.</param>
/// <param name="customComparison">The custom comparison.</param>
/// <returns>The item if found, else null.</returns>
protected virtual BinaryTree<T> FindNode<TSearch>(TSearch value, CustomComparison<TSearch> customComparison)
{
if (_tree == null)
{
return null;
}
var currentNode = _tree;
while (currentNode != null)
{
var nodeResult = customComparison(value, currentNode.Data);
if (nodeResult == 0)
{
return currentNode;
}
currentNode = nodeResult < 0 ? currentNode.Left : currentNode.Right;
}
return null;
}
/// <summary>
/// Removes the item from the tree.
/// </summary>
/// <param name="item">The item to remove.</param>
/// <returns>An indication of whether the item has been removed from the tree.</returns>
protected abstract bool RemoveItem(T item);
/// <summary>
/// Adds the item.
/// </summary>
/// <param name="item">The item.</param>
protected abstract void AddItem(T item);
/// <summary>
/// Find the maximum node.
/// </summary>
/// <returns>The maximum node.</returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected BinaryTree<T> FindMaximumNode()
{
#region Debug
Debug.Assert(_tree != null);
#endregion
return FindMaximumNode(_tree);
}
/// <summary>
/// Find the minimum node.
/// </summary>
/// <returns>The minimum node.</returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected BinaryTree<T> FindMinimumNode()
{
#region Debug
Debug.Assert(_tree != null);
#endregion
return FindMinimumNode(_tree);
}
/// <summary>
/// Finds the maximum node.
/// </summary>
/// <param name="startNode">The start node.</param>
/// <returns>The maximum node below this node.</returns>
[SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
protected static BinaryTree<T> FindMaximumNode(BinaryTree<T> startNode)
{
#region Asserts
Debug.Assert(startNode != null);
#endregion
var searchNode = startNode;
while (searchNode.Right != null)
{
searchNode = searchNode.Right;
}
return searchNode;
}
/// <summary>
/// Finds the minimum node.
/// </summary>
/// <param name="startNode">The start node.</param>
/// <returns>The minimum node below this node.</returns>
[SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
protected static BinaryTree<T> FindMinimumNode(BinaryTree<T> startNode)
{
#region Asserts
Debug.Assert(startNode != null);
#endregion
var searchNode = startNode;
while (searchNode.Left != null)
{
searchNode = searchNode.Left;
}
return searchNode;
}
/// <summary>
/// Gets or sets the <see cref="BinaryTree{T}"/> for this <see cref="BinarySearchTreeBase{TKey,TValue}"/>.
/// </summary>
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected BinaryTree<T> Tree
{
get
{
return _tree;
}
set
{
_tree = value;
}
}
#endregion
#region Private Members
/// <summary>
/// Visits the node in an in-order fashion.
/// </summary>
/// <param name="node">The node.</param>
/// <param name="visitor">The visitor.</param>
private static void VisitNode(BinaryTree<T> node, OrderedVisitor<T> visitor)
{
if (node != null)
{
var pair = node.Data;
visitor.VisitPreOrder(pair);
VisitNode(node.Left, visitor);
visitor.VisitInOrder(pair);
VisitNode(node.Right, visitor);
visitor.VisitPostOrder(pair);
}
}
#endregion
#region ISearchTree<TKey,TValue> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Minimum" lang="cs" title="The following example shows how to use the Minimum property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Minimum" lang="vbnet" title="The following example shows how to use the Minimum property."/>
/// </example>
public virtual T Minimum
{
get
{
#region Validation
ValidateEmpty();
#endregion
return FindMinimumNode().Data;
}
}
private void ValidateEmpty()
{
if (Count == 0)
{
throw new InvalidOperationException("The search tree is empty.");
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Maximum" lang="cs" title="The following example shows how to use the Maximum property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Maximum" lang="vbnet" title="The following example shows how to use the Maximum property."/>
/// </example>
public virtual T Maximum
{
get
{
ValidateEmpty();
return FindMaximumNode().Data;
}
} /// <inheritdoc/>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
public void DepthFirstTraversal(OrderedVisitor<T> visitor)
{
Guard.ArgumentNotNull(visitor, "visitor");
VisitNode(_tree, visitor);
}
/// <inheritdoc/>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IEnumerator<T> GetOrderedEnumerator()
{
if (_tree != null)
{
var trackingVisitor = new TrackingVisitor<T>();
var inOrderVisitor = new InOrderVisitor<T>(trackingVisitor);
_tree.DepthFirstTraversal(inOrderVisitor);
var trackingList = trackingVisitor.TrackingList;
for (var i = 0; i < trackingList.Count; i++)
{
yield return trackingList[i];
}
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="IsEmpty" lang="cs" title="The following example shows how to use the IsEmpty property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="IsEmpty" lang="vbnet" title="The following example shows how to use the IsEmpty property."/>
/// </example>
public bool IsEmpty => Count == 0;
/// <inheritdoc />
public bool Remove(T item)
{
var itemRemoved = RemoveItem(item);
if (itemRemoved)
{
Count--;
}
return itemRemoved;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Clear" lang="cs" title="The following example shows how to use the Clear method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Clear" lang="vbnet" title="The following example shows how to use the Clear method."/>
/// </example>
public void Clear()
{
ClearItems();
}
/// <summary>
/// Clears all the objects in this instance.
/// </summary>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void ClearItems()
{
_tree = null;
Count = 0;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Count" lang="cs" title="The following example shows how to use the Count property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Count" lang="vbnet" title="The following example shows how to use the Count property."/>
/// </example>
public int Count { get; private set; }
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="GetEnumerator" lang="cs" title="The following example shows how to use the GetEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="GetEnumerator" lang="vbnet" title="The following example shows how to use the GetEnumerator method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
public IEnumerator<T> GetEnumerator()
{
if (_tree != null)
{
var stack = new Stack<BinaryTree<T>>();
stack.Push(_tree);
while (stack.Count > 0)
{
var binaryTree = stack.Pop();
yield return binaryTree.Data;
if (binaryTree.Left != null)
{
stack.Push(binaryTree.Left);
}
if (binaryTree.Right != null)
{
stack.Push(binaryTree.Right);
}
}
}
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="AddKeyValuePair" lang="cs" title="The following example shows how to use the AddKeyValuePair method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="AddKeyValuePair" lang="vbnet" title="The following example shows how to use the AddKeyValuePair method."/>
/// </example>
public void Add(T item)
{
AddItem(item);
Count++;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public virtual bool Contains(T item)
{
var node = FindNode(item);
return node != null;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="CopyTo" lang="cs" title="The following example shows how to use the CopyTo method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="CopyTo" lang="vbnet" title="The following example shows how to use the CopyTo method."/>
/// </example>
public void CopyTo(T[] array, int arrayIndex)
{
#region Validation
Guard.ArgumentNotNull(array, "array");
if ((array.Length - arrayIndex) < Count)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
foreach (var association in _tree)
{
array[arrayIndex++] = association;
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="IsReadOnly" lang="cs" title="The following example shows how to use the IsReadOnly property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="IsReadOnly" lang="vbnet" title="The following example shows how to use the IsReadOnly property."/>
/// </example>
public bool IsReadOnly => false;
#endregion
}
}

674
src/NGenerics/DataStructures/Trees/BinaryTree.cs

@ -1,674 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using NGenerics.Patterns.Visitor;
using NGenerics.Util;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An implementation of a Binary Tree data structure.
/// </summary>
/// <typeparam name="T">The type of elements in the <see cref="BinaryTree{T}"/>.</typeparam>
//[Serializable]
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
public class BinaryTree<T> : ICollection<T>, ITree<T>
{
#region Globals
private BinaryTree<T> _leftSubtree;
private BinaryTree<T> _rightSubtree;
private T _data;
#endregion
#region Construction
/// <param name="data">The data contained in this node.</param>
public BinaryTree(T data) : this(data, null, null) { }
/// <param name="data">The data.</param>
/// <param name="left">The data of the left subtree.</param>
/// <param name="right">The data of the right subtree.</param>
public BinaryTree(T data, T left, T right) : this(data, new BinaryTree<T>(left), new BinaryTree<T>(right)) { }
/// <param name="data">The data contained in this node.</param>
/// <param name="left">The left subtree.</param>
/// <param name="right">The right subtree.</param>
public BinaryTree(T data, BinaryTree<T> left, BinaryTree<T> right)
: this(data, left, right, true)
{
}
/// <param name="data">The data contained in this node.</param>
/// <param name="left">The left subtree.</param>
/// <param name="right">The right subtree.</param>
/// <param name="validateData"><see langword="true"/> to validate <paramref name="data"/>; otherwise <see langword="false"/>.</param>
internal BinaryTree(T data, BinaryTree<T> left, BinaryTree<T> right, bool validateData)
{
#region Validation
//TODO: probably not the most efficient way of doing this but SplayTree needs to use a BinaryTree with null data.
if (validateData)
{
Guard.ArgumentNotNull(data, "data");
}
#endregion
_leftSubtree = left;
if (left != null)
{
left.Parent = this;
}
_rightSubtree = right;
if (right != null)
{
right.Parent = this;
}
_data = data;
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
public bool IsEmpty => Count == 0;
/// <inheritdoc />
public bool IsFull => (_leftSubtree != null) && (_rightSubtree != null);
/// <inheritdoc />
public bool Contains(T item)
{
foreach (var thisItem in this)
{
if (item.Equals(thisItem))
{
return true;
}
}
return false;
}
/// <inheritdoc />
public void CopyTo(T[] array, int arrayIndex)
{
Guard.ArgumentNotNull(array, "array");
foreach (var item in this)
{
#region Validation
if (arrayIndex >= array.Length)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
array[arrayIndex++] = item;
}
}
/// <inheritdoc />
public int Count
{
get
{
var count = 0;
if (_leftSubtree != null)
{
count++;
}
if (_rightSubtree != null)
{
count++;
}
return count;
}
}
/// <inheritdoc />
public void Add(T item)
{
AddItem(new BinaryTree<T>(item));
}
/// <inheritdoc />
public bool Remove(T item)
{
if (_leftSubtree != null)
{
if (_leftSubtree._data.Equals(item))
{
RemoveLeft();
return true;
}
}
if (_rightSubtree != null)
{
if (_rightSubtree._data.Equals(item))
{
RemoveRight();
return true;
}
}
return false;
}
/// <summary>
/// Removes the specified child.
/// </summary>
/// <param name="child">The child.</param>
/// <returns>A value indicating whether the child was found (and removed) from this tree.</returns>
public bool Remove(BinaryTree<T> child)
{
if (_leftSubtree != null)
{
if (_leftSubtree == child)
{
RemoveLeft();
return true;
}
}
if (_rightSubtree != null)
{
if (_rightSubtree == child)
{
RemoveRight();
return true;
}
}
return false;
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
public IEnumerator<T> GetEnumerator()
{
var stack = new Stack<BinaryTree<T>>();
stack.Push(this);
while (stack.Count > 0)
{
var tree = stack.Pop();
yield return tree.Data;
if (tree._leftSubtree != null)
{
stack.Push(tree._leftSubtree);
}
if (tree._rightSubtree != null)
{
stack.Push(tree._rightSubtree);
}
}
}
/// <inheritdoc />
public virtual void Clear()
{
if (_leftSubtree != null)
{
_leftSubtree.Parent = null;
_leftSubtree = null;
}
if (_rightSubtree != null)
{
_rightSubtree.Parent = null;
_rightSubtree = null;
}
}
#endregion
#region ITree<T> Members
/// <inheritdoc />
void ITree<T>.Add(ITree<T> child)
{
AddItem((BinaryTree<T>)child);
}
/// <inheritdoc />
ITree<T> ITree<T>.GetChild(int index)
{
return GetChild(index);
}
/// <inheritdoc />
bool ITree<T>.Remove(ITree<T> child)
{
return Remove((BinaryTree<T>)child);
}
/// <inheritdoc />
ITree<T> ITree<T>.FindNode(Predicate<T> condition)
{
return FindNode(condition);
}
/// <inheritdoc />
ITree<T> ITree<T>.Parent => Parent;
#endregion
#region Public Members
/// <summary>
/// Gets the parent of the current node..
/// </summary>
/// <value>The parent of the current node.</value>
public BinaryTree<T> Parent { get; private set; }
/// <summary>
/// Finds the node with the specified condition. If a node is not found matching
/// the specified condition, null is returned.
/// </summary>
/// <param name="condition">The condition to test.</param>
/// <returns>The first node that matches the condition supplied. If a node is not found, null is returned.</returns>
/// <exception cref="ArgumentNullException"><paramref name="condition"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public BinaryTree<T> FindNode(Predicate<T> condition)
{
Guard.ArgumentNotNull(condition, "condition");
if (condition(Data))
{
return this;
}
if (_leftSubtree != null)
{
var ret = _leftSubtree.FindNode(condition);
if (ret != null)
{
return ret;
}
}
if (_rightSubtree != null)
{
var ret = _rightSubtree.FindNode(condition);
if (ret != null)
{
return ret;
}
}
return null;
}
/// <summary>
/// Gets or sets the left subtree.
/// </summary>
/// <value>The left subtree.</value>
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual BinaryTree<T> Left
{
get
{
return _leftSubtree;
}
set
{
if (_leftSubtree != null)
{
RemoveLeft();
}
if (value != null)
{
if (value.Parent != null)
{
value.Parent.Remove(value);
}
value.Parent = this;
}
_leftSubtree = value;
}
}
/// <summary>
/// Gets or sets the right subtree.
/// </summary>
/// <value>The right subtree.</value>
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual BinaryTree<T> Right
{
get
{
return _rightSubtree;
}
set
{
if (_rightSubtree != null)
{
RemoveRight();
}
if (value != null)
{
if (value.Parent != null)
{
value.Parent.Remove(value);
}
value.Parent = this;
}
_rightSubtree = value;
}
}
/// <inheritdoc />
public virtual T Data
{
get
{
return _data;
}
set
{
#region Validation
Guard.ArgumentNotNull(value, "data");
#endregion
_data = value;
}
}
/// <inheritdoc />
public int Degree => Count;
/// <summary>
/// Gets the child at the specified index.
/// </summary>
/// <param name="index">The index of the child in question.</param>
/// <returns>The child at the specified index.</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> does not equal 0 or 1.</exception>
public BinaryTree<T> GetChild(int index)
{
switch (index)
{
case 0:
return _leftSubtree;
case 1:
return _rightSubtree;
default:
throw new ArgumentOutOfRangeException("index");
}
}
/// <inheritdoc />
public virtual int Height
{
get
{
if (Degree == 0)
{
return 0;
}
return 1 + FindMaximumChildHeight();
}
}
/// <summary>
/// Performs a depth first traversal on this tree with the specified visitor.
/// </summary>
/// <param name="orderedVisitor">The ordered visitor.</param>
/// <exception cref="ArgumentNullException"><paramref name="orderedVisitor"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public virtual void DepthFirstTraversal(OrderedVisitor<T> orderedVisitor)
{
Guard.ArgumentNotNull(orderedVisitor, "orderedVisitor");
if (orderedVisitor.HasCompleted)
{
return;
}
// Preorder visit
orderedVisitor.VisitPreOrder(Data);
if (_leftSubtree != null)
{
_leftSubtree.DepthFirstTraversal(orderedVisitor);
}
// In-order visit
orderedVisitor.VisitInOrder(_data);
if (_rightSubtree != null)
{
_rightSubtree.DepthFirstTraversal(orderedVisitor);
}
// PostOrder visit
orderedVisitor.VisitPostOrder(Data);
}
/// <summary>
/// Performs a breadth first traversal on this tree with the specified visitor.
/// </summary>
/// <param name="visitor">The visitor.</param>
/// <exception cref="ArgumentNullException"><paramref name="visitor"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public virtual void BreadthFirstTraversal(IVisitor<T> visitor)
{
Guard.ArgumentNotNull(visitor, "visitor");
var queue = new Queue<BinaryTree<T>>();
queue.Enqueue(this);
while (queue.Count > 0)
{
if (visitor.HasCompleted)
{
break;
}
var binaryTree = queue.Dequeue();
visitor.Visit(binaryTree.Data);
for (var i = 0; i < binaryTree.Degree; i++)
{
var child = binaryTree.GetChild(i);
if (child != null)
{
queue.Enqueue(child);
}
}
}
}
/// <inheritdoc />
public virtual bool IsLeafNode => Degree == 0;
/// <summary>
/// Removes the left child.
/// </summary>
public virtual void RemoveLeft()
{
if (_leftSubtree != null)
{
_leftSubtree.Parent = null;
_leftSubtree = null;
}
}
/// <summary>
/// Removes the left child.
/// </summary>
public virtual void RemoveRight()
{
if (_rightSubtree != null)
{
_rightSubtree.Parent = null;
_rightSubtree = null;
}
}
/// <summary>
/// Adds an item to the <see cref="ICollection{T}"/>.
/// </summary>
/// <param name="subtree">The subtree.</param>
/// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only.</exception>
/// <exception cref="InvalidOperationException">The <see cref="BinaryTree{T}"/> is full.</exception>
/// <exception cref="ArgumentNullException"><paramref name="subtree"/> is null (Nothing in Visual Basic).</exception>
public void Add(BinaryTree<T> subtree)
{
Guard.ArgumentNotNull(subtree, "subtree");
AddItem(subtree);
}
/// <summary>
/// Adds an item to the <see cref="ICollection{T}"/>.
/// </summary>
/// <param name="subtree">The subtree.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void AddItem(BinaryTree<T> subtree)
{
if (_leftSubtree == null)
{
if (subtree.Parent != null)
{
subtree.Parent.Remove(subtree);
}
_leftSubtree = subtree;
subtree.Parent = this;
}
else if (_rightSubtree == null)
{
if (subtree.Parent != null)
{
subtree.Parent.Remove(subtree);
}
_rightSubtree = subtree;
subtree.Parent = this;
}
else
{
throw new InvalidOperationException("This binary tree is full.");
}
}
#endregion
#region Private Members
/// <summary>
/// Finds the maximum height between the child nodes.
/// </summary>
/// <returns>The maximum height of the tree between all paths from this node and all leaf nodes.</returns>
protected virtual int FindMaximumChildHeight()
{
var leftHeight = 0;
var rightHeight = 0;
if (_leftSubtree != null)
{
leftHeight = _leftSubtree.Height;
}
if (_rightSubtree != null)
{
rightHeight = _rightSubtree.Height;
}
return leftHeight > rightHeight ? leftHeight : rightHeight;
}
#endregion
#region Operator Overloads
/// <summary>
/// Gets the <see cref="BinaryTree{T}"/> at the specified index.
/// </summary>
public BinaryTree<T> this[int index] => GetChild(index);
#endregion
#region ICollection<T> Members
/// <inheritdoc />
public bool IsReadOnly => false;
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Object Members
/// <inheritdoc />
public override string ToString()
{
return _data.ToString();
}
#endregion
}
}

68
src/NGenerics/DataStructures/Trees/ISearchTree.cs

@ -1,68 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Patterns.Visitor;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An interface for Search Trees that mimic a dictionary.
/// </summary>
/// <typeparam name="T">The type of element to hold in the tree.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
public interface ISearchTree<T> : ICollection<T>
{
/// <summary>
/// Gets the largest item in the tree.
/// </summary>
/// <value>The largest item in the tree.</value>
/// <exception cref="InvalidOperationException">The <see cref="ISearchTree{T}"/> is empty.</exception>
T Maximum { get; }
/// <summary>
/// Gets the smallest item in the tree.
/// </summary>
/// <value>The smallest item in the tree.</value>
/// <exception cref="InvalidOperationException">The <see cref="ISearchTree{T}"/> is empty.</exception>
T Minimum { get; }
/// <summary>
/// Performs a depth first traversal on the search tree.
/// </summary>
/// <param name="visitor">The visitor to use.</param>
/// <exception cref="ArgumentNullException"><paramref name="visitor"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="DepthFirstTraversal" lang="cs" title="The following example shows how to use the DepthFirstTraversal method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="DepthFirstTraversal" lang="vbnet" title="The following example shows how to use the DepthFirstTraversal method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
void DepthFirstTraversal(OrderedVisitor<T> visitor);
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="GetOrderedEnumerator" lang="cs" title="The following example shows how to use the GetOrderedEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="GetOrderedEnumerator" lang="vbnet" title="The following example shows how to use the GetOrderedEnumerator method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IEnumerator<T> GetOrderedEnumerator();
}
}

82
src/NGenerics/DataStructures/Trees/ITree.cs

@ -1,82 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An interface for the tree data structure
/// </summary>
/// <typeparam name="T">The type of elements in the tree.</typeparam>
public interface ITree<T>
{
/// <summary>
/// Adds the specified child to the tree.
/// </summary>
/// <param name="child">The child to add..</param>
void Add(ITree<T> child);
/// <summary>
/// Gets the data held in this node.
/// </summary>
/// <value>The data.</value>
T Data { get; }
/// <summary>
/// Gets the degree of this node.
/// </summary>
/// <value>The degree of this node.</value>
int Degree { get; }
/// <summary>
/// Gets the child at the specified index.
/// </summary>
/// <param name="index">The index.</param>
/// <returns>The child at the specified index.</returns>
ITree<T> GetChild(int index);
/// <summary>
/// Gets the height of this tree.
/// </summary>
/// <value>The height of this tree.</value>
int Height { get; }
/// <summary>
/// Gets a value indicating whether this instance is leaf node.
/// </summary>
/// <value>
/// <c>true</c> if this instance is leaf node; otherwise, <c>false</c>.
/// </value>
bool IsLeafNode { get; }
/// <summary>
/// Removes the specified child.
/// </summary>
/// <param name="child">The child.</param>
/// <returns>An indication of whether the child was found (and removed) from this tree.</returns>
bool Remove(ITree<T> child);
/// <summary>
/// Finds the node for which the given predicate holds true.
/// </summary>
/// <param name="condition">The condition to test on the data item.</param>
/// <returns>The fist node that matches the condition if found, otherwise null.</returns>
ITree<T> FindNode(Predicate<T> condition);
/// <summary>
/// Gets the parent of the current node.
/// </summary>
/// <value>The parent of the current node.</value>
ITree<T> Parent { get; }
}
}

21
src/NGenerics/DataStructures/Trees/NodeColor.cs

@ -1,21 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.DataStructures.Trees
{
internal enum NodeColor
{
Red = 0,
Black = 1
}
}

291
src/NGenerics/DataStructures/Trees/RedBlackTree.cs

@ -1,291 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
/*
* The insertion and deletion code is based on the code found at http://eternallyconfuzzled.com/tuts/redblack.htm.
* It's an excellent tutorial - if you want to understand Red Black trees, look there first.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An implementation of a Red-Black tree.
/// </summary>
/// <typeparam name="T">The type of element to keep in the tree.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
//[Serializable]
public class RedBlackTree<T> : BinarySearchTreeBase<T>
{
#region Construction
/// <inheritdoc />
public RedBlackTree()
{
// Do nothing - the default Comparer will be used by the base class.
}
/// <inheritdoc/>
public RedBlackTree(IComparer<T> comparer)
: base(comparer)
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTree(Comparison<T> comparison)
: base(comparison)
{
// Do nothing else.
}
#endregion
#region Public Members
/// <summary>
/// Adds an element with the provided key and value to the <see cref="IDictionary{TKey,TValue}"/>.
/// </summary>
/// <param name="item">The item.</param>
protected override void AddItem(T item)
{
#region Validation
if (Equals(item, null))
{
throw new ArgumentNullException("item");
}
#endregion
var root = (RedBlackTreeNode<T>)Tree;
var newRoot = InsertNode(root, item);
newRoot.Color = NodeColor.Black;
Tree = newRoot;
}
/// <summary>
/// Removes the element with the specified key from the <see cref="IDictionary{TKey,TValue}"/>.
/// </summary>
/// <param name="item">The item to remove.</param>
/// <returns>
/// <c>true</c> if the element is successfully removed; otherwise, <c>false</c>. This method also returns false if key was not found in the original <see cref="IDictionary{TKey,TValue}"/>.
/// </returns>
/// <inheritdoc/>
protected override bool RemoveItem(T item)
{
if (Tree != null)
{
var startNode = new RedBlackTreeNode<T>(default(T));
var childNode = startNode;
startNode.Right = (RedBlackTreeNode<T>)Tree;
RedBlackTreeNode<T> parent = null;
RedBlackTreeNode<T> foundNode = null;
var direction = true;
while (childNode[direction] != null)
{
var lastDirection = direction;
var grandParent = parent;
parent = childNode;
childNode = childNode[direction];
var comparisonValue = Comparer.Compare(childNode.Data, item);
if (comparisonValue == 0)
{
foundNode = childNode;
}
direction = comparisonValue < 0;
if ((IsBlack(childNode)) && (IsBlack(childNode[direction])))
{
if (IsRed(childNode[!direction]))
{
parent = parent[lastDirection] = SingleRotation(childNode, direction);
}
else if (IsBlack(childNode[direction]))
{
var sibling = parent[!lastDirection];
if (sibling != null)
{
if ((IsBlack(sibling.Left)) && (IsBlack(sibling.Right)))
{
parent.Color = NodeColor.Black;
sibling.Color = NodeColor.Red;
childNode.Color = NodeColor.Red;
}
else
{
var parentDirection = grandParent.Right == parent;
if (IsRed(sibling[lastDirection]))
{
grandParent[parentDirection] = DoubleRotation(parent, lastDirection);
}
else if (IsRed(sibling[!lastDirection]))
{
grandParent[parentDirection] = SingleRotation(parent, lastDirection);
}
childNode.Color = grandParent[parentDirection].Color = NodeColor.Red;
grandParent[parentDirection].Left.Color = NodeColor.Black;
grandParent[parentDirection].Right.Color = NodeColor.Black;
}
}
}
}
}
if (foundNode != null)
{
foundNode.Data = childNode.Data;
parent[parent.Right == childNode] = childNode[childNode.Left == null];
}
Tree = startNode.Right;
if (Tree != null)
{
((RedBlackTreeNode<T>)Tree).Color = NodeColor.Black;
}
if (foundNode != null)
{
return true;
}
}
return false;
}
#endregion
#region Private Members
/// <summary>
/// Determines whether the specified node is red.
/// </summary>
/// <param name="node">The node.</param>
/// <returns>
/// <c>true</c> if the specified node is red; otherwise, <c>false</c>.
/// </returns>
private static bool IsRed(RedBlackTreeNode<T> node)
{
return (node != null) && (node.Color == NodeColor.Red);
}
/// <summary>
/// Determines whether the specified node is black.
/// </summary>
/// <param name="node">The node.</param>
/// <returns>
/// <c>true</c> if the specified node is black; otherwise, <c>false</c>.
/// </returns>
private static bool IsBlack(RedBlackTreeNode<T> node)
{
return (node == null) || (node.Color == NodeColor.Black);
}
/// <summary>
/// A recursive implementation of insertion of a node into the tree.
/// </summary>
/// <param name="node">The start node.</param>
/// <param name="item">The item.</param>
/// <returns>The node created in the insertion.</returns>
private RedBlackTreeNode<T> InsertNode(RedBlackTreeNode<T> node, T item)
{
if (node == null)
{
node = new RedBlackTreeNode<T>(item);
}
else if (Comparer.Compare(item, node.Data) != 0)
{
var direction = Comparer.Compare(node.Data, item) < 0;
node[direction] = InsertNode(node[direction], item);
if (IsRed(node[direction]))
{
if (IsRed(node[!direction]))
{
node.Color = NodeColor.Red;
node.Left.Color = NodeColor.Black;
node.Right.Color = NodeColor.Black;
}
else
{
if (IsRed(node[direction][direction]))
{
node = SingleRotation(node, !direction);
}
else if (IsRed(node[direction][!direction]))
{
node = DoubleRotation(node, !direction);
}
}
}
}
else
{
throw new ArgumentException(alreadyContainedInTheTree);
}
return node;
}
/// <summary>
/// Perform a single rotation on the node provided..
/// </summary>
/// <param name="node">The node on which to focus the rotation.</param>
/// <param name="direction">The direction of the rotation. If direction is equal to true, a right rotation is performed. Other wise, a left rotation.</param>
/// <returns>The new root of the cluster.</returns>
private static RedBlackTreeNode<T> SingleRotation(RedBlackTreeNode<T> node, bool direction)
{
var childSibling = node[!direction];
node[!direction] = childSibling[direction];
childSibling[direction] = node;
node.Color = NodeColor.Red;
childSibling.Color = NodeColor.Black;
return childSibling;
}
/// <summary>
/// Perform a double rotation on the node provided..
/// </summary>
/// <param name="node">The node on which to focus the rotation.</param>
/// <param name="direction">The direction of the rotation. If direction is equal to true, a right rotation is performed. Other wise, a left rotation.</param>
/// <returns>The new root of the cluster.</returns>
private static RedBlackTreeNode<T> DoubleRotation(RedBlackTreeNode<T> node, bool direction)
{
node[!direction] = SingleRotation(node[!direction], !direction);
return SingleRotation(node, direction);
}
#endregion
}
}

251
src/NGenerics/DataStructures/Trees/RedBlackTreeDictionary.cs

@ -1,251 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
/*
* The insertion and deletion code is based on the code found at http://eternallyconfuzzled.com/tuts/redblack.htm.
* It's an excellent tutorial - if you want to understand Red Black trees, look there first.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Comparers;
using NGenerics.Patterns.Visitor;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An implementation of a Red-Black tree.
/// </summary>
/// <typeparam name="TKey">The type of the keys in the <see cref="RedBlackTree{TKey,TValue}"/>.</typeparam>
/// <typeparam name="TValue">The type of the values in the <see cref="RedBlackTree{TKey,TValue}"/>.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
#if (!SILVERLIGHT && !WINDOWSPHONE)
//[Serializable]
#endif
public class RedBlackTree<TKey, TValue> : RedBlackTree<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue> // BinarySearchTreeBase<TKey, TValue>
{
#region Construction
/// <inheritdoc />
public RedBlackTree() : base(new KeyValuePairComparer<TKey, TValue>())
{
// Do nothing - the default Comparer will be used by the base class.
}
/// <inheritdoc/>
public RedBlackTree(IComparer<TKey> comparer)
: base(new KeyValuePairComparer<TKey, TValue>(comparer))
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTree(Comparison<TKey> comparison)
: base(new KeyValuePairComparer<TKey, TValue>(comparison))
{
// Do nothing else.
}
#endregion
#region Private Members
private RedBlackTreeNode<KeyValuePair<TKey, TValue>> FindNode(TKey key)
{
return base.FindNode(new KeyValuePair<TKey, TValue>(key, default(TValue))) as RedBlackTreeNode<KeyValuePair<TKey, TValue>>;
}
private bool Contains(KeyValuePair<TKey, TValue> item, bool checkValue)
{
var node = FindNode(item);
if ((node != null) && !checkValue)
{
return true;
}
return node != null && Equals(item.Value, node.Data.Value);
}
#endregion
#region IDictionary<TKey,TValue> Members
/// <summary>
/// Removes the element with the specified key from the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <param name="key">The key of the element to remove.</param>
/// <returns>
/// true if the element is successfully removed; otherwise, false. This method also returns false if <paramref name="key"/> was not found in the original <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key"/> is null.
/// </exception>
/// <exception cref="T:System.NotSupportedException">
/// The <see cref="T:System.Collections.Generic.IDictionary`2"/> is read-only.
/// </exception>
public bool Remove(TKey key)
{
return Remove(new KeyValuePair<TKey, TValue>(key, default(TValue)));
}
/// <summary>
/// Adds an element with the provided key and value to the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <param name="key">The object to use as the key of the element to add.</param>
/// <param name="value">The object to use as the value of the element to add.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key"/> is null.
/// </exception>
/// <exception cref="T:System.ArgumentException">
/// An element with the same key already exists in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </exception>
/// <exception cref="T:System.NotSupportedException">
/// The <see cref="T:System.Collections.Generic.IDictionary`2"/> is read-only.
/// </exception>
public void Add(TKey key, TValue value)
{
if (Equals(key, null))
{
throw new ArgumentNullException("key");
}
Add(new KeyValuePair<TKey, TValue>(key, value));
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.IDictionary`2"/> contains an element with the specified key.
/// </summary>
/// <param name="key">The key to locate in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.</param>
/// <returns>
/// true if the <see cref="T:System.Collections.Generic.IDictionary`2"/> contains an element with the key; otherwise, false.
/// </returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key"/> is null.
/// </exception>
public bool ContainsKey(TKey key)
{
return Contains(new KeyValuePair<TKey, TValue>(key, default(TValue)), false);
}
/// <summary>
/// Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <value></value>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Keys" lang="cs" title="The following example shows how to use the Keys property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Keys" lang="vbnet" title="The following example shows how to use the Keys property."/>
/// </example>
public ICollection<TKey> Keys
{
get
{
// Get the keys in sorted order
var visitor = new KeyTrackingVisitor<TKey, TValue>();
var inOrderVisitor = new InOrderVisitor<KeyValuePair<TKey, TValue>>(visitor);
DepthFirstTraversal(inOrderVisitor);
return new ReadOnlyCollection<TKey>(visitor.TrackingList);
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="TryGetValue" lang="cs" title="The following example shows how to use the TryGetValue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="TryGetValue" lang="vbnet" title="The following example shows how to use the TryGetValue method."/>
/// </example>
public bool TryGetValue(TKey key, out TValue value)
{
var node = FindNode(new KeyValuePair<TKey, TValue>(key, default(TValue)));
if (node == null)
{
value = default(TValue);
return false;
}
value = node.Data.Value;
return true;
}
/// <summary>
/// Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the values in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <value></value>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Values" lang="cs" title="The following example shows how to use the Values property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Values" lang="vbnet" title="The following example shows how to use the Values property."/>
/// </example>
public ICollection<TValue> Values
{
get
{
var visitor = new ValueTrackingVisitor<TKey, TValue>();
var inOrderVisitor = new InOrderVisitor<KeyValuePair<TKey, TValue>>(visitor);
DepthFirstTraversal(inOrderVisitor);
return new ReadOnlyCollection<TValue>(visitor.TrackingList);
}
}
/// <summary>
/// Gets or sets the value with the specified key.
/// </summary>
/// <value>The key of the item to set or get.</value>
public TValue this[TKey key]
{
get
{
var node = FindNode(key);
if (node == null)
{
throw new KeyNotFoundException("key");
}
return node.Data.Value;
}
set
{
var node = FindNode(key);
if (node == null)
{
throw new KeyNotFoundException("key");
}
node.Data = new KeyValuePair<TKey, TValue>(key, value);
}
}
#endregion
#region ICollection<KeyValuePair<TKey,TValue>> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public override bool Contains(KeyValuePair<TKey, TValue> item)
{
return Contains(item, true);
}
#endregion
}
}

232
src/NGenerics/DataStructures/Trees/RedBlackTreeList.cs

@ -1,232 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// A RedBlack Tree list variant. Equivalent to <see cref="RedBlackTree{TKey,TValue}"/> where TValue is a <see cref="LinkedList{T}"/>.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
//[Serializable]
internal class RedBlackTreeList<TKey, TValue> : RedBlackTree<TKey, LinkedList<TValue>>
{
#region Delegates
private delegate bool NodeAction(TKey key, LinkedList<TValue> values);
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="RedBlackTreeList&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <inheritdoc/>
public RedBlackTreeList()
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTreeList(IComparer<TKey> comparer)
: base(comparer)
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTreeList(Comparison<TKey> comparison)
: base(comparison)
{
// Do nothing else.
}
#endregion
#region Public Members
/// <summary>
/// Determines whether the specified value contains value.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// <c>true</c> if the specified value contains value; otherwise, <c>false</c>.
/// </returns>
public bool ContainsValue(TValue value)
{
return TraverseItems((key, list) => list.Contains(value));
}
/// <summary>
/// Gets the value enumerator.
/// </summary>
/// <returns>An enumerator to enumerate through the values contained in this instance.</returns>
public IEnumerator<TValue> GetValueEnumerator()
{
var stack = new Stack<BinaryTree<KeyValuePair<TKey, LinkedList<TValue>>>>();
if (Tree != null)
{
stack.Push(Tree);
}
while (stack.Count > 0)
{
var currentNode = stack.Pop();
var list = currentNode.Data.Value;
foreach (var item in list)
{
yield return item;
}
if (currentNode.Left != null)
{
stack.Push(currentNode.Left);
}
if (currentNode.Right != null)
{
stack.Push(currentNode.Right);
}
}
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IEnumerator<KeyValuePair<TKey, TValue>> GetKeyEnumerator()
{
var stack = new Stack<BinaryTree<KeyValuePair<TKey, LinkedList<TValue>>>>();
if (Tree != null)
{
stack.Push(Tree);
}
while (stack.Count > 0)
{
var currentNode = stack.Pop();
var list = currentNode.Data.Value;
foreach (var item in list)
{
yield return new KeyValuePair<TKey, TValue>(currentNode.Data.Key, item);
}
if (currentNode.Left != null)
{
stack.Push(currentNode.Left);
}
if (currentNode.Right != null)
{
stack.Push(currentNode.Right);
}
}
}
/// <summary>
/// Removes the specified value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="key">The key under which the item was found.</param>
/// <returns>A value indicating whether the item was found or not.</returns>
public bool Remove(TValue value, out TKey key)
{
var foundKey = default(TKey);
var ret = TraverseItems(
delegate (TKey itemKey, LinkedList<TValue> list)
{
if (list.Remove(value))
{
if (list.Count == 0)
{
Remove(itemKey);
}
foundKey = itemKey;
return true;
}
return false;
}
);
key = foundKey;
return ret;
}
#endregion
#region Private Members
/// <summary>
/// Traverses the items.
/// </summary>
/// <param name="shouldStop">A predicate that performs an action on the list, and indicates whether the enumeration of items should stop or not.</param>
/// <returns>An indication of whether the enumeration was stopped prematurely.</returns>
private bool TraverseItems(NodeAction shouldStop)
{
#region Validation
Debug.Assert(shouldStop != null);
#endregion
var stack = new Stack<BinaryTree<KeyValuePair<TKey, LinkedList<TValue>>>>();
if (Tree != null)
{
stack.Push(Tree);
}
while (stack.Count > 0)
{
var currentNode = stack.Pop();
if (shouldStop(currentNode.Data.Key, currentNode.Data.Value))
{
return true;
}
if (currentNode.Left != null)
{
stack.Push(currentNode.Left);
}
if (currentNode.Right != null)
{
stack.Push(currentNode.Right);
}
}
return false;
}
#endregion
}
}

107
src/NGenerics/DataStructures/Trees/RedBlackTreeNode.cs

@ -1,107 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// A container class, used for the RedBlackTree.
/// </summary>
/// <typeparam name="T">The type of element.</typeparam>
//[Serializable]
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
internal class RedBlackTreeNode<T> : BinaryTree<T>
{
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="RedBlackTreeNode&lt;T&gt;"/> class.
/// </summary>
/// <param name="data">The data contained in this node.</param>
internal RedBlackTreeNode(T data)
: base(data)
{
Color = NodeColor.Red;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the color of the current node.
/// </summary>
/// <value>The color of the node.</value>
internal NodeColor Color { get; set; }
/// <summary>
/// Gets or sets the <see cref="NGenerics.DataStructures.Trees.BinaryTree&lt;T&gt;"/> with the specified direction.
/// </summary>
/// <value></value>
internal RedBlackTreeNode<T> this[bool direction]
{
get
{
return direction ? Right : Left;
}
set
{
if (direction)
{
Right = value;
}
else
{
Left = value;
}
}
}
/// <summary>
/// Gets or sets the left subtree.
/// </summary>
/// <value>The left subtree.</value>
internal new RedBlackTreeNode<T> Left
{
get
{
return (RedBlackTreeNode<T>)base.Left;
}
set
{
base.Left = value;
}
}
/// <summary>
/// Gets or sets the right subtree.
/// </summary>
/// <value>The right subtree.</value>
internal new RedBlackTreeNode<T> Right
{
get
{
return (RedBlackTreeNode<T>)base.Right;
}
set
{
base.Right = value;
}
}
#endregion
}
}

76
src/NGenerics/NGenerics.csproj

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{415E048E-4611-4815-9CF2-D774E29079AC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NGenerics</RootNamespace>
<AssemblyName>NGenerics</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup>
<Compile Include="DataStructures\Comparers\ReverseComparer.cs" />
<Compile Include="DataStructures\General\Heap.cs" />
<Compile Include="DataStructures\General\HeapType.cs" />
<Compile Include="DataStructures\General\IHeap.cs" />
<Compile Include="DataStructures\Trees\BinarySearchTreeBase.cs" />
<Compile Include="DataStructures\Trees\BinaryTree.cs" />
<Compile Include="DataStructures\Comparers\ComparisonComparer.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Util\Guard.cs" />
<Compile Include="Patterns\Visitor\InOrderVisitor.cs" />
<Compile Include="DataStructures\Queues\IQueue.cs" />
<Compile Include="DataStructures\Trees\ISearchTree.cs" />
<Compile Include="DataStructures\Trees\ITree.cs" />
<Compile Include="Patterns\Visitor\IVisitor.cs" />
<Compile Include="Patterns\Visitor\KeyTrackingVisitor.cs" />
<Compile Include="DataStructures\Comparers\KeyValuePairComparer.cs" />
<Compile Include="DataStructures\Trees\NodeColor.cs" />
<Compile Include="Patterns\Visitor\OrderedVisitor.cs" />
<Compile Include="DataStructures\Queues\PriorityQueue.cs" />
<Compile Include="DataStructures\Queues\PriorityQueueType.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DataStructures\Trees\RedBlackTree.cs" />
<Compile Include="DataStructures\Trees\RedBlackTreeDictionary.cs" />
<Compile Include="DataStructures\Trees\RedBlackTreeList.cs" />
<Compile Include="DataStructures\Trees\RedBlackTreeNode.cs" />
<Compile Include="Patterns\Visitor\TrackingVisitor.cs" />
<Compile Include="Patterns\Visitor\ValueTrackingVisitor.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

34
src/NGenerics/Patterns/Visitor/IVisitor.cs

@ -1,34 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// Provides an interface for visitors.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public interface IVisitor<T>
{
/// <summary>
/// Gets a value indicating whether this instance is done performing it's work..
/// </summary>
/// <value><c>true</c> if this instance is done; otherwise, <c>false</c>.</value>
bool HasCompleted { get; }
/// <summary>
/// Visits the specified object.
/// </summary>
/// <param name="obj">The object to visit.</param>
void Visit(T obj);
}
}

51
src/NGenerics/Patterns/Visitor/InOrderVisitor.cs

@ -1,51 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// An in order implementation of the <see cref="OrderedVisitor{T}"/> class.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public sealed class InOrderVisitor<T> : OrderedVisitor<T>
{
#region Construction
/// <param name="visitor">The visitor.</param>
public InOrderVisitor(IVisitor<T> visitor) : base(visitor) { }
#endregion
#region OrderedVisitor<T> Members
/// <summary>
/// Visits the object in post order.
/// </summary>
/// <param name="obj">The obj.</param>
public override void VisitPostOrder(T obj)
{
// Do nothing.
}
/// <summary>
/// Visits the object in pre order.
/// </summary>
/// <param name="obj">The obj.</param>
public override void VisitPreOrder(T obj)
{
// Do nothing.
}
#endregion
}
}

65
src/NGenerics/Patterns/Visitor/KeyTrackingVisitor.cs

@ -1,65 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System.Collections.Generic;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that tracks (stores) keys from KeyValuePAirs in the order they were visited.
/// </summary>
/// <typeparam name="TKey">The type of the keys for the items to be visited.</typeparam>
/// <typeparam name="TValue">The type of the values for the items to be visited.</typeparam>
public sealed class KeyTrackingVisitor<TKey, TValue> : IVisitor<KeyValuePair<TKey, TValue>>
{
#region Globals
private readonly List<TKey> _tracks;
#endregion
#region Construction
/// <inheritdoc/>
public KeyTrackingVisitor()
{
_tracks = new List<TKey>();
}
#endregion
#region Public Members
/// <summary>
/// Gets the tracking list.
/// </summary>
/// <value>The tracking list.</value>
public IList<TKey> TrackingList => _tracks;
#endregion
#region IVisitor<KeyValuePair<TKey,TValue>> Members
/// <inheritdoc />
public void Visit(KeyValuePair<TKey, TValue> obj)
{
_tracks.Add(obj.Key);
}
/// <inheritdoc />
public bool HasCompleted => false;
#endregion
}
}

102
src/NGenerics/Patterns/Visitor/OrderedVisitor.cs

@ -1,102 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Util;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that visits objects in order (PreOrder, PostOrder, or InOrder).
/// Used primarily as a base class for Visitors specializing in a specific order type.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public class OrderedVisitor<T> : IVisitor<T>
{
#region Globals
private readonly IVisitor<T> _visitorToUse;
#endregion
#region Construction
/// <param name="visitorToUse">The visitor to use when visiting the object.</param>
/// <exception cref="ArgumentNullException"><paramref name="visitorToUse"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public OrderedVisitor(IVisitor<T> visitorToUse)
{
Guard.ArgumentNotNull(visitorToUse, "visitorToUse");
_visitorToUse = visitorToUse;
}
#endregion
#region IOrderedVisitor<T> Members
/// <summary>
/// Determines whether this visitor is done.
/// </summary>
/// <value></value>
/// <returns>
/// <c>true</c> if this visitor is done; otherwise, <c>false</c>.
/// </returns>
public bool HasCompleted => _visitorToUse.HasCompleted;
/// <summary>
/// Visits the object in pre order.
/// </summary>
/// <param name="obj">The obj.</param>
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "PreOrder")]
public virtual void VisitPreOrder(T obj)
{
_visitorToUse.Visit(obj);
}
/// <summary>
/// Visits the object in post order.
/// </summary>
/// <param name="obj">The obj.</param>
public virtual void VisitPostOrder(T obj)
{
_visitorToUse.Visit(obj);
}
/// <summary>
/// Visits the object in order.
/// </summary>
/// <param name="obj">The obj.</param>
public virtual void VisitInOrder(T obj)
{
_visitorToUse.Visit(obj);
}
/// <inheritdoc />
public void Visit(T obj)
{
_visitorToUse.Visit(obj);
}
#endregion
#region Public Members
/// <summary>
/// Gets the visitor to use.
/// </summary>
/// <value>The visitor to use.</value>
public IVisitor<T> VisitorToUse => _visitorToUse;
#endregion
}
}

65
src/NGenerics/Patterns/Visitor/TrackingVisitor.cs

@ -1,65 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System.Collections.Generic;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that tracks (stores) objects in the order they were visited.
/// Handy for demonstrating and testing different ordered visits implementations on
/// data structures.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public sealed class TrackingVisitor<T> : IVisitor<T>
{
#region Globals
private readonly List<T> _tracks;
#endregion
#region Construction
/// <inheritdoc/>
public TrackingVisitor()
{
_tracks = new List<T>();
}
#endregion
#region IVisitor<T> Members
/// <inheritdoc />
public void Visit(T obj)
{
_tracks.Add(obj);
}
/// <inheritdoc />
public bool HasCompleted => false;
#endregion
#region Public Members
/// <summary>
/// Gets the tracking list.
/// </summary>
/// <value>The tracking list.</value>
public IList<T> TrackingList => _tracks;
#endregion
}
}

66
src/NGenerics/Patterns/Visitor/ValueTrackingVisitor.cs

@ -1,66 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System.Collections.Generic;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that tracks (stores) keys from KeyValuePairs in the order they were visited.
/// </summary>
/// <typeparam name="TKey">The type of key of the KeyValuePair.</typeparam>
/// <typeparam name="TValue">The type of value of the KeyValuePair.</typeparam>
public sealed class ValueTrackingVisitor<TKey, TValue> : IVisitor<KeyValuePair<TKey, TValue>>
{
#region Globals
private readonly List<TValue> _tracks;
#endregion
#region Construction
/// <inheritdoc/>
public ValueTrackingVisitor()
{
_tracks = new List<TValue>();
}
#endregion
#region Public Members
/// <summary>
/// Gets the tracking list.
/// </summary>
/// <value>The tracking list.</value>
public IList<TValue> TrackingList => _tracks;
#endregion
#region IVisitor<KeyValuePair<TKey,TValue>> Members
/// <inheritdoc />
public void Visit(KeyValuePair<TKey, TValue> obj)
{
_tracks.Add(obj.Value);
}
/// <inheritdoc />
public bool HasCompleted => false;
#endregion
}
}

33
src/NGenerics/Properties/AssemblyInfo.cs

@ -1,33 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("NGenerics")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NGenerics")]
[assembly: AssemblyCopyright("Copyright \u00A9 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

59
src/NGenerics/Util/Guard.cs

@ -1,59 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
namespace NGenerics.Util
{
/// <summary>
/// Performs common argument validation.
/// </summary>
public static class Guard
{
#region Methods
/// <summary>
/// Checks a string argument to ensure it isn't null or empty.
/// </summary>
/// <param name="argumentValue">The argument value to check.</param>
/// <param name="argumentName">The name of the argument.</param>
/// <exception cref="ArgumentNullException"><paramref name="argumentValue"/> is a null reference.</exception>
/// <exception cref="ArgumentException"><paramref name="argumentValue"/> is <see cref="string.Empty"/>.</exception>
public static void ArgumentNotNullOrEmptyString(string argumentValue, string argumentName)
{
ArgumentNotNull(argumentValue, argumentName);
if (argumentValue.Length == 0)
{
throw new ArgumentException("String cannot be empty.", argumentName);
}
}
/// <summary>
/// Checks an argument to ensure it isn't null.
/// </summary>
/// <param name="argumentValue">The argument value to check.</param>
/// <param name="argumentName">The name of the argument.</param>
/// <exception cref="ArgumentNullException"><paramref name="argumentValue"/> is a null reference.</exception>
public static void ArgumentNotNull(object argumentValue, string argumentName)
{
if (argumentValue == null)
{
throw new ArgumentNullException(argumentName);
}
}
#endregion
}
}

22
src/Perspex.Application/Application.cs

@ -12,7 +12,6 @@ using Perspex.Layout;
using Perspex.Rendering;
using Perspex.Styling;
using Perspex.Threading;
using Splat;
namespace Perspex
{
@ -40,7 +39,7 @@ namespace Perspex
private DataTemplates _dataTemplates;
private readonly Lazy<IClipboard> _clipboard =
new Lazy<IClipboard>(() => (IClipboard)Locator.Current.GetService(typeof(IClipboard)));
new Lazy<IClipboard>(() => (IClipboard)PerspexLocator.Current.GetService(typeof(IClipboard)));
/// <summary>
/// The styler that will be used to apply styles to controls.
@ -157,15 +156,16 @@ namespace Perspex
FocusManager = new FocusManager();
InputManager = new InputManager();
Locator.CurrentMutable.Register(() => new AccessKeyHandler(), typeof(IAccessKeyHandler));
Locator.CurrentMutable.Register(() => this, typeof(IGlobalDataTemplates));
Locator.CurrentMutable.Register(() => this, typeof(IGlobalStyles));
Locator.CurrentMutable.Register(() => FocusManager, typeof(IFocusManager));
Locator.CurrentMutable.Register(() => InputManager, typeof(IInputManager));
Locator.CurrentMutable.Register(() => new KeyboardNavigationHandler(), typeof(IKeyboardNavigationHandler));
Locator.CurrentMutable.Register(() => _styler, typeof(IStyler));
Locator.CurrentMutable.Register(() => new LayoutManager(), typeof(ILayoutManager));
Locator.CurrentMutable.Register(() => new RenderManager(), typeof(IRenderManager));
PerspexLocator.CurrentMutable
.Bind<IAccessKeyHandler>().ToTransient<AccessKeyHandler>()
.Bind<IGlobalDataTemplates>().ToConstant(this)
.Bind<IGlobalStyles>().ToConstant(this)
.Bind<IFocusManager>().ToConstant(FocusManager)
.Bind<IInputManager>().ToConstant(InputManager)
.Bind<IKeyboardNavigationHandler>().ToTransient<KeyboardNavigationHandler>()
.Bind<IStyler>().ToConstant(_styler)
.Bind<ILayoutManager>().ToTransient<LayoutManager>()
.Bind<IRenderManager>().ToTransient<RenderManager>();
}
/// <summary>

3
src/Perspex.Application/Perspex.Application.csproj

@ -89,9 +89,6 @@
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

7
src/Perspex.Application/Platform/IAssetLoader.cs

@ -11,6 +11,13 @@ namespace Perspex.Platform
/// </summary>
public interface IAssetLoader
{
/// <summary>
/// Checks if an asset with the specified URI exists.
/// </summary>
/// <param name="uri">The URI.</param>
/// <returns>True if the asset could be found; otherwise false.</returns>
bool Exists(Uri uri);
/// <summary>
/// Opens the resource with the requested URI.
/// </summary>

1
src/Perspex.Application/packages.config

@ -5,5 +5,4 @@
<package id="Rx-Linq" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-Main" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

10
src/Perspex.Base/Perspex.Base.csproj

@ -46,6 +46,7 @@
<Compile Include="Diagnostics\PerspexObjectExtensions.cs" />
<Compile Include="IObservablePropertyBag.cs" />
<Compile Include="IPropertyBag.cs" />
<Compile Include="PerspexLocator.cs" />
<Compile Include="Metadata\XmlnsDefinitionAttribute.cs" />
<Compile Include="PerspexObjectExtensions.cs" />
<Compile Include="PerspexProperty`1.cs" />
@ -93,20 +94,11 @@
<Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10">
<HintPath>..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

120
src/Perspex.Base/PerspexLocator.cs

@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
#pragma warning disable CS1591 // Enable me later
namespace Perspex
{
public class PerspexLocator : IPerspexDependencyResolver
{
private readonly IPerspexDependencyResolver _parentScope;
public static IPerspexDependencyResolver Current { get; set; }
public static PerspexLocator CurrentMutable { get; set; }
private readonly Dictionary<Type, Func<object>> _registry = new Dictionary<Type, Func<object>>();
static PerspexLocator()
{
Current = CurrentMutable = new PerspexLocator();
}
public PerspexLocator()
{
}
public PerspexLocator(IPerspexDependencyResolver parentScope)
{
_parentScope = parentScope;
}
public object GetService(Type t)
{
Func<object> rv;
return _registry.TryGetValue(t, out rv) ? rv() : _parentScope?.GetService(t);
}
public class RegistrationHelper<TService>
{
private PerspexLocator _locator;
public RegistrationHelper(PerspexLocator locator)
{
_locator = locator;
}
public PerspexLocator ToConstant<TImpl>(TImpl constant) where TImpl : TService
{
_locator._registry[typeof (TService)] = () => constant;
return _locator;
}
public PerspexLocator ToFunc<TImlp>(Func<TImlp> func) where TImlp : TService
{
_locator._registry[typeof (TService)] = () => func();
return _locator;
}
public PerspexLocator ToSingleton<TImpl>() where TImpl : class, TService, new()
{
TImpl instance = null;
return ToFunc(() => instance ?? (instance = new TImpl()));
}
public PerspexLocator ToTransient<TImpl>() where TImpl : class, TService, new() => ToFunc(() => new TImpl());
}
public RegistrationHelper<T> Bind<T>() => new RegistrationHelper<T>(this);
public PerspexLocator BindToSelf<T>(T constant)
=> Bind<T>().ToConstant(constant);
public PerspexLocator BindToSelfSingleton<T>() where T : class, new() => Bind<T>().ToSingleton<T>();
class ResolverDisposable : IDisposable
{
private readonly IPerspexDependencyResolver _resolver;
private readonly PerspexLocator _mutable;
public ResolverDisposable(IPerspexDependencyResolver resolver, PerspexLocator mutable)
{
_resolver = resolver;
_mutable = mutable;
}
public void Dispose()
{
Current = _resolver;
CurrentMutable = _mutable;
}
}
public static IDisposable EnterScope()
{
return Disposable.Empty;
//Switch to that code when we are ready to fix tests
/*
var d = new ResolverDisposable(Current, CurrentMutable);
Current = CurrentMutable = new PerspexLocator(Current);
return d;
*/
}
}
public interface IPerspexDependencyResolver
{
object GetService(Type t);
}
public static class LocatorExtensions
{
public static T GetService<T>(this IPerspexDependencyResolver resolver)
{
return (T) resolver.GetService(typeof (T));
}
}
}

5
src/Perspex.Base/Threading/DispatcherTimer.cs

@ -4,7 +4,6 @@
using System;
using System.Reactive.Disposables;
using Perspex.Platform;
using Splat;
namespace Perspex.Threading
{
@ -175,7 +174,7 @@ namespace Perspex.Threading
{
if (!IsEnabled)
{
IPlatformThreadingInterface threading = Locator.Current.GetService<IPlatformThreadingInterface>();
IPlatformThreadingInterface threading = PerspexLocator.Current.GetService<IPlatformThreadingInterface>();
_timer = threading.StartTimer(Interval, InternalTick);
}
}
@ -187,7 +186,7 @@ namespace Perspex.Threading
{
if (IsEnabled)
{
IPlatformThreadingInterface threading = Locator.Current.GetService<IPlatformThreadingInterface>();
IPlatformThreadingInterface threading = PerspexLocator.Current.GetService<IPlatformThreadingInterface>();
_timer.Dispose();
_timer = null;
}

11
src/Perspex.Base/Threading/MainLoop.cs

@ -2,12 +2,11 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using NGenerics.DataStructures.Queues;
using Perspex.Platform;
using Perspex.Threading;
using Splat;
namespace Perspex.Win32.Threading
{
@ -18,15 +17,14 @@ namespace Perspex.Win32.Threading
{
private static readonly IPlatformThreadingInterface s_platform;
private readonly PriorityQueue<Job, DispatcherPriority> _queue =
new PriorityQueue<Job, DispatcherPriority>(PriorityQueueType.Maximum);
private readonly Queue<Job> _queue = new Queue<Job>();
/// <summary>
/// Initializes static members of the <see cref="MainLoop"/> class.
/// </summary>
static MainLoop()
{
s_platform = Locator.Current.GetService<IPlatformThreadingInterface>();
s_platform = PerspexLocator.Current.GetService<IPlatformThreadingInterface>();
}
/// <summary>
@ -109,6 +107,7 @@ namespace Perspex.Win32.Threading
/// <param name="priority">The priority with which to invoke the method.</param>
internal void Post(Action action, DispatcherPriority priority)
{
// TODO: Respect priority.
AddJob(new Job(action, priority, true));
}
@ -116,7 +115,7 @@ namespace Perspex.Win32.Threading
{
lock (_queue)
{
_queue.Add(job, job.Priority);
_queue.Enqueue(job);
}
s_platform.Wake();
}

1
src/Perspex.Base/packages.config

@ -6,5 +6,4 @@
<package id="Rx-Main" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Serilog" version="1.5.9" targetFramework="portable45-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

3
src/Perspex.Controls/Control.cs

@ -12,7 +12,6 @@ using Perspex.Interactivity;
using Perspex.LogicalTree;
using Perspex.Rendering;
using Perspex.Styling;
using Splat;
namespace Perspex.Controls
{
@ -397,7 +396,7 @@ namespace Perspex.Controls
{
base.OnAttachedToVisualTree(root);
IStyler styler = Locator.Current.GetService<IStyler>();
IStyler styler = PerspexLocator.Current.GetService<IStyler>();
styler.ApplyStyles(this);
}

18
src/Perspex.Controls/MenuItem.cs

@ -14,7 +14,6 @@ using Perspex.Input;
using Perspex.Interactivity;
using Perspex.Threading;
using Perspex.VisualTree;
using Splat;
namespace Perspex.Controls
{
@ -489,7 +488,7 @@ namespace Perspex.Controls
/// <summary>
/// A dependency resolver which returns a <see cref="MenuItemAccessKeyHandler"/>.
/// </summary>
private class DependencyResolver : IDependencyResolver
private class DependencyResolver : IPerspexDependencyResolver
{
/// <summary>
/// Gets the default instance of <see cref="DependencyResolver"/>.
@ -509,7 +508,7 @@ namespace Perspex.Controls
/// <param name="serviceType">The service type.</param>
/// <param name="contract">An optional contract.</param>
/// <returns>A service of the requested type.</returns>
public object GetService(Type serviceType, string contract = null)
public object GetService(Type serviceType)
{
if (serviceType == typeof(IAccessKeyHandler))
{
@ -517,20 +516,9 @@ namespace Perspex.Controls
}
else
{
return Locator.Current.GetService(serviceType, contract);
return PerspexLocator.Current.GetService(serviceType);
}
}
/// <summary>
/// Gets collection of services of the specified type.
/// </summary>
/// <param name="serviceType">The service type.</param>
/// <param name="contract">An optional contract.</param>
/// <returns>A collection of services of the requested type.</returns>
public IEnumerable<object> GetServices(Type serviceType, string contract = null)
{
return Locator.Current.GetServices(serviceType, contract);
}
}
}
}

16
src/Perspex.Controls/Perspex.Controls.csproj

@ -42,6 +42,18 @@
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="DockPanel.cs" />
<Compile Include="SystemDialog.cs" />
<Compile Include="DockPanel\Aligner.cs" />
<Compile Include="DockPanel\Alignment.cs" />
<Compile Include="DockPanel\Alignments.cs" />
<Compile Include="DockPanel\CoordinateMixin.cs" />
<Compile Include="DockPanel\Dock.cs" />
<Compile Include="DockPanel\Docker.cs" />
<Compile Include="DockPanel\DockingArranger.cs" />
<Compile Include="DockPanel\DockPanel.cs" />
<Compile Include="DockPanel\EnumerableMixin.cs" />
<Compile Include="DockPanel\LayoutSizes.cs" />
<Compile Include="DockPanel\RectMixin.cs" />
<Compile Include="Generators\ITreeItemContainerGenerator.cs" />
<Compile Include="Generators\ItemContainers.cs" />
<Compile Include="IContentControl.cs" />
@ -51,6 +63,7 @@
<Compile Include="ISetLogicalParent.cs" />
<Compile Include="MenuItemAccessKeyHandler.cs" />
<Compile Include="Mixins\SelectableMixin.cs" />
<Compile Include="Platform\ISystemDialogImpl.cs" />
<Compile Include="Presenters\IContentPresenter.cs" />
<Compile Include="Primitives\AccessText.cs" />
<Compile Include="Border.cs" />
@ -171,9 +184,6 @@
<Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10">
<HintPath>..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

14
src/Perspex.Controls/Platform/ISystemDialogImpl.cs

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Platform;
namespace Perspex.Controls.Platform
{
public interface ISystemDialogImpl
{
Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent);
}
}

13
src/Perspex.Controls/Presenters/TextPresenter.cs

@ -93,8 +93,19 @@ namespace Perspex.Controls.Presenters
if (selectionStart == selectionEnd)
{
var charPos = FormattedText.HitTestTextPosition(CaretIndex);
Brush caretBrush = Brushes.Black;
var backgroundColor = (((Control)TemplatedParent).GetValue(BackgroundProperty) as SolidColorBrush)?.Color;
var caretBrush = Brushes.Black;
if(backgroundColor.HasValue)
{
byte red = (byte)~(backgroundColor.Value.R);
byte green = (byte)~(backgroundColor.Value.G);
byte blue = (byte)~(backgroundColor.Value.B);
caretBrush = new SolidColorBrush(Color.FromRgb(red, green, blue));
}
if (_caretBlink)
{
var x = Math.Floor(charPos.X) + 0.5;

3
src/Perspex.Controls/Primitives/Popup.cs

@ -5,7 +5,6 @@ using System;
using Perspex.Interactivity;
using Perspex.Rendering;
using Perspex.VisualTree;
using Splat;
namespace Perspex.Controls.Primitives
{
@ -94,7 +93,7 @@ namespace Perspex.Controls.Primitives
/// This property allows a client to customize the behaviour of the popup by injecting
/// a specialized dependency resolver into the <see cref="PopupRoot"/>'s constructor.
/// </remarks>
public IDependencyResolver DependencyResolver
public IPerspexDependencyResolver DependencyResolver
{
get;
set;

5
src/Perspex.Controls/Primitives/PopupRoot.cs

@ -8,7 +8,6 @@ using Perspex.Interactivity;
using Perspex.Media;
using Perspex.Platform;
using Perspex.VisualTree;
using Splat;
namespace Perspex.Controls.Primitives
{
@ -41,8 +40,8 @@ namespace Perspex.Controls.Primitives
/// <param name="dependencyResolver">
/// The dependency resolver to use. If null the default dependency resolver will be used.
/// </param>
public PopupRoot(IDependencyResolver dependencyResolver)
: base(Locator.Current.GetService<IPopupImpl>(), dependencyResolver)
public PopupRoot(IPerspexDependencyResolver dependencyResolver)
: base(PerspexLocator.Current.GetService<IPopupImpl>(), dependencyResolver)
{
GetObservable(ParentProperty).Subscribe(x => InheritanceParent = (PerspexObject)x);
}

44
src/Perspex.Controls/SystemDialog.cs

@ -0,0 +1,44 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Perspex.Controls.Platform;
namespace Perspex.Controls
{
public abstract class FileDialog : SystemDialog
{
public List<FileDialogFilter> Filters { get; set; } = new List<FileDialogFilter>();
public string InitialFileName { get; set; }
public string InitialDirectory { get; set; }
}
public class SaveFileDialog : FileDialog
{
public string DefaultExtension { get; set; }
public async Task<string> ShowAsync(Window window = null)
=>
((await PerspexLocator.Current.GetService<ISystemDialogImpl>().ShowFileDialogAsync(this, window?.PlatformImpl)) ??
new string[0]).FirstOrDefault();
}
public class OpenFileDialog : FileDialog
{
public bool AllowMultiple { get; set; }
public Task<string[]> ShowAsync(Window window = null)
=> PerspexLocator.Current.GetService<ISystemDialogImpl>().ShowFileDialogAsync(this, window?.PlatformImpl);
}
public abstract class SystemDialog
{
public string Title { get; set; }
}
public class FileDialogFilter
{
public string Name { get; set; }
public List<string> Extensions { get; set; } = new List<string>();
}
}

3
src/Perspex.Controls/Templates/DataTemplateExtensions.cs

@ -3,7 +3,6 @@
using System.Linq;
using Perspex.LogicalTree;
using Splat;
namespace Perspex.Controls.Templates
{
@ -63,7 +62,7 @@ namespace Perspex.Controls.Templates
}
}
IGlobalDataTemplates global = Locator.Current.GetService<IGlobalDataTemplates>();
IGlobalDataTemplates global = PerspexLocator.Current.GetService<IGlobalDataTemplates>();
if (global != null)
{

5
src/Perspex.Controls/TextBox.cs

@ -2,7 +2,6 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Perspex.Input.Platform;
using Splat;
using System;
using System.Collections.Generic;
using System.Linq;
@ -150,13 +149,13 @@ namespace Perspex.Controls
private async void Copy()
{
await ((IClipboard)Locator.Current.GetService(typeof(IClipboard)))
await ((IClipboard)PerspexLocator.Current.GetService(typeof(IClipboard)))
.SetTextAsync(GetSelection());
}
private async void Paste()
{
var text = await ((IClipboard)Locator.Current.GetService(typeof(IClipboard))).GetTextAsync();
var text = await ((IClipboard)PerspexLocator.Current.GetService(typeof(IClipboard))).GetTextAsync();
if (text == null)
{
return;

11
src/Perspex.Controls/TopLevel.cs

@ -12,7 +12,6 @@ using Perspex.Platform;
using Perspex.Rendering;
using Perspex.Styling;
using Perspex.Threading;
using Splat;
namespace Perspex.Controls
{
@ -87,7 +86,7 @@ namespace Perspex.Controls
/// </summary>
/// <param name="impl">The platform-specific window implementation.</param>
public TopLevel(ITopLevelImpl impl)
: this(impl, Locator.Current)
: this(impl, PerspexLocator.Current)
{
}
@ -98,7 +97,7 @@ namespace Perspex.Controls
/// <param name="dependencyResolver">
/// The dependency resolver to use. If null the default dependency resolver will be used.
/// </param>
public TopLevel(ITopLevelImpl impl, IDependencyResolver dependencyResolver)
public TopLevel(ITopLevelImpl impl, IPerspexDependencyResolver dependencyResolver)
{
if (impl == null)
{
@ -108,7 +107,7 @@ namespace Perspex.Controls
PlatformImpl = impl;
dependencyResolver = dependencyResolver ?? Locator.Current;
dependencyResolver = dependencyResolver ?? PerspexLocator.Current;
var renderInterface = TryGetService<IPlatformRenderInterface>(dependencyResolver);
var styler = TryGetService<IStyler>(dependencyResolver);
_accessKeyHandler = TryGetService<IAccessKeyHandler>(dependencyResolver);
@ -327,13 +326,13 @@ namespace Perspex.Controls
}
/// <summary>
/// Tries to get a service from an <see cref="IDependencyResolver"/>, throwing an
/// Tries to get a service from an <see cref="IPerspexDependencyResolver"/>, throwing an
/// exception if not found.
/// </summary>
/// <typeparam name="T">The service type.</typeparam>
/// <param name="resolver">The resolver.</param>
/// <returns>The service.</returns>
private static T TryGetService<T>(IDependencyResolver resolver) where T : class
private static T TryGetService<T>(IPerspexDependencyResolver resolver) where T : class
{
var result = resolver.GetService<T>();

3
src/Perspex.Controls/Window.cs

@ -8,7 +8,6 @@ using Perspex.Input;
using Perspex.Media;
using Perspex.Platform;
using Perspex.Styling;
using Splat;
namespace Perspex.Controls
{
@ -72,7 +71,7 @@ namespace Perspex.Controls
/// Initializes a new instance of the <see cref="Window"/> class.
/// </summary>
public Window()
: base(Locator.Current.GetService<IWindowImpl>())
: base(PerspexLocator.Current.GetService<IWindowImpl>())
{
_maxPlatformClientSize = this.PlatformImpl.MaxClientSize;
}

1
src/Perspex.Controls/packages.config

@ -6,5 +6,4 @@
<package id="Rx-Main" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Serilog" version="1.5.9" targetFramework="portable45-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

3
src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs

@ -9,7 +9,6 @@ using Perspex;
using Perspex.Input.Platform;
using Perspex.Media;
using Perspex.Media.Imaging;
using Splat;
using TheArtOfDev.HtmlRenderer.Adapters;
using TheArtOfDev.HtmlRenderer.Adapters.Entities;
using TheArtOfDev.HtmlRenderer.Perspex.Utilities;
@ -118,7 +117,7 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters
protected override void SetToClipboardInt(string text)
{
Locator.Current.GetService<IClipboard>().SetTextAsync(text);
PerspexLocator.Current.GetService<IClipboard>().SetTextAsync(text);
}
protected override void SetToClipboardInt(RImage image)

3
src/Perspex.HtmlRenderer/Perspex.HtmlRenderer.csproj

@ -172,9 +172,6 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Splat">
<HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll</HintPath>
</Reference>

1
src/Perspex.HtmlRenderer/packages.config

@ -4,5 +4,4 @@
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="portable45-net45+win8" />
<package id="Rx-Core" version="2.2.5" targetFramework="portable45-net45+win8" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="portable45-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

3
src/Perspex.Input/Cursors.cs

@ -1,7 +1,6 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Splat;
using System;
using System.Collections.Generic;
using System.Linq;
@ -50,7 +49,7 @@ namespace Perspex.Input
public Cursor(StandardCursorType cursorType)
: this(
((IStandardCursorFactory)Locator.Current.GetService(typeof(IStandardCursorFactory))).GetCursor(
((IStandardCursorFactory)PerspexLocator.Current.GetService(typeof(IStandardCursorFactory))).GetCursor(
cursorType))
{
}

3
src/Perspex.Input/FocusManager.cs

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Linq;
using Perspex.Interactivity;
using Perspex.VisualTree;
using Splat;
namespace Perspex.Input
{
@ -35,7 +34,7 @@ namespace Perspex.Input
/// <summary>
/// Gets the instance of the <see cref="IFocusManager"/>.
/// </summary>
public static IFocusManager Instance => Locator.Current.GetService<IFocusManager>();
public static IFocusManager Instance => PerspexLocator.Current.GetService<IFocusManager>();
/// <summary>
/// Gets the currently focused <see cref="IInputElement"/>.

3
src/Perspex.Input/InputManager.cs

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Reactive.Subjects;
using Perspex.Input.Raw;
using Splat;
namespace Perspex.Input
{
@ -16,7 +15,7 @@ namespace Perspex.Input
private readonly Subject<RawInputEventArgs> _postProcess = new Subject<RawInputEventArgs>();
public static IInputManager Instance => Locator.Current.GetService<IInputManager>();
public static IInputManager Instance => PerspexLocator.Current.GetService<IInputManager>();
public IObservable<RawInputEventArgs> RawEventReceived => _rawEventReceived;

7
src/Perspex.Input/KeyboardDevice.cs

@ -8,7 +8,6 @@ using System.Reactive.Linq;
using System.Runtime.CompilerServices;
using Perspex.Input.Raw;
using Perspex.Interactivity;
using Splat;
namespace Perspex.Input
{
@ -26,11 +25,11 @@ namespace Perspex.Input
public event PropertyChangedEventHandler PropertyChanged;
public static IKeyboardDevice Instance => Locator.Current.GetService<IKeyboardDevice>();
public static IKeyboardDevice Instance => PerspexLocator.Current.GetService<IKeyboardDevice>();
public IInputManager InputManager => Locator.Current.GetService<IInputManager>();
public IInputManager InputManager => PerspexLocator.Current.GetService<IInputManager>();
public IFocusManager FocusManager => Locator.Current.GetService<IFocusManager>();
public IFocusManager FocusManager => PerspexLocator.Current.GetService<IFocusManager>();
public IInputElement FocusedElement
{

9
src/Perspex.Input/MouseDevice.cs

@ -9,7 +9,6 @@ using Perspex.Input.Raw;
using Perspex.Interactivity;
using Perspex.Platform;
using Perspex.VisualTree;
using Splat;
namespace Perspex.Input
{
@ -31,7 +30,7 @@ namespace Perspex.Input
.Subscribe(ProcessRawEvent);
}
public static IMouseDevice Instance => Locator.Current.GetService<IMouseDevice>();
public static IMouseDevice Instance => PerspexLocator.Current.GetService<IMouseDevice>();
public IInputElement Captured
{
@ -39,7 +38,7 @@ namespace Perspex.Input
protected set;
}
public IInputManager InputManager => Locator.Current.GetService<IInputManager>();
public IInputManager InputManager => PerspexLocator.Current.GetService<IInputManager>();
public Point Position
{
@ -107,7 +106,7 @@ namespace Perspex.Input
if (source != null)
{
var settings = Locator.Current.GetService<IPlatformSettings>();
var settings = PerspexLocator.Current.GetService<IPlatformSettings>();
var doubleClickTime = settings.DoubleClickTime.TotalMilliseconds;
if (!_lastClickRect.Contains(p) || timestamp - _lastClickTime > doubleClickTime)
@ -261,7 +260,7 @@ namespace Perspex.Input
control.RaiseEvent(e);
}
root.PointerOverElement = elements.FirstOrDefault();
root.PointerOverElement = elements.FirstOrDefault() ?? root;
return root.PointerOverElement;
}
}

3
src/Perspex.Input/Perspex.Input.csproj

@ -126,9 +126,6 @@
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

1
src/Perspex.Input/packages.config

@ -5,5 +5,4 @@
<package id="Rx-Linq" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-Main" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

3
src/Perspex.Interactivity/Perspex.Interactivity.csproj

@ -81,9 +81,6 @@
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

1
src/Perspex.Interactivity/packages.config

@ -5,5 +5,4 @@
<package id="Rx-Linq" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-Main" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

16
src/Perspex.Layout/LayoutManager.cs

@ -2,10 +2,10 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using NGenerics.DataStructures.General;
using Perspex.VisualTree;
using Serilog;
using Serilog.Core.Enrichers;
@ -44,14 +44,14 @@ namespace Perspex.Layout
private bool _measureNeeded = true;
/// <summary>
/// The controls that need to be measured, sorted by distance to layout root.
/// The controls that need to be measured.
/// </summary>
private Heap<Item> _toMeasure = new Heap<Item>(HeapType.Minimum);
private List<Item> _toMeasure = new List<Item>();
/// <summary>
/// The controls that need to be arranged, sorted by distance to layout root.
/// The controls that need to be arranged.
/// </summary>
private Heap<Item> _toArrange = new Heap<Item>(HeapType.Minimum);
private List<Item> _toArrange = new List<Item>();
/// <summary>
/// Prevents re-entrancy.
@ -207,7 +207,8 @@ namespace Perspex.Layout
{
var measure = _toMeasure;
_toMeasure = new Heap<Item>(HeapType.Minimum);
_toMeasure = new List<Item>();
measure.Sort();
if (!Root.IsMeasureValid)
{
@ -254,7 +255,8 @@ namespace Perspex.Layout
{
var arrange = _toArrange;
_toArrange = new Heap<Item>(HeapType.Minimum);
_toArrange = new List<Item>();
arrange.Sort();
if (!Root.IsArrangeValid && Root.IsMeasureValid)
{

7
src/Perspex.Layout/Perspex.Layout.csproj

@ -39,10 +39,6 @@
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Animation\Perspex.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Perspex.Animation</Name>
@ -84,9 +80,6 @@
<Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10">
<HintPath>..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

1
src/Perspex.Layout/packages.config

@ -6,5 +6,4 @@
<package id="Rx-Main" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Serilog" version="1.5.9" targetFramework="portable45-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

3
src/Perspex.SceneGraph/Media/EllipseGeometry.cs

@ -3,7 +3,6 @@
using System;
using Perspex.Platform;
using Splat;
namespace Perspex.Media
{
@ -18,7 +17,7 @@ namespace Perspex.Media
/// <param name="rect">The rectangle that the ellipse should fill.</param>
public EllipseGeometry(Rect rect)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
IStreamGeometryImpl impl = factory.CreateStreamGeometry();
using (IStreamGeometryContextImpl ctx = impl.Open())

3
src/Perspex.SceneGraph/Media/FormattedText.cs

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using Perspex.Platform;
using Splat;
namespace Perspex.Media
{
@ -37,7 +36,7 @@ namespace Perspex.Media
FontWeight = fontWeight;
TextAlignment = textAlignment;
var platform = Locator.Current.GetService<IPlatformRenderInterface>();
var platform = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
PlatformImpl = platform.CreateFormattedText(
text,

7
src/Perspex.SceneGraph/Media/Imaging/Bitmap.cs

@ -3,7 +3,6 @@
using System.IO;
using Perspex.Platform;
using Splat;
namespace Perspex.Media.Imaging
{
@ -18,7 +17,7 @@ namespace Perspex.Media.Imaging
/// <param name="fileName">The filename of the bitmap.</param>
public Bitmap(string fileName)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
PlatformImpl = factory.LoadBitmap(fileName);
}
@ -28,7 +27,7 @@ namespace Perspex.Media.Imaging
/// <param name="stream">The stream to read the bitmap from.</param>
public Bitmap(Stream stream)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
PlatformImpl = factory.LoadBitmap(stream);
}
@ -39,7 +38,7 @@ namespace Perspex.Media.Imaging
/// <param name="height">The height of the bitmap, in pixels.</param>
public Bitmap(int width, int height)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
PlatformImpl = factory.CreateBitmap(width, height);
}

3
src/Perspex.SceneGraph/Media/Imaging/RenderTargetBitmap.cs

@ -3,7 +3,6 @@
using System;
using Perspex.Platform;
using Splat;
namespace Perspex.Media.Imaging
{
@ -55,7 +54,7 @@ namespace Perspex.Media.Imaging
/// <returns>The platform-specific implementation.</returns>
private static IBitmapImpl CreateImpl(int width, int height)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
return factory.CreateRenderTargetBitmap(width, height);
}
}

3
src/Perspex.SceneGraph/Media/RectangleGeometry.cs

@ -2,7 +2,6 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Perspex.Platform;
using Splat;
namespace Perspex.Media
{
@ -17,7 +16,7 @@ namespace Perspex.Media
/// <param name="rect">The rectangle bounds.</param>
public RectangleGeometry(Rect rect)
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
IStreamGeometryImpl impl = factory.CreateStreamGeometry();
using (IStreamGeometryContextImpl context = impl.Open())

3
src/Perspex.SceneGraph/Media/StreamGeometry.cs

@ -2,7 +2,6 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Perspex.Platform;
using Splat;
namespace Perspex.Media
{
@ -16,7 +15,7 @@ namespace Perspex.Media
/// </summary>
public StreamGeometry()
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>();
PlatformImpl = factory.CreateStreamGeometry();
}

3
src/Perspex.SceneGraph/Perspex.SceneGraph.csproj

@ -143,9 +143,6 @@
<Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10">
<HintPath>..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

1
src/Perspex.SceneGraph/packages.config

@ -6,5 +6,4 @@
<package id="Rx-Main" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable-net45+win8" />
<package id="Serilog" version="1.5.9" targetFramework="portable45-net45+win8" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8" />
</packages>

3
src/Perspex.Styling/Perspex.Styling.csproj

@ -77,9 +77,6 @@
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

3
src/Perspex.Styling/Styling/Styler.cs

@ -4,7 +4,6 @@
using System;
using System.Linq;
using Perspex.VisualTree;
using Splat;
namespace Perspex.Styling
{
@ -17,7 +16,7 @@ namespace Perspex.Styling
.GetSelfAndVisualAncestors()
.OfType<IStyleHost>()
.FirstOrDefault();
IGlobalStyles global = Locator.Current.GetService<IGlobalStyles>();
IGlobalStyles global = PerspexLocator.Current.GetService<IGlobalStyles>();
if (global != null)
{

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save