public static class Application
{
private static readonly Dictionary<AppControlFilter, Type> s_filterMap = new Dictionary<AppControlFilter, Type>();
- private static readonly List<Service> s_serviceList = new List<Service>();
- private static readonly ActorStack s_actorStack = new ActorStack();
- private static Window s_window = null;
+ private static readonly List<ServiceController> s_serviceControllerList = new List<ServiceController>();
+ private static readonly UIControllerStack s_uiControllerStack = new UIControllerStack();
+ private static Window s_defaultWindow = null;
/// <summary>
/// Occurs when the application starts.
/// </summary>
public static event EventHandler Exited = delegate { };
- private static Actor ForegroundActor
+ private static UIController Foreground
{
get
{
- return s_actorStack.Peek();
+ return s_uiControllerStack.Peek();
}
}
};
ops.OnPause = (userData) =>
{
- if (ForegroundActor != null)
+ if (Foreground != null)
{
- ForegroundActor.OnPause();
+ Foreground.SendPause();
}
};
ops.OnResume = (userData) =>
{
- if (ForegroundActor != null)
+ if (Foreground != null)
{
- ForegroundActor.OnResume();
+ Foreground.SendResume();
}
};
ops.OnAppControl = (appControlHandle, userData) =>
{
AppControl control = new AppControl(appControlHandle);
- if (control.IsService)
- {
- Type found = FindServiceInFilters(control);
- if (found != null)
- {
- StartService(found, control);
- }
- }
- else
- {
- Type found = FindActorInFilters(control);
- if (found != null)
- {
- StartActor(null, found, Context.ActorFlags.NewInstance, control);
- }
- }
+ StartController(null, null, control, Controller.ControlFlags.NewInstance);
};
ops.OnTerminate = (userData) =>
{
}
/// <summary>
- /// Registers an Actor class type.
- /// </summary>
- /// <param name="actorType">The type of Actor class.</param>
- public static void RegisterActor(Type actorType)
- {
- RegisterActor(actorType, new AppControlFilter[0] { });
- }
-
- /// <summary>
- /// Registers an Actor class type.
- /// </summary>
- /// <param name="actorType">The type of Actor class.</param>
- /// <param name="filter">The filter to match Actor and AppControl.</param>
- public static void RegisterActor(Type actorType, AppControlFilter filter)
- {
- RegisterActor(actorType, new AppControlFilter[] { filter });
- }
-
- /// <summary>
- /// Registers an Actor class type.
+ ///
/// </summary>
- /// <param name="actorType">The type of Actor class.</param>
- /// <param name="filters">The array of filters to match Actor and AppControl.</param>
- public static void RegisterActor(Type actorType, AppControlFilter[] filters)
+ /// <param name="controllerType"></param>
+ public static void RegisterController(Type controllerType)
{
- if (!actorType.IsSubclassOf(typeof(Actor)))
- throw new ArgumentException(actorType.FullName + " is not a subclass of Actor.");
-
- RegisterContext(actorType, filters);
+ RegisterController(controllerType, new AppControlFilter[0] { });
}
/// <summary>
- /// Registers an Service class type.
+ ///
/// </summary>
- /// <param name="serviceType">The type of Service class.</param>
- public static void RegisterService(Type serviceType)
+ /// <param name="controllerType"></param>
+ /// <param name="filter"></param>
+ public static void RegisterController(Type controllerType, AppControlFilter filter)
{
- RegisterService(serviceType, new AppControlFilter[0] { });
+ RegisterController(controllerType, new AppControlFilter[] { filter });
}
/// <summary>
- /// Registers an Service class type.
+ ///
/// </summary>
- /// <param name="serviceType">The type of Service class.</param>
- /// <param name="filter">The filter to match Service and AppControl.</param>
- public static void RegisterService(Type serviceType, AppControlFilter filter)
+ /// <param name="controllerType"></param>
+ /// <param name="filters"></param>
+ public static void RegisterController(Type controllerType, AppControlFilter[] filters)
{
- RegisterService(serviceType, new AppControlFilter[] { filter });
- }
-
- /// <summary>
- /// Registers an Service class type.
- /// </summary>
- /// <param name="serviceType">The type of Service class.</param>
- /// <param name="filters">The array of filters to match Service and AppControl.</param>
- public static void RegisterService(Type serviceType, AppControlFilter[] filters)
- {
- if (!serviceType.IsSubclassOf(typeof(Service)))
- throw new ArgumentException(serviceType.FullName + " is not a subclass of Service.");
-
- RegisterContext(serviceType, filters);
- }
-
- internal static void StartActor(Context caller, Type actorType, Context.ActorFlags flags, AppControl control)
- {
- if (caller == null && actorType == null)
+ if (controllerType == null)
{
- throw new ArgumentNullException("actorType");
+ throw new ArgumentNullException("controllerType");
}
- Actor targetActor = null;
-
- Actor callerActor = caller as Actor;
- if (callerActor != null && ForegroundActor != callerActor)
- {
- throw new InvalidOperationException("StartActor() should be called from the foreground Actor.");
+ if (!controllerType.IsSubclassOf(typeof(UIController)) || !controllerType.IsSubclassOf(typeof(ServiceController)))
+ {
+ throw new ArgumentException(controllerType.FullName + " is not a sub class of UIController or ServiceController.", "controllerType");
}
- if (actorType == null)
+ foreach (var prop in controllerType.GetProperties())
{
- actorType = FindActorInFilters(control);
- if (actorType == null)
+ foreach (var attr in prop.GetCustomAttributes(false))
{
- throw new ArgumentException("Could not find the matched Actor.", "control");
+ var filter = attr as AppControlFilter;
+ if (filter != null)
+ {
+ s_filterMap.Add(filter, controllerType);
+ }
}
}
-
- if (callerActor != null && !IsFlagSet(flags, Context.ActorFlags.NewInstance))
+ if (filters != null)
{
- targetActor = s_actorStack.FindInForegroundTask(actorType);
+ foreach (var filter in filters)
+ {
+ s_filterMap.Add(filter, controllerType);
+ }
}
-
- if (s_window == null)
+ }
+
+ internal static void StartController(Controller caller, Type controllerType, AppControl control, Controller.ControlFlags flags)
+ {
+ if (control == null)
{
- s_window = new Window();
+ throw new ArgumentNullException("control");
}
- if (!s_window.Visible)
+ if (controllerType == null)
{
- s_window.Active();
- s_window.Show();
+ controllerType = FindControllerInFilterMap(control);
+ if (controllerType == null)
+ {
+ throw new ArgumentException("Could not find any matched controller.", "controllerType");
+ }
}
- if (targetActor == null)
- {
- targetActor = (Actor)Activator.CreateInstance(actorType);
- targetActor.OnCreate(callerActor != null ? callerActor.TaskId : Guid.NewGuid(), control);
- s_actorStack.Push(targetActor);
- }
- else
+ if (controllerType.IsSubclassOf(typeof(UIController)))
{
- if (IsFlagSet(flags, Context.ActorFlags.ClearTop))
+ UIController target = null;
+ UIController uiCaller = caller as UIController;
+ if (uiCaller != null && uiCaller != Foreground)
{
- while (targetActor != ForegroundActor)
- {
- Actor popped = s_actorStack.Pop();
- popped.OnPause();
- popped.OnDestroy();
- }
+ throw new InvalidOperationException("Starting UIController should be called from the foreground.");
}
- else if (IsFlagSet(flags, Context.ActorFlags.MoveToTop))
+ if (uiCaller != null && !IsFlagSet(flags, Controller.ControlFlags.NewInstance))
{
- if (ForegroundActor != targetActor)
- {
- ForegroundActor.OnPause();
- s_actorStack.MoveToTop(targetActor);
- }
+ target = s_uiControllerStack.FindInForegroundTask(controllerType);
}
- }
- ForegroundActor.OnStart();
- ForegroundActor.OnResume();
- }
- internal static void StopActor(Actor actor)
- {
- if (ForegroundActor == null)
- {
- throw new InvalidOperationException("The Actor stack is empty.");
- }
- Guid prevForegroundTaskId = ForegroundActor.TaskId;
+ if (s_defaultWindow == null)
+ {
+ s_defaultWindow = new Window();
+ }
- s_actorStack.Remove(actor);
- actor.OnPause();
- actor.OnDestroy();
+ if (!s_defaultWindow.Visible)
+ {
+ s_defaultWindow.Active();
+ s_defaultWindow.Show();
+ }
- if (actor.TaskId == prevForegroundTaskId)
- {
- if (ForegroundActor.TaskId == actor.TaskId)
+ if (target == null)
{
- ForegroundActor.OnResume();
+ target = (UIController)Activator.CreateInstance(controllerType);
+ target.TaskId = uiCaller == null ? Guid.NewGuid() : uiCaller.TaskId;
+ target.Window = s_defaultWindow;
+ target.SendCreate();
+ s_uiControllerStack.Push(target);
}
else
{
- if (s_actorStack.Count == 0 && s_serviceList.Count == 0)
+ if (IsFlagSet(flags, Controller.ControlFlags.ClearTop))
{
- Exit();
+ while (target != Foreground)
+ {
+ UIController popped = s_uiControllerStack.Pop();
+ popped.SendPause();
+ popped.SendDestroy();
+ }
}
- else
+ else if (IsFlagSet(flags, Controller.ControlFlags.MoveToTop))
{
- s_window.Hide();
+ if (Foreground != target)
+ {
+ Foreground.SendPause();
+ s_uiControllerStack.MoveToTop(target);
+ }
}
}
+ Foreground.SendStart(control);
+ Foreground.SendResume();
}
- }
-
- internal static void StartService(Type serviceType, AppControl control)
- {
- if (serviceType == null)
+ else if (controllerType.IsSubclassOf(typeof(ServiceController)))
{
- serviceType = FindServiceInFilters(control);
- if (serviceType == null)
+ ServiceController svc = s_serviceControllerList.Find(s => s.GetType() == controllerType);
+ if (svc == null)
{
- throw new ArgumentException("Could not find the matched Service.", "control");
+ svc = (ServiceController)Activator.CreateInstance(controllerType);
+ s_serviceControllerList.Add(svc);
+ svc.SendCreate();
}
+ svc.SendStart(control);
}
else
{
- if (!serviceType.IsSubclassOf(typeof(Service)))
- {
- throw new ArgumentException(serviceType.FullName + " is not a subclass of Service.", "serviceType");
- }
+ throw new ArgumentException("Invalid controller type.", "controllerType");
}
-
- Service svc = s_serviceList.Find(s => s.GetType() == serviceType);
- if (svc == null)
- {
- svc = (Service)Activator.CreateInstance(serviceType);
- s_serviceList.Add(svc);
- svc.OnCreate(control);
- }
- svc.OnStart();
}
- internal static void StopService(Type serviceType)
+ internal static void StopController(UIController target)
{
- if (!serviceType.IsSubclassOf(typeof(Service)))
+ if (Foreground == null)
{
- throw new ArgumentException(serviceType.FullName + " is not a subclass of Service.");
+ throw new InvalidOperationException("The UIController stack is empty.");
}
- Service svc = s_serviceList.Find(s => s.GetType() == serviceType);
- if (svc != null)
+ Guid prevForegroundTaskId = Foreground.TaskId;
+
+ s_uiControllerStack.Remove(target);
+ target.SendPause();
+ target.SendDestroy();
+ if (target.TaskId == prevForegroundTaskId)
{
- svc.OnDestroy();
- s_serviceList.Remove(svc);
- if (ForegroundActor == null && s_serviceList.Count == 0)
+ if (Foreground.TaskId == target.TaskId)
{
- Exit();
+ Foreground.SendResume();
}
- }
- }
-
- internal static void Finish(Context caller)
- {
- if (caller is Actor)
- {
- StopActor(caller as Actor);
- }
- else if (caller is Service)
- {
- // TODO: check the value of GetType()
- StopService(caller.GetType());
- }
- }
-
- private static Type FindActorInFilters(AppControl control)
- {
- foreach (var item in s_filterMap)
- {
- if (item.Key.IsMatch(control) && item.Value.IsSubclassOf(typeof(Actor)))
+ else
{
- return item.Value;
+ if (s_uiControllerStack.Count == 0 && s_serviceControllerList.Count == 0)
+ {
+ Exit();
+ }
+ else
+ {
+ s_defaultWindow.Hide();
+ }
}
}
- return null;
}
- private static Type FindServiceInFilters(AppControl control)
+ internal static void StopController(Type controllerType)
{
- foreach (var item in s_filterMap)
- {
- if (item.Key.IsMatch(control) && item.Value.IsSubclassOf(typeof(Service)))
+ if (controllerType.IsSubclassOf(typeof(UIController)))
+ {
+ UIController target = s_uiControllerStack.Find(controllerType);
+ if (target == null)
{
- return item.Value;
+ throw new InvalidOperationException("Could not find the UIController to stop.");
}
+ StopController(target);
}
- return null;
- }
-
- private static void RegisterContext(Type contextType, AppControlFilter[] filters)
- {
- foreach (var prop in contextType.GetProperties())
+ else if (controllerType.IsSubclassOf(typeof(ServiceController)))
{
- foreach (var attr in prop.GetCustomAttributes(false))
+ ServiceController svc = s_serviceControllerList.Find(s => s.GetType() == controllerType);
+ if (svc != null)
{
- var filter = attr as AppControlFilter;
- if (filter != null)
+ svc.SendDestroy();
+ s_serviceControllerList.Remove(svc);
+ if (s_uiControllerStack.Count == 0 && s_serviceControllerList.Count == 0)
{
- s_filterMap.Add(filter, contextType);
+ Exit();
}
}
}
- if (filters != null)
+ }
+
+ private static Type FindControllerInFilterMap(AppControl control)
+ {
+ foreach (var item in s_filterMap)
{
- foreach (var filter in filters)
+ if (item.Key.IsMatch(control))
{
- s_filterMap.Add(filter, contextType);
+ return item.Value;
}
}
+ return null;
}
-
- private static bool IsFlagSet(Context.ActorFlags flags, Context.ActorFlags values)
+
+ private static bool IsFlagSet(Controller.ControlFlags flags, Controller.ControlFlags values)
{
return (values & flags) == values;
}
- private class ActorStack
+ private class UIControllerStack
{
- private readonly List<Actor> _actorList;
+ private readonly List<UIController> _uiControllerList;
public int Count
{
get
{
- return _actorList.Count;
+ return _uiControllerList.Count;
}
}
- public ActorStack()
+ public UIControllerStack()
{
- _actorList = new List<Actor>();
+ _uiControllerList = new List<UIController>();
}
- public Actor Peek()
+ public UIController Peek()
{
- return _actorList.LastOrDefault(null);
+ return _uiControllerList.LastOrDefault(null);
}
- public void Push(Actor item)
+ public void Push(UIController item)
{
- _actorList.Add(item);
+ _uiControllerList.Add(item);
}
- public Actor Pop()
+ public UIController Pop()
{
- Actor last = Peek();
- _actorList.Remove(last);
+ UIController last = Peek();
+ _uiControllerList.Remove(last);
return last;
}
- public void Remove(Actor actor)
+ public void Remove(UIController actor)
+ {
+ _uiControllerList.Remove(actor);
+ }
+
+ public UIController Find(Type controllerType)
{
- _actorList.Remove(actor);
+ return _uiControllerList.Find(s => s.GetType() == controllerType);
}
- public Actor FindInForegroundTask(Type actorType)
+ public UIController FindInForegroundTask(Type controllerType)
{
- return _actorList.Find(s => s.GetType() == actorType && s.TaskId == Peek().TaskId);
+ return _uiControllerList.Find(s => s.GetType() == controllerType && s.TaskId == Peek().TaskId);
}
- public void MoveToTop(Actor actor)
+ public void MoveToTop(UIController actor)
{
- _actorList.Remove(actor);
- _actorList.Add(actor);
+ _uiControllerList.Remove(actor);
+ _uiControllerList.Add(actor);
}
}
}