Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 187 #188

Merged
merged 4 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
env:
Solution_Name: ./src/MauiReactor.Build.sln
TemplatePack_Name: ./src/MauiReactor.TemplatePack/MauiReactor.TemplatePack.csproj
Version: 2.0.7-beta
Version: 2.0.8-beta

steps:
- name: Checkout
Expand Down
37 changes: 18 additions & 19 deletions samples/MauiReactor.TestApp/Pages/ListViewExtendedTestPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public override VisualNode Render()
//NOTE: Header/Footer not working under .net 7
//https://github.com/dotnet/maui/issues/13560
//https://github.com/dotnet/maui/issues/12312
.Header(new Label("Header"))
.Footer(new Label("Footer"))
.Header(Label("Header"))
.Footer(Label("Footer"))
};
}

Expand All @@ -38,38 +38,37 @@ private void OnSelectedItem(object? sender, MauiControls.SelectedItemChangedEven

private ViewCell RenderGroup(GroupOfPerson person)
{
return new ViewCell
{
new Label(person.Initial)
{
new MenuFlyout
{
new MenuFlyoutItem("MenuItem1")
return ViewCell(
[
Label(person.Initial,
[
MenuFlyout(
[
MenuFlyoutItem("MenuItem1")
.OnClicked(()=>OnClickMenuItem("MenuItem1")),
new MenuFlyoutItem("MenuItem2")
MenuFlyoutItem("MenuItem2")
.OnClicked(()=>OnClickMenuItem("MenuItem2")),
new MenuFlyoutItem("MenuItem3")
MenuFlyoutItem("MenuItem3")
.OnClicked(()=>OnClickMenuItem("MenuItem3")),
}
}
])
])
.FontSize(14.0)
.FontAttributes(MauiControls.FontAttributes.Bold)
.Margin(5)
.BackgroundColor(Colors.LightGray)
,
};
]);
}

private ViewCell RenderItem(Person person)
{
return new ViewCell
{
new Label($"{person.FirstName} {person.LastName}")
return ViewCell(
[
Label($"{person.FirstName} {person.LastName}")
.FontSize(14.0)
.FontAttributes(MauiControls.FontAttributes.Bold)
.Padding(5)
.VerticalTextAlignment(TextAlignment.Center)
};
]);
}

private void OnClickMenuItem(string title)
Expand Down
92 changes: 92 additions & 0 deletions samples/MauiReactor.TestApp/Pages/TestBug187.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MauiReactor.TestApp.Models;

namespace MauiReactor.TestApp.Pages;

public class TestBug187 : Component
{
private readonly IEnumerable<Monkey> _allMonkeys = Monkey.GetList();

public override VisualNode Render() => ContentPage([
new ListView(MauiControls.ListViewCachingStrategy.RetainElement)
.HasUnevenRows(true)
.ItemsSource(_allMonkeys, RenderMonkeyTemplate)
]);

private ViewCell RenderMonkeyTemplate(Monkey monkey) => monkey.Name switch
{
"Capuchin Monkey" or "Howler Monkey" or "Red-shanked Douc" => RenderSpecialMonkeyTemplate2(monkey),
_ => RenderFullMonkeyTemplate2(monkey)
};

private ViewCell RenderSpecialMonkeyTemplate(Monkey monkey) => new ViewCell
{
new HorizontalStackLayout
{
new Label(monkey.Name)
.FontSize(12.0)
.Margin(5)
}
.BackgroundColor(Colors.AliceBlue)
};

private ViewCell RenderSpecialMonkeyTemplate2(Monkey monkey) => ViewCell([
HorizontalStackLayout(
[
Label(monkey.Name)
.FontSize(12.0)
.Margin(5)
])
.BackgroundColor(Colors.AliceBlue)
]);

private ViewCell RenderFullMonkeyTemplate(Monkey monkey) => new ViewCell
{
new HorizontalStackLayout
{
new Image()
.Source(new Uri(monkey.ImageUrl))
.HeightRequest(100)
.Margin(4),

new StackLayout
{
new Label(monkey.Name)
.FontSize(12.0)
.Margin(5),

new Label(monkey.Location)
.FontSize(12.0)
.Margin(5)
}
}
.Padding(10)
};

private ViewCell RenderFullMonkeyTemplate2(Monkey monkey) => ViewCell([
HorizontalStackLayout(
[
Image()
.Source(new Uri(monkey.ImageUrl))
.HeightRequest(100)
.Margin(4),

StackLayout(
[
Label(monkey.Name)
.FontSize(12.0)
.Margin(5),

Label(monkey.Location)
.FontSize(12.0)
.Margin(5)
])
])
.Padding(10)
]);

}
11 changes: 10 additions & 1 deletion src/MauiReactor/Internals/Validation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ public static class Validate
{
[return: NotNull]
public static T EnsureNotNull<T>([NotNull] this T? value)
=> value ?? throw new InvalidOperationException();
{
if (value == null)
{
throw new InvalidOperationException();
}

return value;
}

public static void EnsureNull<T>(this T? value)
{
if (value != null)
{
throw new InvalidOperationException();
}
}

}
Expand Down
16 changes: 11 additions & 5 deletions src/MauiReactor/Internals/VisualNodePool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

internal class VisualNodePool
{
private readonly Stack<VisualNode> _availableObjects = new();
private readonly Stack<VisualNode> _availableObjects = [];
private readonly HashSet<VisualNode> _pooledObjects = [];

public T GetObject<T>() where T : VisualNode, new()
{
Expand All @@ -15,14 +16,19 @@ internal class VisualNodePool
}
else
{
System.Diagnostics.Debug.WriteLine($"Generating new visual node: {typeof(T)}");
return new T();
//System.Diagnostics.Debug.WriteLine($"Generating new visual node: {typeof(T)}");
var newInstance = new T();
_pooledObjects.Add(newInstance);
return newInstance;
}
}

public void ReleaseObject(VisualNode obj)
{
//System.Diagnostics.Debug.WriteLine($"Releasing new visual node: {obj.GetType()}");
_availableObjects.Push(obj);
if (_pooledObjects.Contains(obj))
{
//System.Diagnostics.Debug.WriteLine($"Releasing new visual node: {obj.GetType()}");
_availableObjects.Push(obj);
}
}
}
10 changes: 5 additions & 5 deletions src/MauiReactor/PropertyValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ public interface IPropertyValue

public class PropertyValue<T> : IPropertyValue
{
private PropertyValue()
{
SetDefault = true;
}
//private PropertyValue()
//{
// SetDefault = true;
//}
public PropertyValue(T value)
{
Value = value;
Expand All @@ -31,7 +31,7 @@ public PropertyValue(Func<T> valueAction)
Value = valueAction();
}

public static IPropertyValue Default { get; } = new PropertyValue<T>();
//public static IPropertyValue Default { get; } = new PropertyValue<T>();

public T? Value { get; }

Expand Down
43 changes: 14 additions & 29 deletions src/MauiReactor/VisualNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,7 @@ public static T WithMetadata<T>(this T node, string key, object value) where T :

public static T WithMetadata<T>(this T node, object value) where T : VisualNode
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
ArgumentNullException.ThrowIfNull(value);

node.SetMetadata(value.GetType().FullName ?? throw new InvalidOperationException(), value);
return node;
Expand All @@ -120,7 +117,7 @@ public abstract class VisualNode : IVisualNode, IAutomationItemContainer

protected internal Dictionary<BindableProperty, Animatable> _animatables = [];

private readonly Dictionary<string, object?> _metadata = new();
private readonly Dictionary<string, object?> _metadata = [];

private IReadOnlyList<VisualNode>? _children = null;

Expand Down Expand Up @@ -214,21 +211,6 @@ internal virtual void Reset()

public void AppendAnimatable<T>(BindableProperty key, T animation, Action<T> action) where T : RxAnimation
{
if (key is null)
{
throw new ArgumentNullException(nameof(key));
}

if (animation is null)
{
throw new ArgumentNullException(nameof(animation));
}

if (action is null)
{
throw new ArgumentNullException(nameof(action));
}

var newAnimatableProperty = new Animatable(key, animation, new Action<RxAnimation>(target => action((T)target)));

_animatables[key] = newAnimatableProperty;
Expand Down Expand Up @@ -274,11 +256,11 @@ internal virtual bool Animate()
{
if (_isMounted)
{
var animated = AnimateThis();
var animated = AnimateThis();

OnAnimate();
OnAnimate();

return animated;
return animated;
}

return false;
Expand Down Expand Up @@ -541,7 +523,7 @@ protected virtual void OnMigrated(VisualNode newNode)

_animatables.Clear();

_isMounted = false;
//_isMounted = false;

ReleaseNodeToPool(this);
}
Expand Down Expand Up @@ -643,7 +625,7 @@ IEnumerable<T> IAutomationItemContainer.Descendants<T>()

static readonly Dictionary<Type, VisualNodePool> _nodePools = [];

protected T GetNodeFromPool<T>() where T : VisualNode, new()
protected static T GetNodeFromPool<T>() where T : VisualNode, new()
{
if (!_nodePools.TryGetValue(typeof(T), out var nodePool))
{
Expand All @@ -654,7 +636,7 @@ IEnumerable<T> IAutomationItemContainer.Descendants<T>()
}


private void ReleaseNodeToPool(VisualNode node)
private static void ReleaseNodeToPool(VisualNode node)
{
if (!_nodePools.TryGetValue(node.GetType(), out var nodePool))
{
Expand Down Expand Up @@ -692,7 +674,7 @@ public static T Set<T>(this T element, BindableProperty property, object value)
{
protected BindableObject? _nativeControl;

private readonly Dictionary<BindableProperty, object?> _attachedProperties = new();
private readonly Dictionary<BindableProperty, object?> _attachedProperties = [];

private Action<T?>? _componentRefAction;

Expand Down Expand Up @@ -738,9 +720,12 @@ internal override void MergeWith(VisualNode newNode)
((VisualNode<T>)newNode)._nativeControl = this._nativeControl;
((VisualNode<T>)newNode)._isMounted = this._nativeControl != null;
((VisualNode<T>)newNode)._componentRefAction?.Invoke(NativeControl);

OnMigrated(newNode);

base.MergeWith(newNode);

_nativeControl = null;
}
else
{
Expand Down Expand Up @@ -769,7 +754,7 @@ protected override void OnMigrated(VisualNode newNode)
}

_attachedProperties.Clear();
_nativeControl = null;
//_nativeControl = null;

base.OnMigrated(newNode);

Expand Down Expand Up @@ -937,7 +922,7 @@ public static bool SetPropertyValue(this BindableObject dependencyObject, Bindab
var propertiesBag = (HashSet<BindableProperty>?)dependencyObject.GetValue(VisualNode._mauiReactorPropertiesBagKey.BindableProperty);
if (propertiesBag == null)
{
dependencyObject.SetValue(VisualNode._mauiReactorPropertiesBagKey, propertiesBag = new HashSet<BindableProperty>());
dependencyObject.SetValue(VisualNode._mauiReactorPropertiesBagKey, propertiesBag = []);
}

propertiesBag.Add(property);
Expand Down
Loading