[NUI] Add FrameRenderedCallback, FramePresentedCallback as hidden API (#1811)
authordongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 15 Jul 2020 06:47:56 +0000 (15:47 +0900)
committerGitHub <noreply@github.com>
Wed, 15 Jul 2020 06:47:56 +0000 (15:47 +0900)
- csharp binding for DALi DevelWindow's AddFrameRenderedCallback and AddFramePresentedCallback
- TestCase will not be added in tizen CSharp-TCT, but they were added in test sample to do TDD
- paired with https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/238104/
- comments have been updated

src/Tizen.NUI/src/internal/Interop/Interop.WindowInternal.cs
src/Tizen.NUI/src/public/Window.cs [changed mode: 0644->0755]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AddFrameRenderedCallbackTest.cs [new file with mode: 0755]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Tizen.NUI.Samples.csproj

index 654678d..a6688bd 100755 (executable)
@@ -1,15 +1,21 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
+
 namespace Tizen.NUI
 {
+    using global::System;
+    using global::System.Runtime.InteropServices;
+
     internal static partial class Interop
     {
         internal static partial class WindowInternal
         {
-            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_GetNativeHandle")]
-            public static extern global::System.IntPtr Window_GetNativeHandle(global::System.Runtime.InteropServices.HandleRef jarg1);
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_GetNativeHandle")]
+            public static extern IntPtr Window_GetNativeHandle(HandleRef jarg1);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_AddFrameRenderedCallback")]
+            public static extern void AddFrameRenderedCallback(HandleRef nuiWindow, HandleRef nuiCallbakc, int nuiFrameId);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_AddFramePresentedCallback")]
+            public static extern void AddFramePresentedCallback(HandleRef nuiWindow, HandleRef nuiCallbakc, int nuiFrameId);
         }
     }
-}
\ No newline at end of file
+}
old mode 100644 (file)
new mode 100755 (executable)
index b346132..6f01fe3
 
 extern alias TizenSystemInformation;
 using TizenSystemInformation.Tizen.System;
-using System;
+using global::System;
 using System.ComponentModel;
 using System.Collections.Generic;
-using System.Runtime.InteropServices;
+using global::System.Runtime.InteropServices;
 using Tizen.NUI.BaseComponents;
 
 namespace Tizen.NUI
@@ -53,10 +53,10 @@ namespace Tizen.NUI
                 stageCPtr = new global::System.Runtime.InteropServices.HandleRef(this, Interop.Stage.Stage_GetCurrent());
 
                 localController = new LayoutController(this);
-                NUILog.Debug("layoutController id:" + localController.GetId() );
+                NUILog.Debug("layoutController id:" + localController.GetId());
             }
         }
-               
+
         /// <summary>
         /// Creates a new Window.<br />
         /// This creates an extra window in addition to the default main window<br />
@@ -67,9 +67,9 @@ namespace Tizen.NUI
         /// <since_tizen> 6 </since_tizen>
         /// <feature> http://tizen.org/feature/opengles.surfaceless_context </feature>
         /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
-        public Window(Rectangle windowPosition = null , bool isTranslucent = false) : this(Interop.Window.Window_New__SWIG_0(Rectangle.getCPtr(windowPosition), "", isTranslucent), true)
+        public Window(Rectangle windowPosition = null, bool isTranslucent = false) : this(Interop.Window.Window_New__SWIG_0(Rectangle.getCPtr(windowPosition), "", isTranslucent), true)
         {
-            if( IsSupportedMultiWindow() == false )
+            if (IsSupportedMultiWindow() == false)
             {
                 NUILog.Error("This device does not support surfaceless_context. So Window cannot be created. ");
             }
@@ -1094,12 +1094,12 @@ namespace Tizen.NUI
         /// <param name="orientations">The list of orientations.</param>
         /// <since_tizen> 6 </since_tizen>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public void SetAvailableOrientations( List<Window.WindowOrientation> orientations )
+        public void SetAvailableOrientations(List<Window.WindowOrientation> orientations)
         {
             PropertyArray orientationArray = new PropertyArray();
-            for( int i = 0; i < orientations.Count; i++ )
+            for (int i = 0; i < orientations.Count; i++)
             {
-              orientationArray.PushBack(new PropertyValue((int)orientations[i]));
+                orientationArray.PushBack(new PropertyValue((int)orientations[i]));
             }
 
             Interop.Window.Window_SetAvailableOrientations(swigCPtr, PropertyArray.getCPtr(orientationArray));
@@ -1168,7 +1168,7 @@ namespace Tizen.NUI
             if (LayersChildren == null || LayersChildren.Count < 0)
                 return 0;
 
-            return (uint) LayersChildren.Count;
+            return (uint)LayersChildren.Count;
         }
 
         internal Layer GetRootLayer()
@@ -1292,7 +1292,7 @@ namespace Tizen.NUI
                 _rootLayer.Dispose();
                 localController.Dispose();
 
-                foreach(var layer in _childLayers)
+                foreach (var layer in _childLayers)
                 {
                     layer.Dispose();
                 }
@@ -1310,5 +1310,70 @@ namespace Tizen.NUI
         {
             Interop.Window.delete_Window(swigCPtr);
         }
+
+        /// <summary>
+        /// Type of callback which is called when the frame rendering is done by graphics driver or when the frame is displayed on display.
+        /// </summary>
+        /// <param name="frameId">The Id to specify the frame. It will be passed when the callback is called.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public delegate void FrameCallbackType(int frameId);
+
+        /// <summary>
+        /// Adds a callback that is called when the frame rendering is done by the graphics driver.
+        /// A callback of the following type may be used:
+        /// <code>
+        /// void MyFunction( int frameId )
+        /// </code>
+        /// This callback will be deleted once it is called. 
+        /// <remarks>
+        /// Ownership of the callback is passed onto this class
+        /// </remarks>
+        /// </summary>
+        /// <param name="callback">The function to call</param>
+        /// <param name="frameId">The Id to specify the frame. It will be passed when the callback is called.</param>
+        /// <exception cref="ArgumentNullException">This exception can occur by the callback is null.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void AddFrameRenderedCallback(FrameCallbackType callback, int frameId)
+        {
+            IntPtr ip = Marshal.GetFunctionPointerForDelegate<Delegate>(callback);
+
+            if (IntPtr.Zero == ip)
+            {
+                throw new ArgumentNullException(nameof(callback), "FrameCallbackType should not be null");
+            }
+
+            Interop.WindowInternal.AddFrameRenderedCallback(swigCPtr, new HandleRef(this, ip), frameId);
+
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        /// <summary>
+        /// Adds a callback that is called when the frame is displayed on the display.
+        /// A callback of the following type may be used:
+        /// <code>
+        /// void MyFunction( int frameId )
+        /// </code>
+        /// This callback will be deleted once it is called. 
+        /// <remarks>
+        /// Ownership of the callback is passed onto this class
+        /// </remarks>
+        /// </summary>
+        /// <param name="callback">The function to call</param>
+        /// <param name="frameId">The Id to specify the frame. It will be passed when the callback is called.</param>
+        /// <exception cref="ArgumentNullException">This exception can occur by the callback is null.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void AddFramePresentedCallback(FrameCallbackType callback, int frameId)
+        {
+            IntPtr ip = Marshal.GetFunctionPointerForDelegate<Delegate>(callback);
+
+            if (IntPtr.Zero == ip)
+            {
+                throw new ArgumentNullException(nameof(callback), "FrameCallbackType should not be null");
+            }
+
+            Interop.WindowInternal.AddFramePresentedCallback(swigCPtr, new HandleRef(this, ip), frameId);
+
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
     }
 }
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AddFrameRenderedCallbackTest.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AddFrameRenderedCallbackTest.cs
new file mode 100755 (executable)
index 0000000..cc21b81
--- /dev/null
@@ -0,0 +1,171 @@
+
+using global::System;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using NUnit.Framework;
+using System.Threading.Tasks;
+
+namespace Tizen.NUI.Samples
+{
+    using tlog = Tizen.Log;
+    public class AddFrameRenderedCallbackTest : IExample
+    {
+        const string tag = "NUITEST";
+
+        public void Activate()
+        {
+            test();
+        }
+        public void Deactivate()
+        {
+        }
+
+        Window win;
+        Window.FrameCallbackType cb;
+        void test()
+        {
+            win = NUIApplication.GetDefaultWindow();
+            win.TouchEvent += WinTouchEvent;
+            View view = new View();
+            view.Size = new Size(100, 100);
+            view.BackgroundColor = Color.Blue;
+            win.Add(view);
+
+            cb = testCallback;
+            win.AddFrameRenderedCallback(cb, 0);
+            win.AddFramePresentedCallback(cb, 0);
+
+            Timer timer = new Timer(5000);
+            timer.Tick += testOnTick;
+            timer.Start();
+        }
+
+        private void WinTouchEvent(object sender, Window.TouchEventArgs e)
+        {
+            win.AddFrameRenderedCallback(cb, cnt++);
+            Console.WriteLine($"testOnTick() AddFrameRenderedCallback() send id={cnt}");
+            win.AddFramePresentedCallback(cb, cnt++);
+            Console.WriteLine($"testOnTick() AddFramePresentedCallback() send id={cnt}");
+        }
+
+        int cnt;
+        bool testOnTick(object o, Timer.TickEventArgs e)
+        {
+            win.AddFrameRenderedCallback(cb, cnt++);
+            Console.WriteLine($"testOnTick() AddFrameRenderedCallback() send id={cnt}");
+            win.AddFramePresentedCallback(cb, cnt++);
+            Console.WriteLine($"testOnTick() AddFramePresentedCallback() send id={cnt}");
+            return true;
+        }
+
+        void testCallback(int id)
+        {
+            Console.WriteLine($"testCallback() id={id}");
+        }
+
+
+        [Test]
+        public async Task Test_AddFrameRenderedCallback()
+        {
+            var isCalled = false;
+            Tizen.NUI.Window.FrameCallbackType callback = (int id) =>
+            {
+                isCalled = true;
+            };
+
+            win.AddFrameRenderedCallback(callback, 0);
+
+            await Task.Delay(500);
+
+            Assert.IsTrue(isCalled, "isCalled should be true");
+        }
+        [Test]
+        public async Task Test_AddFramePresentedCallback()
+        {
+            var isCalled = false;
+            Tizen.NUI.Window.FrameCallbackType callback = (int id) =>
+            {
+                isCalled = true;
+            };
+
+            win.AddFramePresentedCallback(callback, 0);
+
+            await Task.Delay(500);
+
+            Assert.IsTrue(isCalled, "isCalled should be true");
+        }
+
+        [Test]
+        public void Test_AddFrameRenderedCallbackNegative()
+        {
+            try
+            {
+                win.AddFrameRenderedCallback(null, 0);
+            }
+            catch (Exception ex)
+            {
+                if (ex is ArgumentNullException)
+                {
+                    Assert.Pass();
+                }
+                else
+                {
+                    Assert.Fail("ArgumentNullException should occur");
+                }
+            }
+        }
+
+        [Test]
+        public void Test_AddFramePresentedCallbackNegative()
+        {
+            try
+            {
+                win.AddFramePresentedCallback(null, 0);
+            }
+            catch (Exception ex)
+            {
+                if (ex is ArgumentNullException)
+                {
+                    Assert.Pass();
+                }
+                else
+                {
+                    Assert.Fail("ArgumentNullException should occur");
+                }
+            }
+        }
+        [Test]
+        public async Task Test_AddFrameRenderedCallbackId()
+        {
+            var checkId = -1;
+            Tizen.NUI.Window.FrameCallbackType callback = (int id) =>
+            {
+                checkId = id;
+            };
+
+            var testId = 9;
+            win.AddFrameRenderedCallback(callback, testId);
+
+            await Task.Delay(500);
+
+            Assert.AreEqual(testId, checkId, "should be same");
+        }
+
+        [Test]
+        public async Task Test_AddFramePresentedCallbackId()
+        {
+            var checkId = -1;
+            Tizen.NUI.Window.FrameCallbackType callback = (int id) =>
+            {
+                checkId = id;
+            };
+
+            var testId = 7;
+            win.AddFramePresentedCallback(callback, testId);
+
+            await Task.Delay(500);
+
+            Assert.AreEqual(testId, checkId, "should be same");
+        }
+    }
+}
index 6989666..11a4024 100755 (executable)
@@ -35,6 +35,9 @@
     <ProjectReference Include="../../../src/Tizen.NUI/Tizen.NUI.csproj" />
     <ProjectReference Include="../../../src/Tizen.NUI.Components/Tizen.NUI.Components.csproj" />
     <ProjectReference Include="../../../src/Tizen.NUI.Wearable/Tizen.NUI.Wearable.csproj" />
+    <PackageReference Include="nunit" Version="3.12.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
+    <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
   </ItemGroup>
 
 </Project>