Toasts – Rev 41

Subversion Repositories:
Rev:
using System;
using System.Collections.Concurrent;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
using Markdig;
using Markdig.Renderers;

namespace Toasts
{
    public class ToastDisplay : IDisposable
    {
        private readonly CancellationToken _cancellationToken;
        private readonly BufferBlock<ToastDisplayData> _toastFormBufferBlock;
        private ConcurrentBag<IDisposable> tplDataflowLinks;
        private readonly TransformBlock<ToastDisplayData, ToastDisplayData> _toastBodyTransformBlock;
        private readonly ActionBlock<ToastDisplayData> _toastFormActionBlock;

        private ToastDisplay()
        {
            tplDataflowLinks = new ConcurrentBag<IDisposable>();
        }

        public ToastDisplay(CancellationToken cancellationToken) : this()
        {
            _cancellationToken = cancellationToken;

            _toastFormBufferBlock = new BufferBlock<ToastDisplayData>(new DataflowBlockOptions { CancellationToken = _cancellationToken});
            _toastBodyTransformBlock = new TransformBlock<ToastDisplayData, ToastDisplayData>(ToastBodyToHTML,
                new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken });
            _toastFormActionBlock = new ActionBlock<ToastDisplayData>(DisplayForm, new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken });

            tplDataflowLinks.Add(_toastFormBufferBlock.LinkTo(_toastBodyTransformBlock, new DataflowLinkOptions {PropagateCompletion = true}));
            tplDataflowLinks.Add(_toastBodyTransformBlock.LinkTo(DataflowBlock.NullTarget<ToastDisplayData>(), new DataflowLinkOptions { PropagateCompletion = true }, result => result == null));
            tplDataflowLinks.Add(_toastBodyTransformBlock.LinkTo(_toastFormActionBlock, new DataflowLinkOptions {PropagateCompletion = true}));
        }

        private ToastDisplayData ToastBodyToHTML(ToastDisplayData toastDisplayData)
        {
            switch (toastDisplayData.Content)
            {
                case "text/markdown":
                    toastDisplayData.Body = Markdown.ToHtml(toastDisplayData.Body);
                    break;
            }

            return toastDisplayData;
        }

        public void Dispose()
        {
            while (tplDataflowLinks.TryTake(out var disposable))
            {
                disposable.Dispose();
            }
        }

        private static void DisplayForm(ToastDisplayData toastPayload)
        {
            var thread = new Thread(() =>
            {
                var toastForm = new ToastForm(toastPayload.Title, toastPayload.Body)
                {
                    EnableChime = toastPayload.EnableChime,
                    Chime = toastPayload.Chime ?? toastPayload.Chime,
                    LingerTime = toastPayload.LingerTime,
                    Image = toastPayload.Image,
                    ContentType = toastPayload.Content
                };

                Application.Run(toastForm);
            });
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        public async Task Queue(ToastDisplayData toastPayload)
        {
            await _toastFormBufferBlock.SendAsync(toastPayload, _cancellationToken);
        }
    }
}

Generated by GNU Enscript 1.6.5.90.