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

[WIP] Applying best practice #871

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
35 changes: 19 additions & 16 deletions src/Caliburn.Micro.Core/Conductor/Conductor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,26 @@ public override async Task ActivateItemAsync(T item, CancellationToken cancellat
{
if (item != null && item.Equals(ActiveItem))
{
if (IsActive)
if (!IsActive)
K4PS3 marked this conversation as resolved.
Show resolved Hide resolved
{
await ScreenExtensions.TryActivateAsync(item, cancellationToken);
OnActivationProcessed(item, true);
return;
}

await ScreenExtensions.TryActivateAsync(item, cancellationToken);
OnActivationProcessed(item, true);

return;
}

ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(new[] { ActiveItem }, cancellationToken);

if (closeResult.CloseCanOccur)
{
await ChangeActiveItemAsync(item, true, cancellationToken);
}
else
if (!closeResult.CloseCanOccur)
{
OnActivationProcessed(item, false);

return;
}

await ChangeActiveItemAsync(item, true, cancellationToken);
}

/// <summary>
Expand All @@ -49,19 +51,20 @@ public override async Task DeactivateItemAsync(T item, bool close, CancellationT
}

ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(new[] { ActiveItem }, CancellationToken.None);

if (closeResult.CloseCanOccur)
if (!closeResult.CloseCanOccur)
{
await ChangeActiveItemAsync(default, close);
return;
}

await ChangeActiveItemAsync(default, close);
}

/// <summary>
/// Called to check whether or not this instance can close.
/// </summary>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task<bool> CanCloseAsync(CancellationToken cancellationToken = default )
public override async Task<bool> CanCloseAsync(CancellationToken cancellationToken = default)
{
ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(new[] { ActiveItem }, cancellationToken);

Expand All @@ -72,7 +75,7 @@ public override async Task DeactivateItemAsync(T item, bool close, CancellationT
/// Called when activating.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
protected override Task OnActivateAsync(CancellationToken cancellationToken)
protected override Task OnActivateAsync(CancellationToken cancellationToken)
=> ScreenExtensions.TryActivateAsync(ActiveItem, cancellationToken);

/// <summary>
Expand All @@ -81,14 +84,14 @@ protected override Task OnActivateAsync(CancellationToken cancellationToken)
/// <param name="close">Indicates whether this instance will be closed.</param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
protected override Task OnDeactivateAsync(bool close, CancellationToken cancellationToken)
protected override Task OnDeactivateAsync(bool close, CancellationToken cancellationToken)
=> ScreenExtensions.TryDeactivateAsync(ActiveItem, close, cancellationToken);

/// <summary>
/// Gets the children.
/// </summary>
/// <returns>The collection of children.</returns>
public override IEnumerable<T> GetChildren()
public override IEnumerable<T> GetChildren()
=> new[] { ActiveItem };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ public AllActive()
/// <summary>
/// Gets the items that are currently being conducted.
/// </summary>
public IObservableCollection<T> Items
public IObservableCollection<T> Items
=> _items;

/// <summary>
/// Called when activating.
/// </summary>
protected override Task OnActivateAsync(CancellationToken cancellationToken)
protected override Task OnActivateAsync(CancellationToken cancellationToken)
=> Task.WhenAll(_items.OfType<IActivate>().Select(x => x.ActivateAsync(cancellationToken)));

/// <summary>
Expand Down Expand Up @@ -94,16 +94,18 @@ public override async Task<bool> CanCloseAsync(CancellationToken cancellationTok
{
ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(_items.ToList(), cancellationToken);

if (!closeResult.CloseCanOccur && closeResult.Children.Any())
if (closeResult.CloseCanOccur || !closeResult.Children.Any())
{
foreach (IDeactivate deactivate in closeResult.Children.OfType<IDeactivate>())
{
await deactivate.DeactivateAsync(true, cancellationToken);
}
return closeResult.CloseCanOccur;
}

_items.RemoveRange(closeResult.Children);
foreach (IDeactivate deactivate in closeResult.Children.OfType<IDeactivate>())
{
await deactivate.DeactivateAsync(true, cancellationToken);
}

_items.RemoveRange(closeResult.Children);

return closeResult.CloseCanOccur;
}

Expand Down Expand Up @@ -151,22 +153,27 @@ public override async Task DeactivateItemAsync(T item, bool close, CancellationT
if (item == null)
return;

if (close)
if (!close)
{
ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(new[] { item }, CancellationToken.None);
await ScreenExtensions.TryDeactivateAsync(item, false, cancellationToken);

if (closeResult.CloseCanOccur)
await CloseItemCoreAsync(item, cancellationToken);
return;
}
else
await ScreenExtensions.TryDeactivateAsync(item, false, cancellationToken);

ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(new[] { item }, CancellationToken.None);
if (!closeResult.CloseCanOccur)
{
return;
}

await CloseItemCoreAsync(item, cancellationToken);
}

/// <summary>
/// Gets the children.
/// </summary>
/// <returns>The collection of children.</returns>
public override IEnumerable<T> GetChildren()
public override IEnumerable<T> GetChildren()
=> _items;

private async Task CloseItemCoreAsync(T item, CancellationToken cancellationToken = default)
Expand Down
120 changes: 64 additions & 56 deletions src/Caliburn.Micro.Core/Conductor/ConductorWithCollectionOneActive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ public OneActive()
/// <summary>
/// Gets the items that are currently being conducted.
/// </summary>
public IObservableCollection<T> Items
public IObservableCollection<T> Items
=> _items;

/// <summary>
/// Gets the children.
/// </summary>
/// <returns>The collection of children.</returns>
public override IEnumerable<T> GetChildren()
public override IEnumerable<T> GetChildren()
=> _items;

/// <summary>
Expand All @@ -66,18 +66,20 @@ public override IEnumerable<T> GetChildren()
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task ActivateItemAsync(T item, CancellationToken cancellationToken = default)
{
if (item != null && item.Equals(ActiveItem))
if (item == null || !item.Equals(ActiveItem))
{
if (IsActive)
{
await ScreenExtensions.TryActivateAsync(item, cancellationToken);
OnActivationProcessed(item, true);
}
await ChangeActiveItemAsync(item, false, cancellationToken);

return;
}

await ChangeActiveItemAsync(item, false, cancellationToken);
if (!IsActive)
{
return;
}

await ScreenExtensions.TryActivateAsync(item, cancellationToken);
OnActivationProcessed(item, true);
}

/// <summary>
Expand All @@ -90,16 +92,22 @@ public override async Task ActivateItemAsync(T item, CancellationToken cancellat
public override async Task DeactivateItemAsync(T item, bool close, CancellationToken cancellationToken = default)
{
if (item == null)
{
return;
}

if (!close)
await ScreenExtensions.TryDeactivateAsync(item, false, cancellationToken);
else
{
ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(new[] { item }, CancellationToken.None);
await ScreenExtensions.TryDeactivateAsync(item, false, cancellationToken);

if (closeResult.CloseCanOccur)
await CloseItemCoreAsync(item, cancellationToken);
return;
}

ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(new[] { item }, CancellationToken.None);

if (closeResult.CloseCanOccur)
{
await CloseItemCoreAsync(item, cancellationToken);
}
}

Expand Down Expand Up @@ -148,39 +156,40 @@ protected virtual T DetermineNextItemToActivate(IList<T> list, int lastIndex)
public override async Task<bool> CanCloseAsync(CancellationToken cancellationToken = default)
{
ICloseResult<T> closeResult = await CloseStrategy.ExecuteAsync(_items.ToList(), cancellationToken);

if (!closeResult.CloseCanOccur && closeResult.Children.Any())
if (closeResult.CloseCanOccur || !closeResult.Children.Any())
{
IEnumerable<T> closable = closeResult.Children;
return closeResult.CloseCanOccur;
}

if (closable.Contains(ActiveItem))
{
var list = _items.ToList();
T next = ActiveItem;
do
{
T previous = next;
next = DetermineNextItemToActivate(list, list.IndexOf(previous));
list.Remove(previous);
} while (closable.Contains(next));
IEnumerable<T> closable = closeResult.Children;

T previousActive = ActiveItem;
await ChangeActiveItemAsync(next, true);
_items.Remove(previousActive);
if (closable.Contains(ActiveItem))
{
var list = _items.ToList();
T next = ActiveItem;
do
{
T previous = next;
next = DetermineNextItemToActivate(list, list.IndexOf(previous));
list.Remove(previous);
} while (closable.Contains(next));

var stillToClose = closable.ToList();
stillToClose.Remove(previousActive);
closable = stillToClose;
}
T previousActive = ActiveItem;
await ChangeActiveItemAsync(next, true);
_items.Remove(previousActive);

foreach (IDeactivate deactivate in closable.OfType<IDeactivate>())
{
await deactivate.DeactivateAsync(true, cancellationToken);
}
var stillToClose = closable.ToList();
stillToClose.Remove(previousActive);
closable = stillToClose;
}

_items.RemoveRange(closable);
foreach (IDeactivate deactivate in closable.OfType<IDeactivate>())
{
await deactivate.DeactivateAsync(true, cancellationToken);
}

_items.RemoveRange(closable);

return closeResult.CloseCanOccur;
}

Expand All @@ -189,7 +198,7 @@ public override async Task<bool> CanCloseAsync(CancellationToken cancellationTok
/// </summary>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
protected override Task OnActivateAsync(CancellationToken cancellationToken)
protected override Task OnActivateAsync(CancellationToken cancellationToken)
=> ScreenExtensions.TryActivateAsync(ActiveItem, cancellationToken);

/// <summary>
Expand All @@ -200,19 +209,19 @@ protected override Task OnActivateAsync(CancellationToken cancellationToken)
/// <returns>A task that represents the asynchronous operation.</returns>
protected override async Task OnDeactivateAsync(bool close, CancellationToken cancellationToken)
{
if (close)
if (!close)
{
foreach (IDeactivate deactivate in _items.OfType<IDeactivate>())
{
await deactivate.DeactivateAsync(true, cancellationToken);
}
await ScreenExtensions.TryDeactivateAsync(ActiveItem, false, cancellationToken);

_items.Clear();
return;
}
else

foreach (IDeactivate deactivate in _items.OfType<IDeactivate>())
{
await ScreenExtensions.TryDeactivateAsync(ActiveItem, false, cancellationToken);
await deactivate.DeactivateAsync(true, cancellationToken);
}

_items.Clear();
}

/// <summary>
Expand All @@ -225,17 +234,16 @@ protected override T EnsureItem(T newItem)
if (newItem == null)
{
newItem = DetermineNextItemToActivate(_items, ActiveItem != null ? _items.IndexOf(ActiveItem) : 0);
}
else
{
var index = _items.IndexOf(newItem);

if (index == -1)
_items.Add(newItem);
else
newItem = _items[index];
return base.EnsureItem(newItem);
}

var index = _items.IndexOf(newItem);
if (index == -1)
_items.Add(newItem);
else
newItem = _items[index];

return base.EnsureItem(newItem);
}
}
Expand Down
Loading