/Yaulw/Thread/DispatcherThread.cs
C# | 507 lines | 319 code | 66 blank | 122 comment | 63 complexity | a625f9f92766faf6cc9f5b33e57121e8 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Sys = System.Threading;
- using System.Reflection;
- using Yaulw.WPF;
- using System.Threading;
- using System.Windows.Threading;
- using Yaulw.Other;
-
- namespace Yaulw.Thread
- {
- /// <summary>
- ///
- /// </summary>
- public enum DispatcherThreatType
- {
- WPF,
- // Winforms // ~Not implmented
- // Silverlight? // ~Not implemented
- }
-
- /// <summary>
- ///
- /// </summary>
- public class WindowType
- {
- public Type T;
- public Enum Key;
- public bool IsSingleton;
- public bool IsPerformanceLoaded;
-
- public WindowType(Type t, Enum Key, bool IsSingleton, bool IsPerformanceLoaded)
- {
- this.T = t;
- this.Key = Key;
- this.IsSingleton = IsSingleton;
- this.IsPerformanceLoaded = IsPerformanceLoaded;
- }
- }
-
- /// <summary>
- ///
- /// </summary>
- public class WindowAttributes
- {
- public IntPtr hWndOwner;
- public uint Height;
- public uint Width;
- public int Top;
- public int Left;
- public string Title;
-
- public WindowAttributes(IntPtr hWndOwner, uint Height, uint Width, int Top, int Left, string Title)
- {
- this.hWndOwner = hWndOwner;
- this.Height = Height;
- this.Width = Width;
- this.Top = Top;
- this.Left = Left;
- this.Title = Title;
- }
-
- public WindowAttributes(IntPtr hWndOwner, int Top, int Left)
- {
- this.hWndOwner = hWndOwner;
- this.Height = 0;
- this.Width = 0;
- this.Top = Top;
- this.Left = Left;
- this.Title = String.Empty;
- }
-
- public WindowAttributes(IntPtr hWndOwner)
- {
- this.hWndOwner = hWndOwner;
- this.Height = 0;
- this.Width = 0;
- this.Top = int.MinValue;
- this.Left = int.MinValue;
- this.Title = String.Empty;
- }
-
- }
-
- #region Window Manager Definition
-
- /// <summary>
- /// Abstract Base Class all Window Managers must inherit from.
- ///
- /// </summary>
- public abstract class WindowManager : IDisposable
- {
- #region Private Members
-
- private Dictionary<WindowType, List<object>> s_WindowsToManage = new Dictionary<WindowType, List<object>>();
-
- #endregion
-
- #region Construction
-
- /// <summary>
- /// Construct a Window Manager Object
- /// </summary>
- /// <param name="dispatcher">Thread Dispatcher Object</param>
- /// <param name="windowTypes">Window Types this WindowManager is managing</param>
- /// <param name="PerformanceLoad">true, to load performance enabled windows upon construction</param>
- public WindowManager(Dispatcher dispatcher, WindowType[] windowTypes, bool PerformanceLoad)
- {
- Dispatcher = dispatcher;
- WindowTypes = windowTypes;
- if (Dispatcher == null)
- throw new ArgumentException("dispatcher can't be null");
- if (windowTypes == null || windowTypes.Length < 1)
- throw new ArgumentException("windowTypes can't be null or empty");
-
- // Add All Window Types
- foreach (WindowType type in windowTypes)
- {
- // Add the Type to be managed
- AddWindowTypeToManage(type);
-
- // perform performance optimization
- if (PerformanceLoad && type.IsPerformanceLoaded)
- {
- object o = CreateInstance(type);
- AddObject(type, o);
- }
- }
- }
-
- #endregion
-
- #region Public Properties
-
- /// <summary>
- /// Returns the Dispatcher Thread responsible for this Window Manager
- /// </summary>
- public Dispatcher Dispatcher { get; private set; }
-
- /// <summary>
- /// Returns all the Window Types that have been set to be managed by this Window Manager
- /// </summary>
- public WindowType[] WindowTypes { get; private set; }
-
- #endregion
-
- #region Protected Common Window Object Operations
-
- /// <summary>
- /// Create a new Object Instance of type
- /// </summary>
- /// <param name="window">type of object to create</param>
- /// <returns>a new object for type, or null</returns>
- protected object CreateInstance(WindowType window)
- {
- object o = null;
- if (window != null)
- o = Activator.CreateInstance(window.T);
- return o;
- }
-
- /// <summary>
- /// Create a new Object Instance of type
- /// </summary>
- /// <param name="windowKey">type of object to create</param>
- /// <returns>a new object for type, or null</returns>
- protected object CreateInstance(Enum windowKey)
- {
- return CreateInstance(GetType(windowKey));
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="windowKey"></param>
- /// <returns></returns>
- protected List<object> GetObjects(Enum windowKey)
- {
- foreach (WindowType type in s_WindowsToManage.Keys)
- {
- if (type.Key.ToString() == windowKey.ToString())
- return s_WindowsToManage[type];
- }
- return null;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="window"></param>
- /// <returns></returns>
- protected List<object> GetObjects(WindowType window)
- {
- foreach (WindowType type in s_WindowsToManage.Keys)
- {
- if (type.Key.ToString() == window.Key.ToString())
- return s_WindowsToManage[type];
- }
- return null;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="windowKey"></param>
- /// <returns></returns>
- protected WindowType GetType(Enum windowKey)
- {
- foreach (WindowType type in s_WindowsToManage.Keys)
- {
- if (type.Key.ToString() == windowKey.ToString())
- return type;
- }
- return null;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="window"></param>
- /// <param name="o"></param>
- /// <returns></returns>
- protected bool AddObject(WindowType window, object o)
- {
- if (AddWindowTypeToManage(window))
- {
- List<object> objects = GetObjects(window);
- if (objects.Count == 0)
- {
- objects.Add(o);
- return true;
- }
- else if (objects.Count > 0 && !window.IsSingleton)
- {
- objects.Add(o);
- return true;
- }
- }
- return false;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="windowKey"></param>
- /// <param name="o"></param>
- /// <returns></returns>
- protected bool AddObject(Enum windowKey, object o)
- {
- WindowType type = GetType(windowKey);
- if (type != null)
- {
- List<object> objects = GetObjects(windowKey);
- if (objects.Count == 0)
- {
- objects.Add(o);
- return true;
- }
- else if (objects.Count > 0 && !type.IsSingleton)
- {
- objects.Add(o);
- return true;
- }
- }
- return false;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="window"></param>
- /// <returns></returns>
- protected bool DeleteObject(WindowType window)
- {
- List<object> objects = GetObjects(window);
- if (objects != null && objects.Count > 0)
- {
- int nIndex = objects.Count - 1;
- if (objects[nIndex] is IDisposable)
- ((IDisposable)objects[nIndex]).Dispose();
- objects.RemoveAt(nIndex);
- return true;
- }
- return false;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="windowKey"></param>
- /// <returns></returns>
- protected bool DeleteObject(Enum windowKey)
- {
- List<object> objects = GetObjects(windowKey);
- if (objects != null && objects.Count > 0)
- {
- int nIndex = objects.Count - 1;
- if (objects[nIndex] is IDisposable)
- ((IDisposable)objects[nIndex]).Dispose();
- objects.RemoveAt(nIndex);
- return true;
- }
- return false;
- }
-
- /// <summary>
- ///
- /// </summary>
- protected void ClearAllObjects()
- {
- // Iterate thru all objects and call dispose on them if they support it,
- // then clear main dictionary
- foreach (WindowType type in s_WindowsToManage.Keys)
- while (DeleteObject(type)) ;
-
- s_WindowsToManage.Clear();
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="window"></param>
- /// <returns></returns>
- protected bool AddWindowTypeToManage(WindowType window)
- {
- if (window != null && !IsWindowTypeManaged(window))
- s_WindowsToManage[window] = new List<object>();
-
- return (IsWindowTypeManaged(window));
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="window"></param>
- /// <returns></returns>
- protected bool IsWindowTypeManaged(WindowType window)
- {
- if (window != null)
- {
- foreach (WindowType type in s_WindowsToManage.Keys)
- {
- if (type.Key.ToString() == window.Key.ToString())
- return true;
- }
- }
- return false;
- }
-
- #endregion
-
- #region Abtract Methods
-
- public delegate object ShowDelegate(Enum windowKey, WindowAttributes attributes, object tag);
- public abstract object ShowWindow(Enum windowKey, WindowAttributes attributes, object tag);
- public abstract object ShowDialog(Enum windowKey, WindowAttributes attributes, object tag);
-
- public delegate bool HideCloseDelegate(Enum windowKey);
- public abstract bool HideWindow(Enum windowKey);
- public abstract bool CloseWindow(Enum windowKey);
-
- public delegate bool ActionDelegate(Enum windowKey, DelegateCollection.Bool_Param1_Window_Func action);
- public abstract bool RunAction(Enum windowKey, DelegateCollection.Bool_Param1_Window_Func action);
-
- public abstract void Dispose();
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Get All Window Objects for a Window, in a readonly fashion
- /// </summary>
- /// <param name="windowKey"></param>
- /// <returns></returns>
- public object[] GetAllWindowObjectsForWindow(Enum windowKey)
- {
- List<object> objects = GetObjects(windowKey);
- if (objects != null)
- return objects.ToArray();
- else
- return null;
- }
-
- #endregion
- }
-
- #endregion
-
- #region Dispatcher Thread
-
- /// <summary>
- ///
- /// </summary>
- static class DispatcherThread
- {
- #region Private Static Members
-
- private static Sys.Thread s_DispatcherThread = null;
- private static bool s_DispatcherThreadIsInitialized = false;
-
- private static WPFWindowManager s_wpfWindowManager = null;
- private static DispatcherThreatType s_useWindowManagerType = DispatcherThreatType.WPF;
- private static WindowType[] s_windowTypes = null;
- private static bool s_PerformPerformanceLoad = false;
-
- #endregion
-
- #region Private Static Methods
-
- /// <summary>
- /// Message Loop Thread for ButtonForm
- /// </summary>
- private static void ThreadProc()
- {
- // Create WindowManager Object on this thread *Allow global access to the object*
- if (s_useWindowManagerType == DispatcherThreatType.WPF)
- s_wpfWindowManager = new WPFWindowManager(Dispatcher.CurrentDispatcher, s_windowTypes, s_PerformPerformanceLoad);
-
- s_DispatcherThreadIsInitialized = true; // always set to true to allow caller to exit out
- if (s_wpfWindowManager != null)
- {
- //Enter Dispatcher Message Loop
- System.Windows.Threading.Dispatcher.Run();
- }
- }
-
- #endregion
-
- #region Public Static Methods
-
- /// <summary>
- /// Retrieve the Window Manager for this Dispatcher Thread
- /// </summary>
- /// <returns>a valid window Manager or null, if none</returns>
- public static WindowManager GetWMForDispatcher()
- {
- if (s_DispatcherThreadIsInitialized)
- {
- if (s_useWindowManagerType == DispatcherThreatType.WPF && s_wpfWindowManager != null)
- return s_wpfWindowManager;
- }
- return null;
- }
-
- /// <summary>
- /// Use this function to start the Dispatcher ThreadProc(above), if needed. COM+ can shutdown the thread anytime,
- /// we need to make sure that the thread is alive BEFORE calling WindowManager
- /// </summary>
- public static void Start(DispatcherThreatType threatType, WindowType[] windowTypes, bool PerformPerformanceLoad, bool bWait)
- {
- if (s_DispatcherThread != null && s_DispatcherThread.IsAlive)
- {
- return;
- }
- else
- {
- s_DispatcherThreadIsInitialized = false;
-
- // Specify Thread Attributes
- s_useWindowManagerType = threatType;
- s_windowTypes = windowTypes;
- s_PerformPerformanceLoad = PerformPerformanceLoad;
-
- // Start a new Thread so it can become the Message Loop
- s_DispatcherThread = new Sys.Thread(new Sys.ThreadStart(DispatcherThread.ThreadProc));
-
- // GUI components require the thread to be STA; otherwise throws an error
- s_DispatcherThread.SetApartmentState(ApartmentState.STA);
- s_DispatcherThread.Start();
-
- // Make sure the Application Object is running
- // (COM will eventually just time out otherwise)
- if (bWait) // Syncronous call
- {
- while (!s_DispatcherThreadIsInitialized)
- System.Threading.Thread.Sleep(20);
- }
- }
- }
-
- /// <summary>
- /// Terminates all ButtonForm Objects and the Message Dispatcher Thread *do this only on shutdown*
- /// </summary>
- public static void Stop()
- {
- if (s_DispatcherThreadIsInitialized)
- {
- // Enforce that all WindowManagers support IDispose
- if (s_wpfWindowManager != null)
- {
- s_wpfWindowManager.Dispose();
- s_wpfWindowManager = null;
- }
- s_DispatcherThread.Abort();
- s_DispatcherThreadIsInitialized = false;
- s_DispatcherThread = null;
- }
- }
-
- #endregion
- }
-
- #endregion
- }