Skip to content

Commit

Permalink
Merge branch 'styling-perf'
Browse files Browse the repository at this point in the history
  • Loading branch information
grokys committed Mar 7, 2016
2 parents b3d9be3 + b46d91e commit a35f800
Show file tree
Hide file tree
Showing 35 changed files with 1,025 additions and 354 deletions.
27 changes: 27 additions & 0 deletions Perspex.sln
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog", "samples\C
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.UnitTests", "tests\Perspex.UnitTests\Perspex.UnitTests.csproj", "{88060192-33D5-4932-B0F9-8BD2763E857D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Benchmarks", "tests\Perspex.Benchmarks\Perspex.Benchmarks.csproj", "{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{fb05ac90-89ba-4f2f-a924-f37875fb547c}*SharedItemsImports = 4
Expand Down Expand Up @@ -1295,6 +1297,30 @@ Global
{88060192-33D5-4932-B0F9-8BD2763E857D}.Release|iPhone.Build.0 = Release|Any CPU
{88060192-33D5-4932-B0F9-8BD2763E857D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{88060192-33D5-4932-B0F9-8BD2763E857D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.AppStore|Any CPU.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.AppStore|iPhone.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Debug|iPhone.Build.0 = Debug|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|Any CPU.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|iPhone.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|iPhone.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1339,5 +1365,6 @@ Global
{E1AA3DBF-9056-4530-9376-18119A7A3FFE} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{61BEC86C-F307-4295-B5B8-9428610D7D55} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{88060192-33D5-4932-B0F9-8BD2763E857D} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
EndGlobalSection
EndGlobal
2 changes: 1 addition & 1 deletion src/Markup/Perspex.Markup.Xaml/Parsers/SelectorParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public SelectorParser(Func<string, string, Type> typeResolver)
public Selector Parse(string s)
{
var syntax = SelectorGrammar.Selector.Parse(s);
var result = new Selector();
var result = default(Selector);

foreach (var i in syntax)
{
Expand Down
14 changes: 9 additions & 5 deletions src/Perspex.Base/PerspexProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public class PerspexProperty : IEquatable<PerspexProperty>
public static readonly object UnsetValue = new Unset();

private static int s_nextId = 1;
private readonly int _id;
private readonly Subject<PerspexPropertyChangedEventArgs> _initialized;
private readonly Subject<PerspexPropertyChangedEventArgs> _changed;
private readonly PropertyMetadata _defaultMetadata;
Expand Down Expand Up @@ -61,7 +60,7 @@ protected PerspexProperty(
PropertyType = valueType;
OwnerType = ownerType;
Notifying = notifying;
_id = s_nextId++;
Id = s_nextId++;

_metadata.Add(ownerType, metadata);
_defaultMetadata = metadata;
Expand All @@ -85,7 +84,7 @@ protected PerspexProperty(PerspexProperty source, Type ownerType)
PropertyType = source.PropertyType;
OwnerType = ownerType;
Notifying = source.Notifying;
_id = source._id;
Id = source.Id;
_defaultMetadata = source._defaultMetadata;
}

Expand Down Expand Up @@ -164,6 +163,11 @@ protected PerspexProperty(PerspexProperty source, Type ownerType)
/// </remarks>
public Action<IPerspexObject, bool> Notifying { get; }

/// <summary>
/// Gets the integer ID that represents this property.
/// </summary>
internal int Id { get; }

/// <summary>
/// Provides access to a property's binding via the <see cref="PerspexObject"/>
/// indexer.
Expand Down Expand Up @@ -392,13 +396,13 @@ public override bool Equals(object obj)
/// <inheritdoc/>
public bool Equals(PerspexProperty other)
{
return other != null && _id == other._id;
return other != null && Id == other.Id;
}

/// <inheritdoc/>
public override int GetHashCode()
{
return _id;
return Id;
}

/// <summary>
Expand Down
54 changes: 27 additions & 27 deletions src/Perspex.Base/PerspexPropertyRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ public class PerspexPropertyRegistry
/// <summary>
/// The registered properties by type.
/// </summary>
private readonly Dictionary<Type, List<PerspexProperty>> _registered =
new Dictionary<Type, List<PerspexProperty>>();
private readonly Dictionary<Type, Dictionary<int, PerspexProperty>> _registered =
new Dictionary<Type, Dictionary<int, PerspexProperty>>();

/// <summary>
/// The registered attached properties by owner type.
/// </summary>
private readonly Dictionary<Type, List<PerspexProperty>> _attached =
new Dictionary<Type, List<PerspexProperty>>();
private readonly Dictionary<Type, Dictionary<int, PerspexProperty>> _attached =
new Dictionary<Type, Dictionary<int, PerspexProperty>>();

/// <summary>
/// Gets the <see cref="PerspexPropertyRegistry"/> instance
Expand All @@ -39,11 +39,11 @@ public class PerspexPropertyRegistry
/// <returns>A collection of <see cref="PerspexProperty"/> definitions.</returns>
public IEnumerable<PerspexProperty> GetAttached(Type ownerType)
{
List<PerspexProperty> list;
Dictionary<int, PerspexProperty> inner;

if (_attached.TryGetValue(ownerType, out list))
if (_attached.TryGetValue(ownerType, out inner))
{
return list;
return inner.Values;
}

return Enumerable.Empty<PerspexProperty>();
Expand All @@ -65,13 +65,13 @@ public IEnumerable<PerspexProperty> GetRegistered(Type type)
// Ensure the type's static ctor has been run.
RuntimeHelpers.RunClassConstructor(type.TypeHandle);

List<PerspexProperty> list;
Dictionary<int, PerspexProperty> inner;

if (_registered.TryGetValue(type, out list))
if (_registered.TryGetValue(type, out inner))
{
foreach (PerspexProperty p in list)
foreach (var p in inner)
{
yield return p;
yield return p.Value;
}
}

Expand Down Expand Up @@ -105,15 +105,15 @@ public PerspexProperty FindRegistered(Type type, PerspexProperty property)
{
while (type != null)
{
List<PerspexProperty> list;
Dictionary<int, PerspexProperty> inner;

if (_registered.TryGetValue(type, out list))
if (_registered.TryGetValue(type, out inner))
{
var index = list.IndexOf(property);
PerspexProperty result;

if (index != -1)
if (inner.TryGetValue(property.Id, out result))
{
return list[index];
return result;
}
}

Expand Down Expand Up @@ -250,30 +250,30 @@ public void Register(Type type, PerspexProperty property)
Contract.Requires<ArgumentNullException>(type != null);
Contract.Requires<ArgumentNullException>(property != null);

List<PerspexProperty> list;
Dictionary<int, PerspexProperty> inner;

if (!_registered.TryGetValue(type, out list))
if (!_registered.TryGetValue(type, out inner))
{
list = new List<PerspexProperty>();
_registered.Add(type, list);
inner = new Dictionary<int, PerspexProperty>();
_registered.Add(type, inner);
}

if (!list.Contains(property))
if (!inner.ContainsKey(property.Id))
{
list.Add(property);
inner.Add(property.Id, property);
}

if (property.IsAttached)
{
if (!_attached.TryGetValue(property.OwnerType, out list))
if (!_attached.TryGetValue(property.OwnerType, out inner))
{
list = new List<PerspexProperty>();
_attached.Add(property.OwnerType, list);
inner = new Dictionary<int, PerspexProperty>();
_attached.Add(property.OwnerType, inner);
}

if (!list.Contains(property))
if (!inner.ContainsKey(property.Id))
{
list.Add(property);
inner.Add(property.Id, property);
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/Perspex.Styling/Perspex.Styling.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Styling\ActivatedSubject.cs" />
<Compile Include="Styling\ActivatedValue.cs" />
<Compile Include="Styling\TemplateSelector.cs" />
<Compile Include="Styling\DescendentSelector.cs" />
<Compile Include="Styling\ChildSelector.cs" />
<Compile Include="Styling\IGlobalStyles.cs" />
<Compile Include="Styling\ISetter.cs" />
<Compile Include="Styling\IStyle.cs" />
Expand All @@ -67,6 +70,8 @@
<Compile Include="Styling\StyleExtensions.cs" />
<Compile Include="Styling\Styler.cs" />
<Compile Include="Styling\Styles.cs" />
<Compile Include="Styling\PropertyEqualsSelector.cs" />
<Compile Include="Styling\TypeNameAndClassSelector.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Reactive.Core">
Expand Down
56 changes: 56 additions & 0 deletions src/Perspex.Styling/Styling/ChildSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// 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;
using Perspex.LogicalTree;

namespace Perspex.Styling
{
internal class ChildSelector : Selector
{
private readonly Selector _parent;
private string _selectorString;

public ChildSelector(Selector parent)
{
if (parent == null)
{
throw new InvalidOperationException("Child selector must be preceeded by a selector.");
}

_parent = parent;
}

/// <inheritdoc/>
public override bool InTemplate => _parent.InTemplate;

/// <inheritdoc/>
public override Type TargetType => null;

public override string ToString()
{
if (_selectorString == null)
{
_selectorString = _parent.ToString() + " > ";
}

return _selectorString;
}

protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
{
var controlParent = ((ILogical)control).LogicalParent;

if (controlParent != null)
{
return _parent.Match((IStyleable)controlParent, subscribe);
}
else
{
return SelectorMatch.False;
}
}

protected override Selector MovePrevious() => null;
}
}
80 changes: 80 additions & 0 deletions src/Perspex.Styling/Styling/DescendentSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// 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;
using System.Collections.Generic;
using Perspex.LogicalTree;

namespace Perspex.Styling
{
internal class DescendentSelector : Selector
{
private readonly Selector _parent;
private string _selectorString;

public DescendentSelector(Selector parent)
{
if (parent == null)
{
throw new InvalidOperationException("Descendent selector must be preceeded by a selector.");
}

_parent = parent;
}

/// <inheritdoc/>
public override bool InTemplate => _parent.InTemplate;

/// <inheritdoc/>
public override Type TargetType => null;

public override string ToString()
{
if (_selectorString == null)
{
_selectorString = _parent.ToString() + ' ';
}

return _selectorString;
}

protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
{
ILogical c = (ILogical)control;
List<IObservable<bool>> descendentMatches = new List<IObservable<bool>>();

while (c != null)
{
c = c.LogicalParent;

if (c is IStyleable)
{
var match = _parent.Match((IStyleable)c, subscribe);

if (match.ImmediateResult != null)
{
if (match.ImmediateResult == true)
{
return SelectorMatch.True;
}
}
else
{
descendentMatches.Add(match.ObservableResult);
}
}
}

if (descendentMatches.Count > 0)
{
return new SelectorMatch(StyleActivator.Or(descendentMatches));
}
else
{
return SelectorMatch.False;
}
}

protected override Selector MovePrevious() => null;
}
}
Loading

0 comments on commit a35f800

Please sign in to comment.