/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// using System; using System.Threading; using wasSharp.Collections.Generic; namespace wasSharpNET.Console { /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// A command-line spinner indicating activity. /// public class ConsoleSpin : IDisposable { private static readonly CircularQueue spinArt = new CircularQueue(new[] {".oOo", "oOo.", "Oo.o", "o.oO"}); private static readonly ManualResetEvent spinEvent = new ManualResetEvent(false); private static Thread spinThread; private static bool run = true; public ConsoleSpin() : this(ConsoleExtensions.ConsoleTextAlignment.TOP_LEFT) { } public ConsoleSpin(ConsoleExtensions.ConsoleTextAlignment alignment) { spinThread = new Thread(() => { while (run) { spinEvent.WaitOne(); var deco = spinArt.Dequeue(); deco.Write(alignment); foreach (var c in deco) "\b".Write(alignment); Thread.Sleep(100); } }) { IsBackground = true }; spinThread.Start(); } public void Dispose() { // Stop the callback thread. try { if (spinThread != null) { run = false; spinEvent.Reset(); if (!spinThread.ThreadState.Equals(ThreadState.Running) && !spinThread.ThreadState.Equals(ThreadState.WaitSleepJoin) || spinThread.Join(1000)) return; spinThread.Abort(); spinThread.Join(); } } catch (Exception) { /* We are going down and we do not care. */ } finally { spinThread = null; } } public void Start() { spinEvent.Set(); } public void Stop() { spinEvent.Reset(); } } }