Skip to content

Commit 1bb9b75

Browse files
committed
tweak message queue semantics
1 parent 4f0396c commit 1bb9b75

File tree

3 files changed

+40
-23
lines changed

3 files changed

+40
-23
lines changed

MaterialDesignThemes.Wpf/ISnackbarMessageQueue.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ public interface ISnackbarMessageQueue
4141
/// <param name="content">Message.</param>
4242
/// <param name="actionContent">Content for the action button.</param>
4343
/// <param name="actionHandler">Call back to be executed if user clicks the action button.</param>
44-
/// <param name="neverConsiderToBeDuplicate">Subsequent, duplicate messages queued within a short time span will
45-
/// be discarded. To override this behaviour and ensure the message always gets displayed set to <c>true</c>.</param>
46-
void Enqueue(object content, object actionContent, Action actionHandler, bool neverConsiderToBeDuplicate);
44+
/// <param name="promote">The message will promoted to the front ot the queue and never considered to be a duplicate.</param>
45+
void Enqueue(object content, object actionContent, Action actionHandler, bool promote);
4746

4847
/// <summary>
4948
/// Queues a notificaton message for display in a snackbar.
@@ -52,11 +51,7 @@ public interface ISnackbarMessageQueue
5251
/// <param name="actionContent">Content for the action button.</param>
5352
/// <param name="actionHandler">Call back to be executed if user clicks the action button.</param>
5453
/// <param name="actionArgument">Argument to pass to <paramref name="actionHandler"/>.</param>
55-
/// <param name="neverConsiderToBeDuplicate">Subsequent, duplicate messages queued within a short time span will
56-
/// be discarded. To override this behaviour and ensure the message always gets displayed set to <c>true</c>.</param>
57-
void Enqueue<TArgument>(object content, object actionContent, Action<TArgument> actionHandler, TArgument actionArgument, bool neverConsiderToBeDuplicate);
58-
59-
//TODO consider additional variants of Enqueue:
60-
// ShowAsync(. . .)
54+
/// <param name="promote">The message will promoted to the front ot the queue and never considered to be a duplicate.</param>
55+
void Enqueue<TArgument>(object content, object actionContent, Action<TArgument> actionHandler, TArgument actionArgument, bool promote);
6156
}
6257
}

MaterialDesignThemes.Wpf/SnackbarMessageQueue.cs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class SnackbarMessageQueue : ISnackbarMessageQueue, IDisposable
1313
{
1414
private readonly TimeSpan _messageDuration;
1515
private readonly HashSet<Snackbar> _pairedSnackbars = new HashSet<Snackbar>();
16-
private readonly Queue<SnackbarMessageQueueItem> _snackbarMessages = new Queue<SnackbarMessageQueueItem>();
16+
private readonly LinkedList<SnackbarMessageQueueItem> _snackbarMessages = new LinkedList<SnackbarMessageQueueItem>();
1717
private readonly ManualResetEvent _disposedEvent = new ManualResetEvent(false);
1818
private readonly ManualResetEvent _pausedEvent = new ManualResetEvent(false);
1919
private readonly ManualResetEvent _messageWaitingEvent = new ManualResetEvent(false);
@@ -193,7 +193,7 @@ public void Enqueue(object content, bool neverConsiderToBeDuplicate)
193193
{
194194
if (content == null) throw new ArgumentNullException(nameof(content));
195195

196-
_snackbarMessages.Enqueue(new SnackbarMessageQueueItem(content));
196+
_snackbarMessages.AddLast(new SnackbarMessageQueueItem(content));
197197
_messageWaitingEvent.Set();
198198
}
199199

@@ -202,11 +202,11 @@ public void Enqueue(object content, object actionContent, Action actionHandler)
202202
Enqueue(content, actionContent, actionHandler, false);
203203
}
204204

205-
public void Enqueue(object content, object actionContent, Action actionHandler, bool neverConsiderToBeDuplicate)
205+
public void Enqueue(object content, object actionContent, Action actionHandler, bool promote)
206206
{
207207
if (content == null) throw new ArgumentNullException(nameof(content));
208208

209-
_snackbarMessages.Enqueue(new SnackbarMessageQueueItem(content, actionContent, actionHandler));
209+
_snackbarMessages.AddLast(new SnackbarMessageQueueItem(content, actionContent, actionHandler));
210210
_messageWaitingEvent.Set();
211211
}
212212

@@ -217,7 +217,7 @@ public void Enqueue<TArgument>(object content, object actionContent, Action<TArg
217217
}
218218

219219
public void Enqueue<TArgument>(object content, object actionContent, Action<TArgument> actionHandler,
220-
TArgument actionArgument, bool neverConsiderToBeDuplicate)
220+
TArgument actionArgument, bool promote)
221221
{
222222
if (content == null) throw new ArgumentNullException(nameof(content));
223223

@@ -230,11 +230,32 @@ public void Enqueue<TArgument>(object content, object actionContent, Action<TArg
230230
}
231231

232232
var argumentType = actionArgument != null ? typeof(TArgument) : null;
233-
_snackbarMessages.Enqueue(new SnackbarMessageQueueItem(content, actionContent, actionHandler,
234-
actionArgument, argumentType, neverConsiderToBeDuplicate));
233+
234+
var snackbarMessageQueueItem = new SnackbarMessageQueueItem(content, actionContent, actionHandler,
235+
actionArgument, argumentType, promote);
236+
if (promote)
237+
InsertAsLastNotPromotedNode(snackbarMessageQueueItem);
238+
else
239+
_snackbarMessages.AddLast(snackbarMessageQueueItem);
240+
235241
_messageWaitingEvent.Set();
236242
}
237243

244+
private void InsertAsLastNotPromotedNode(SnackbarMessageQueueItem snackbarMessageQueueItem)
245+
{
246+
var node = _snackbarMessages.First;
247+
while (node != null)
248+
{
249+
if (!node.Value.IsPromoted)
250+
{
251+
_snackbarMessages.AddBefore(node, snackbarMessageQueueItem);
252+
return;
253+
}
254+
node = node.Next;
255+
}
256+
_snackbarMessages.AddLast(snackbarMessageQueueItem);
257+
}
258+
238259
private async void PumpAsync()
239260
{
240261
while (!_isDisposed)
@@ -264,9 +285,10 @@ private async void PumpAsync()
264285
//show message
265286
if (snackbar != null)
266287
{
267-
var message = _snackbarMessages.Dequeue();
288+
var message = _snackbarMessages.First.Value;
289+
_snackbarMessages.RemoveFirst();
268290
if (_latestShownItem == null
269-
|| message.NeverConsiderToBeDuplicate
291+
|| message.IsPromoted
270292
|| !Equals(_latestShownItem.Item1.Content, message.Content)
271293
|| !Equals(_latestShownItem.Item1.ActionContent, message.ActionContent)
272294
|| _latestShownItem.Item2 <= DateTime.Now.Subtract(_messageDuration))
@@ -359,7 +381,7 @@ await Task.WhenAny(
359381
durationPassedWaitHandle
360382
});
361383
}),
362-
Task.Factory.StartNew(() => actionClickWaitHandle.WaitOne()));
384+
Task.Factory.StartNew(actionClickWaitHandle.WaitOne));
363385
}
364386

365387
private static void DoActionCallback(SnackbarMessageQueueItem messageQueueItem)
@@ -403,7 +425,7 @@ public void Dispose()
403425
_isDisposed = true;
404426
_disposedEvent.Set();
405427
_disposedEvent.Dispose();
406-
_pausedEvent.Dispose();
428+
_pausedEvent.Dispose();
407429
}
408430
}
409431
}

MaterialDesignThemes.Wpf/SnackbarMessageQueueItem.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ namespace MaterialDesignThemes.Wpf
44
{
55
internal class SnackbarMessageQueueItem
66
{
7-
public SnackbarMessageQueueItem(object content, object actionContent = null, object actionHandler = null, object actionArgument = null, Type argumentType = null, bool neverConsiderToBeDuplicate = false)
7+
public SnackbarMessageQueueItem(object content, object actionContent = null, object actionHandler = null, object actionArgument = null, Type argumentType = null, bool isPromoted = false)
88
{
99
Content = content;
1010
ActionContent = actionContent;
1111
ActionHandler = actionHandler;
1212
ActionArgument = actionArgument;
1313
ArgumentType = argumentType;
14-
NeverConsiderToBeDuplicate = neverConsiderToBeDuplicate;
14+
IsPromoted = isPromoted;
1515
}
1616

1717
public object Content { get; }
@@ -24,6 +24,6 @@ public SnackbarMessageQueueItem(object content, object actionContent = null, obj
2424

2525
public Type ArgumentType { get; }
2626

27-
public bool NeverConsiderToBeDuplicate { get; }
27+
public bool IsPromoted { get; }
2828
}
2929
}

0 commit comments

Comments
 (0)