Add PerformanceTest
authorchungryeol Lim <cdark.lim@samsung.com>
Fri, 9 Sep 2016 11:05:44 +0000 (20:05 +0900)
committerWonYoung Choi <wy80.choi@samsung.com>
Thu, 22 Sep 2016 05:05:22 +0000 (14:05 +0900)
* EcoreAnimator, ElmScrollCOnfig have been added.
* ScrollAnimationStared/Stoppe and Changed event have been added in GenList.
* RenderPost event has been added in EvasObject.

Change-Id: Ia093d4787cc50e4ac5a966b35222102069f43729
Signed-off-by: chungryeol Lim <cdark.lim@samsung.com>
12 files changed:
src/ElmSharp/ElmSharp.Net45.csproj
src/ElmSharp/ElmSharp.csproj
src/ElmSharp/ElmSharp/EcoreAnimator.cs [new file with mode: 0644]
src/ElmSharp/ElmSharp/Elementary.cs
src/ElmSharp/ElmSharp/ElmScrollConfig.cs [new file with mode: 0644]
src/ElmSharp/ElmSharp/EvasObject.cs
src/ElmSharp/ElmSharp/GenList.cs
src/ElmSharp/Interop/Interop.Ecore.cs
src/ElmSharp/Interop/Interop.Elementary.cs
test/ElmSharp.Test/ElmSharp.Test.csproj
test/ElmSharp.Test/TC/ListTest1.cs
test/ElmSharp.Test/TC/PerformanceTest.cs [new file with mode: 0644]

index 3bdf703..7ee9b6d 100644 (file)
     <Compile Include="ElmSharp\DateChangedEventArgs.cs" />\r
     <Compile Include="ElmSharp\DateTimeSelector.cs" />\r
     <Compile Include="ElmSharp\DisplayedMonthChangedEventArgs.cs" />\r
+    <Compile Include="ElmSharp\EcoreAnimator.cs" />\r
     <Compile Include="ElmSharp\EcoreMainloop.cs" />\r
     <Compile Include="ElmSharp\EcoreSynchronizationContext.cs" />\r
     <Compile Include="ElmSharp\EdjeObject.cs" />\r
     <Compile Include="ElmSharp\Elementary.cs" />\r
+    <Compile Include="ElmSharp\ElmScrollConfig.cs" />\r
     <Compile Include="ElmSharp\Entry.cs" />\r
     <Compile Include="ElmSharp\EvasKeyEventArgs.cs" />\r
     <Compile Include="ElmSharp\EvasMap.cs" />\r
index 47fa3cd..4803ec2 100644 (file)
     <Compile Include="ElmSharp\DateChangedEventArgs.cs" />\r
     <Compile Include="ElmSharp\DateTimeSelector.cs" />\r
     <Compile Include="ElmSharp\DisplayedMonthChangedEventArgs.cs" />\r
+    <Compile Include="ElmSharp\EcoreAnimator.cs" />\r
     <Compile Include="ElmSharp\EcoreMainloop.cs" />\r
     <Compile Include="ElmSharp\EcoreSynchronizationContext.cs" />\r
     <Compile Include="ElmSharp\EdjeObject.cs" />\r
+    <Compile Include="ElmSharp\ElmScrollConfig.cs" />\r
     <Compile Include="ElmSharp\Elementary.cs" />\r
     <Compile Include="ElmSharp\Entry.cs" />\r
     <Compile Include="ElmSharp\EvasKeyEventArgs.cs" />\r
diff --git a/src/ElmSharp/ElmSharp/EcoreAnimator.cs b/src/ElmSharp/ElmSharp/EcoreAnimator.cs
new file mode 100644 (file)
index 0000000..db52ecd
--- /dev/null
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+
+namespace ElmSharp
+{
+    public static class EcoreAnimator
+    {
+        static readonly Dictionary<int, Func<bool>> _taskMap = new Dictionary<int, Func<bool>>();
+        static readonly Object _taskLock = new Object();
+        static int _newTaskId = 0;
+
+        static Interop.Ecore.EcoreTaskCallback _nativeHandler;
+
+        static EcoreAnimator()
+        {
+            _nativeHandler = NativeHandler;
+        }
+
+        public static double GetCurrentTime()
+        {
+            return Interop.Ecore.ecore_time_get();
+        }
+
+        public static IntPtr AddAmimator(Func<bool> handler)
+        {
+            int id = RegistHandler(handler);
+            return Interop.Ecore.ecore_animator_add(_nativeHandler, (IntPtr)id);
+        }
+
+        public static void RemoveAnimator(IntPtr anim)
+        {
+            int taskId = (int)Interop.Ecore.ecore_animator_del(anim);
+            _taskMap.Remove(taskId);
+        }
+
+        static int RegistHandler(Func<bool> task)
+        {
+            int taskId;
+            lock (_taskLock)
+            {
+                taskId = _newTaskId++;
+            }
+            _taskMap[taskId] = task;
+            return taskId;
+        }
+
+        static bool NativeHandler(IntPtr userData)
+        {
+            int task_id = (int)userData;
+            Func<bool> userAction = null;
+            _taskMap.TryGetValue(task_id, out userAction);
+            return (userAction != null)?userAction():false;
+        }
+
+    }
+}
index 6a027ec..f8c2721 100644 (file)
@@ -18,5 +18,15 @@ namespace ElmSharp
         {
             Interop.Elementary.elm_run();
         }
+
+        public static double GetSystemScrollFriction()
+        {
+            return Interop.Elementary.elm_config_scroll_bring_in_scroll_friction_get();
+        }
+
+        public static void SetSystemScrollFriction(double timeSet)
+        {
+            Interop.Elementary.elm_config_scroll_bring_in_scroll_friction_set(timeSet);
+        }
     }
 }
diff --git a/src/ElmSharp/ElmSharp/ElmScrollConfig.cs b/src/ElmSharp/ElmSharp/ElmScrollConfig.cs
new file mode 100644 (file)
index 0000000..5501962
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+
+namespace ElmSharp
+{
+    public static class ElmScrollConfig
+    {
+        public static double BringInScrollFriction
+        {
+            get
+            {
+                return Interop.Elementary.elm_config_scroll_bring_in_scroll_friction_get();
+            }
+            set
+            {
+                Interop.Elementary.elm_config_scroll_bring_in_scroll_friction_set(value);
+            }
+        }
+    }
+}
index a52ace6..123e635 100644 (file)
@@ -13,6 +13,7 @@ namespace ElmSharp
         Interop.EvasObjectEvent<EvasKeyEventArgs> _keydown;
         Interop.EvasObjectEvent _moved;
         Interop.EvasObjectEvent _resized;
+        Interop.EvasObjectEvent _renderPost;
 
         protected EvasObject(EvasObject parent) : this()
         {
@@ -39,6 +40,13 @@ namespace ElmSharp
             remove { _resized.On -= value; }
         }
 
+        public event EventHandler RenderPost
+        {
+            add { _renderPost.On += value; }
+            remove { _renderPost.On -= value; }
+        }
+
+
         public bool IsRealized { get { return Handle != IntPtr.Zero; } }
 
         public string ClassName
@@ -295,6 +303,7 @@ namespace ElmSharp
                 _keyup = new Interop.EvasObjectEvent<EvasKeyEventArgs>(this, Handle, Interop.Evas.ObjectCallbackType.KeyUp, EvasKeyEventArgs.Create);
                 _moved = new Interop.EvasObjectEvent(this, Handle, Interop.Evas.ObjectCallbackType.Move);
                 _resized = new Interop.EvasObjectEvent(this, Handle, Interop.Evas.ObjectCallbackType.Resize);
+                _renderPost = new Interop.EvasObjectEvent(this, Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost);
 
                 _deleted.On += (s, e) => MakeInvalidate();
                 _keydown.On += (s, e) => KeyDown?.Invoke(this, e);
index c210463..3be368e 100644 (file)
@@ -52,6 +52,9 @@ namespace ElmSharp
         Interop.SmartEvent<GenListItemEventArgs> _realized;
         Interop.SmartEvent<GenListItemEventArgs> _unrealized;
         Interop.SmartEvent<GenListItemEventArgs> _longpressed;
+        Interop.SmartEvent _scrollAnimationStarted;
+        Interop.SmartEvent _scrollAnimationStopped;
+        Interop.SmartEvent _changed;
 
         public GenList(EvasObject parent) : base(parent)
         {
@@ -93,6 +96,24 @@ namespace ElmSharp
         public event EventHandler<GenListItemEventArgs> ItemUnrealized;
         public event EventHandler<GenListItemEventArgs> ItemLongPressed;
 
+        public event EventHandler Changed
+        {
+            add { _changed.On += value; }
+            remove { _changed.On -= value; }
+        }
+
+        public event EventHandler ScrollAnimationStarted
+        {
+            add { _scrollAnimationStarted.On += value; }
+            remove { _scrollAnimationStarted.On -= value; }
+        }
+
+        public event EventHandler ScrollAnimationStopped
+        {
+            add { _scrollAnimationStopped.On += value; }
+            remove { _scrollAnimationStopped.On -= value; }
+        }
+
         public GenListItem Append(GenItemClass itemClass, object data)
         {
             return Append(itemClass, data, GenListItemType.Normal);
@@ -191,6 +212,9 @@ namespace ElmSharp
             _realized = new Interop.SmartEvent<GenListItemEventArgs>(this, Handle, "realized", GenListItemEventArgs.CreateFromSmartEvent);
             _unrealized = new Interop.SmartEvent<GenListItemEventArgs>(this, Handle, "unrealized", GenListItemEventArgs.CreateFromSmartEvent);
             _longpressed = new Interop.SmartEvent<GenListItemEventArgs>(this, Handle, "longpressed", GenListItemEventArgs.CreateFromSmartEvent);
+            _scrollAnimationStarted = new Interop.SmartEvent(this, Handle, "scroll,anim,start");
+            _scrollAnimationStopped = new Interop.SmartEvent(this, Handle, "scroll,anim,stop");
+            _changed = new Interop.SmartEvent(this, Handle, "changed");
 
             _selected.On += (s, e) => { ItemSelected?.Invoke(this, e); };
             _unselected.On += (s, e) => { ItemUnselected?.Invoke(this, e); };
@@ -202,7 +226,6 @@ namespace ElmSharp
             _realized.On += (s, e) => { ItemRealized?.Invoke(this, e); };
             _unrealized.On += (s, e) => { ItemUnrealized?.Invoke(this, e); };
             _longpressed.On += (s, e) => { ItemLongPressed?.Invoke(this, e); };
-
         }
 
         void AddInternal(GenListItem item)
index b7c8929..60e4f6b 100644 (file)
@@ -49,7 +49,13 @@ internal static partial class Interop
         [DllImport(Libraries.Ecore)]
         internal static extern IntPtr ecore_timer_del(IntPtr timer);
 
+        [DllImport(Libraries.Ecore)]
+        internal static extern IntPtr ecore_animator_add(EcoreTaskCallback func, IntPtr data);
 
-    }
+        [DllImport(Libraries.Ecore)]
+        internal static extern IntPtr ecore_animator_del(IntPtr animator);
 
+        [DllImport(Libraries.Ecore)]
+        internal static extern double ecore_time_get();
+    }
 }
index 33d3226..fca0aa0 100644 (file)
@@ -14,6 +14,12 @@ internal static partial class Interop
     internal static partial class Elementary
     {
         [DllImport(Libraries.Elementary)]
+        internal static extern double elm_config_scroll_bring_in_scroll_friction_set(double time);
+
+        [DllImport(Libraries.Elementary)]
+        internal static extern double elm_config_scroll_bring_in_scroll_friction_get();
+
+        [DllImport(Libraries.Elementary)]
         internal static extern IntPtr elm_config_accel_preference_set(string preference);
 
         [DllImport(Libraries.Elementary)]
index 8899c50..f6b7a55 100644 (file)
@@ -56,6 +56,7 @@
     <Compile Include="TC\GenListTest2.cs" />\r
     <Compile Include="TC\GenListTest3.cs" />\r
     <Compile Include="TC\GenListTest4.cs" />\r
+    <Compile Include="TC\PerformanceTest.cs" />\r
     <Compile Include="TC\GenListTest5.cs" />\r
     <Compile Include="TC\ImageTest1.cs" />\r
     <Compile Include="TC\IconTest1.cs" />\r
     <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>\r
     <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>\r
   </PropertyGroup>\r
-</Project>
\ No newline at end of file
+</Project>
index bef324b..3b359da 100644 (file)
@@ -40,6 +40,7 @@ namespace ElmSharp.Test
             list.ItemActivated += List_ItemActivated;
             list.ItemDoubleClicked += List_ItemDoubleClicked;
             list.ItemLongPressed += List_ItemLongPressed;
+            list.RenderPost += List_RenderPost;
             list.Update();
             list.Show();
 
@@ -72,6 +73,12 @@ namespace ElmSharp.Test
             box.PackEnd(prepend);
         }
 
+        int count = 0;
+        private void List_RenderPost(object sender, EventArgs e)
+        {
+            Console.WriteLine("{0} List_RenderPost", count++);
+        }
+
         private void List_ItemLongPressed(object sender, ListItemEventArgs e)
         {
             Console.WriteLine("{0} item was long pressed", e.Item.Text);
diff --git a/test/ElmSharp.Test/TC/PerformanceTest.cs b/test/ElmSharp.Test/TC/PerformanceTest.cs
new file mode 100644 (file)
index 0000000..f6ee690
--- /dev/null
@@ -0,0 +1,186 @@
+using System;
+using ElmSharp;
+
+namespace ElmSharp.Test
+{
+    public class PerformanceTest : TestCaseBase
+    {
+        public override string TestName => "PerformanceTest";
+        public override string TestDescription => "To test Performance of GenList";
+
+        const int TestItemMax = 2000;
+        const double TimeSet = 5.0;
+
+        string[] arrLabel = {
+            "Time Warner Cable(Cable)",
+            "ComCast (Cable)",
+            "Dish (Satellite)",
+            "DirecTV (Satellite)",
+            "Tata Sky (Satellite)",
+            "Nextra Cable(Cable)",
+            "DD Plus (Cable)",
+            "Tikona Cable(Cable)",
+            "True Provider (Cable)",
+            "Vodafone (Satellite)",
+            "Sample Text"
+        };
+        GenList list;
+        Box box;
+        Box box2;
+        GenListItem ItemTarget = null;
+        double _enteringSpeed = 0;
+        int _frameCount = 0;
+        int _ecoreCount = 0;
+        double _frameSet = 0;
+        IntPtr _anim = IntPtr.Zero;
+        double FrameFPS = 0;
+        double AnimatorFPS = 0;
+
+        public override void Run(Window window)
+        {
+            Conformant conformant = new Conformant(window);
+            conformant.Show();
+
+            Naviframe navi = new Naviframe(window)
+            {
+                PreserveContentOnPop = true,
+                DefaultBackButtonEnabled = true
+            };
+
+            box = new Box(window)
+            {
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1,
+            };
+            box.Show();
+
+            box2 = new Box(box);
+            //elm_box_padding_set(box2, ELM_SCALE_SIZE(10), ELM_SCALE_SIZE(10)); ºÎºÐ ºüÁü.
+            box2.Show();
+            box.PackEnd(box2);
+
+            list = new GenList(window)
+            {
+                Homogeneous = true,
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1,
+            };
+            box.PackEnd(list);
+            navi.Push(box, "Performance");
+
+            InitializeListItem();
+
+            list.Changed += List_Changed;
+            list.ScrollAnimationStarted += List_ScrollAnimationStarted;
+            list.ScrollAnimationStopped += List_ScrollAnimationStopped;
+            list.Show();
+
+            navi.Show();
+            conformant.SetContent(navi);
+        }
+
+        private void InitializeListItem()
+        {
+            GenItemClass defaultClass = new GenItemClass("default")
+            {
+                GetTextHandler = (obj, part) =>
+                {
+                    return (string)obj;
+                }
+            };
+
+            for (int i = 0; i < TestItemMax; ++i)
+            {
+                if (i == 999)
+                    ItemTarget = list.Append(defaultClass, new string(arrLabel[i % 10].ToCharArray()));
+                else
+                    list.Append(defaultClass, new string(arrLabel[i % 10].ToCharArray()));
+            }
+        }
+
+        private void List_ScrollAnimationStopped(object sender, EventArgs e)
+        {
+            list.RenderPost -= List_RenderPostFrame;
+            list.ScrollAnimationStarted -= List_ScrollAnimationStarted;
+            list.ScrollAnimationStopped -= List_ScrollAnimationStopped;
+
+            EcoreAnimator.RemoveAnimator(_anim);
+            ElmScrollConfig.BringInScrollFriction = _frameSet;
+
+            FrameFPS = _frameCount / TimeSet;
+            AnimatorFPS = _ecoreCount / TimeSet;
+
+            Button btn1 = new Button(box2)
+            {
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1,
+            };
+            btn1.Text = string.Format("Entering Speed : {0:f1} msec", _enteringSpeed);
+            btn1.Show();
+            box2.PackEnd(btn1);
+            Button btn2 = new Button(box2)
+            {
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1,
+            };
+            btn2.Text = string.Format("Animator FPS : {0:f1} fps", AnimatorFPS);
+            btn2.Show();
+            box2.PackEnd(btn2);
+            Button btn3 = new Button(box2)
+            {
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1,
+            };
+            btn3.Text = string.Format("Evas FPS : {0:f1} fps", FrameFPS);
+            btn3.Show();
+            box2.PackEnd(btn3);
+            box2.SetAlignment(-1, -1);
+            box2.SetWeight(1, 0.07);
+        }
+
+        private void List_RenderPost(object sender, EventArgs e)
+        {
+            list.RenderPost -= List_RenderPost;
+            _enteringSpeed = (EcoreAnimator.GetCurrentTime() - _enteringSpeed) * 1000;
+
+            _frameSet = ElmScrollConfig.BringInScrollFriction;
+            ElmScrollConfig.BringInScrollFriction = TimeSet;
+            list.ScrollTo(ItemTarget, ScrollToPosition.In, true);
+        }
+
+        private void List_ScrollAnimationStarted(object sender, EventArgs e)
+        {
+            _ecoreCount = 0;
+            _anim = EcoreAnimator.AddAmimator(OnEcoreCheck);
+            list.RenderPost += List_RenderPostFrame;
+        }
+
+        private bool OnEcoreCheck()
+        {
+            _ecoreCount++;
+            return true;
+        }
+
+        private void List_RenderPostFrame(object sender, EventArgs e)
+        {
+            _frameCount++;
+        }
+
+        private void List_Changed(object sender, EventArgs e)
+        {
+            _enteringSpeed = EcoreAnimator.GetCurrentTime();
+            list.Changed -= List_Changed;
+            list.RenderPost += List_RenderPost;
+        }
+    }
+}