Refactor Lifecycles
[platform/core/csapi/tizenfx.git] / Tizen.Applications / Tizen.Applications / Application.cs
index 0f1559e..a926fb3 100755 (executable)
@@ -22,9 +22,9 @@ namespace Tizen.Applications
     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.
@@ -36,11 +36,11 @@ namespace Tizen.Applications
         /// </summary>
         public static event EventHandler Exited = delegate { };
 
-        private static Actor ForegroundActor
+        private static UIController Foreground
         {
             get
             {
-                return s_actorStack.Peek();
+                return s_uiControllerStack.Peek();
             }
         }
 
@@ -58,37 +58,22 @@ namespace Tizen.Applications
             };
             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) =>
             {
@@ -112,332 +97,279 @@ namespace Tizen.Applications
         }
 
         /// <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);
             }
         }
     }