From 1a396873633dffe0f0d8c19aa827063272a7f594 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang <35016426+stom-hwang@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:25:24 +0900 Subject: [PATCH 01/82] [Tts] Make SynthesizedPcmEventArgs inherit System.EventArgs (#5540) Signed-off-by: Suyeon Hwang --- src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs index 566957035a5..33c7332774c 100644 --- a/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs +++ b/src/Tizen.Uix.Tts/Tizen.Uix.Tts/SynthesizedPcmEventArgs.cs @@ -15,13 +15,15 @@ */ +using System; + namespace Tizen.Uix.Tts { /// /// This class holds information related to the TTS SynthesizedPcm event. /// /// 11 - public class SynthesizedPcmEventArgs + public class SynthesizedPcmEventArgs : EventArgs { internal SynthesizedPcmEventArgs(int utteranceId, SynthesizedPcmEvent synthesizedPcmEvent, byte[] data, AudioType audioType, int sampleRate) { From d949790304e0113c0f4b62cfeb2b3eaa6ca5457e Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Wed, 13 Sep 2023 16:25:19 +0900 Subject: [PATCH 02/82] [NUI] Binding GetLastHoverEvent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since GetLastTouchEvent returns all values ​​regardless of touch or hover, it was separated into GetLastTouchEvent and GetLastHoverEvent. https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/298755/ https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-adaptor/+/298753/ https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-core/+/298752/ --- .../src/internal/Interop/Interop.Window.cs | 6 +++++ src/Tizen.NUI/src/public/Window/Window.cs | 25 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs b/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs index 558e41fb20f..5cf427cf10f 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs @@ -344,12 +344,18 @@ internal static partial class Window [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_GetLastTouchEvent")] public static extern global::System.IntPtr GetLastTouchEvent(global::System.Runtime.InteropServices.HandleRef window); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_GetLastHoverEvent")] + public static extern global::System.IntPtr GetLastHoverEvent(global::System.Runtime.InteropServices.HandleRef window); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InternalRetrievingLastKeyEvent")] public static extern void InternalRetrievingLastKeyEvent(global::System.Runtime.InteropServices.HandleRef window, global::System.Runtime.InteropServices.HandleRef key); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InternalRetrievingLastTouchEvent")] public static extern void InternalRetrievingLastTouchEvent(global::System.Runtime.InteropServices.HandleRef window, global::System.Runtime.InteropServices.HandleRef touch); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InternalRetrievingLastHoverEvent")] + public static extern void InternalRetrievingLastHoverEvent(global::System.Runtime.InteropServices.HandleRef window, global::System.Runtime.InteropServices.HandleRef hover); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_SetNeedsRotationCompletedAcknowledgement")] public static extern void SetNeedsRotationCompletedAcknowledgement(global::System.Runtime.InteropServices.HandleRef window, bool needAcknowledgement); diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index 3956b86f823..4d14e0ea145 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -43,6 +43,7 @@ public partial class Window : BaseHandle private LayoutController localController; private Key internalLastKeyEvent; private Touch internalLastTouchEvent; + private Hover internalLastHoverEvent; private Timer internalHoverTimer; static internal bool IsSupportedMultiWindow() @@ -1268,13 +1269,13 @@ internal void FeedHover(TouchPoint touchPoint = null) { if (touchPoint == null) { - using Touch touch = GetLastTouchEvent(); - if (touch == null || touch.GetPointCount() < 1) + using Hover hover = GetLastHoverEvent(); + if (hover == null || hover.GetPointCount() < 1) { return; } - using Vector2 screenPosition = touch.GetScreenPosition(0); - touchPoint = new TouchPoint(touch.GetDeviceId(0), TouchPoint.StateType.Motion, screenPosition.X, screenPosition.Y); + using Vector2 screenPosition = hover.GetScreenPosition(0); + touchPoint = new TouchPoint(hover.GetDeviceId(0), TouchPoint.StateType.Motion, screenPosition.X, screenPosition.Y); } Interop.Window.FeedHoverEvent(SwigCPtr, TouchPoint.getCPtr(touchPoint)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -2136,6 +2137,22 @@ public Touch GetLastTouchEvent() return internalLastTouchEvent; } + /// + /// Gets the last hover event the window gets. + /// + /// The last hover event the window gets. + [EditorBrowsable(EditorBrowsableState.Never)] + public Hover GetLastHoverEvent() + { + if(internalLastHoverEvent == null) + { + internalLastHoverEvent = new Hover(); + } + Interop.Window.InternalRetrievingLastHoverEvent(SwigCPtr, internalLastHoverEvent.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return internalLastHoverEvent; + } + /// /// Sets the necessary for window rotation Acknowledgement. /// After this function called, SendRotationCompletedAcknowledgement() should be called to complete window rotation. From 372e37d419aee9835e2e5c65b2f9d4e70d9bff64 Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Fri, 4 Aug 2023 15:57:10 +0100 Subject: [PATCH 03/82] [NUI] Particle System binding and implementation of C# side ParticleSystem provides 4 classes: ParticleEmitter - emitter of particles ParticleSource - source of particles (spawning new particles) ParticleModifier - controller of particles behaviour Particle - wrapper over particle data --- .../src/internal/Interop/Interop.Particle.cs | 53 ++ .../Interop/Interop.ParticleEmitter.cs | 124 ++++ .../Interop/Interop.ParticleModifier.cs | 34 ++ .../Interop/Interop.ParticleSource.cs | 35 ++ .../src/public/ParticleSystem/Particle.cs | 500 +++++++++++++++ .../public/ParticleSystem/ParticleEmitter.cs | 575 ++++++++++++++++++ .../public/ParticleSystem/ParticleModifier.cs | 166 +++++ .../public/ParticleSystem/ParticleSource.cs | 206 +++++++ .../ParticleSystemSample.cs | 200 ++++++ .../Tizen.NUI.ParticleSystem.Sample.csproj | 24 + .../res/image/blue-part2.png | Bin 0 -> 28050 bytes 11 files changed, 1917 insertions(+) create mode 100644 src/Tizen.NUI/src/internal/Interop/Interop.Particle.cs create mode 100644 src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs create mode 100644 src/Tizen.NUI/src/internal/Interop/Interop.ParticleModifier.cs create mode 100644 src/Tizen.NUI/src/internal/Interop/Interop.ParticleSource.cs create mode 100644 src/Tizen.NUI/src/public/ParticleSystem/Particle.cs create mode 100644 src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs create mode 100644 src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs create mode 100644 src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs create mode 100644 test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs create mode 100644 test/Tizen.NUI.ParticleSystem.Sample/Tizen.NUI.ParticleSystem.Sample.csproj create mode 100644 test/Tizen.NUI.ParticleSystem.Sample/res/image/blue-part2.png diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.Particle.cs b/src/Tizen.NUI/src/internal/Interop/Interop.Particle.cs new file mode 100644 index 00000000000..6c8817f1c57 --- /dev/null +++ b/src/Tizen.NUI/src/internal/Interop/Interop.Particle.cs @@ -0,0 +1,53 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using global::System.Runtime.InteropServices; + +namespace Tizen.NUI.ParticleSystem +{ + internal static partial class Interop + { + internal static partial class Particle + { + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_ReadFloat")] + internal static extern float ReadFloat(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_ReadVector2")] + internal static extern global::System.IntPtr ReadVector2(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_ReadVector3")] + internal static extern global::System.IntPtr ReadVector3(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_ReadVector4")] + internal static extern global::System.IntPtr ReadVector4(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_WriteFloat")] + internal static extern void WriteFloat(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex, float value); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_WriteVector2")] + internal static extern void WriteVector2(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex, HandleRef value); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_WriteVector3")] + internal static extern void WriteVector3(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex, HandleRef value); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Particle_WriteVector4")] + internal static extern void WriteVector4(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamIndex, uint particleIndex, HandleRef value); + } + } +} + diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs new file mode 100644 index 00000000000..c463e81df86 --- /dev/null +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs @@ -0,0 +1,124 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using global::System.Runtime.InteropServices; + +namespace Tizen.NUI.ParticleSystem +{ + internal static partial class Interop + { + internal static partial class ParticleEmitter + { + [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_New_SWIG_0")] + internal static extern global::System.IntPtr New(HandleRef view); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_ParticleEmitter")] + internal static extern void DeleteParticleEmitter(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_Assign")] + internal static extern global::System.IntPtr Assign(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_DownCast")] + internal static extern global::System.IntPtr DownCast(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_SetSource")] + internal static extern void SetSource(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_SetDomain")] + internal static extern void SetDomain(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_SetRenderer")] + internal static extern void SetRenderer(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_AddModifier")] + internal static extern void AddModifier(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_SetParticleCount")] + internal static extern void SetParticleCount(global::System.Runtime.InteropServices.HandleRef jarg1, uint count); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetParticleCount")] + internal static extern uint GetParticleCount(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_SetEmissionRate")] + internal static extern void SetEmissionRate(global::System.Runtime.InteropServices.HandleRef jarg1, uint count); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_SetInitialParticleCount")] + internal static extern void SetInitialParticleCount(global::System.Runtime.InteropServices.HandleRef jarg1, uint count); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_SetActiveParticlesLimit")] + internal static extern void SetActiveParticlesLimit(global::System.Runtime.InteropServices.HandleRef jarg1, uint count); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetActiveParticlesLimit")] + internal static extern uint GetActiveParticlesLimit(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_Start")] + internal static extern void Start(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_Stop")] + internal static extern void Stop(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_RemoveModifierAt")] + internal static extern void RemoveModifierAt(global::System.Runtime.InteropServices.HandleRef jarg1, uint index); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetModifierAt")] + internal static extern global::System.IntPtr GetModifierAt(global::System.Runtime.InteropServices.HandleRef jarg1, uint index); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetParticleList")] + internal static extern global::System.IntPtr GetParticleList(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetSource")] + internal static extern global::System.IntPtr GetSource(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetDomain")] + internal static extern global::System.IntPtr GetDomain(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetRenderer")] + internal static extern global::System.IntPtr GetRenderer(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetEmissionRate")] + internal static extern uint GetEmissionRate(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetInitialParticleCount")] + internal static extern uint GetInitialParticleCount(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_GetActiveParticleLimit")] + internal static extern uint GetActiveParticleLimit(global::System.Runtime.InteropServices.HandleRef jarg1); + + // ParticleRenderer + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleRenderer_SetTexture")] + internal static extern void SetTexture(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleRenderer_SetBlendingMode")] + internal static extern void SetBlendingMode(global::System.Runtime.InteropServices.HandleRef jarg1, ParticleBlendingMode mode); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleRenderer_GetBlendingMode")] + internal static extern int GetBlendingMode(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleEmitter_NewParticle")] + internal static extern int NewParticle(global::System.IntPtr emitter, float lifetime); + + // ParticleList + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream")] + internal unsafe static extern uint AddLocalStream(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, void* defaultValue, uint typeSize ); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_GetDefaultStreamIndex")] + internal unsafe static extern int GetDefaultStreamIndex(global::System.Runtime.InteropServices.HandleRef jarg1, uint builtInStream ); + + } + } +} + diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleModifier.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleModifier.cs new file mode 100644 index 00000000000..d110894a2b4 --- /dev/null +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleModifier.cs @@ -0,0 +1,34 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using global::System.Runtime.InteropServices; +using System.Reflection; +using System; + +namespace Tizen.NUI.ParticleSystem +{ + internal static partial class Interop + { + internal static partial class ParticleModifier + { + internal delegate void ParticleModifierUpdateInvokerType(IntPtr ptr, IntPtr particleListPtr, uint first, uint count); + + [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleModifier_New_SWIG_0")] + public static extern global::System.IntPtr New(ParticleModifierUpdateInvokerType updateInvoker, out IntPtr basePtr); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleSource.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleSource.cs new file mode 100644 index 00000000000..10c0ca246f3 --- /dev/null +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleSource.cs @@ -0,0 +1,35 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using global::System.Runtime.InteropServices; +using System.Reflection; +using System; + +namespace Tizen.NUI.ParticleSystem +{ + internal static partial class Interop + { + internal static partial class ParticleSource + { + internal delegate void ParticleSourceInitInvokerType(IntPtr ptr); + internal delegate uint ParticleSourceUpdateInvokerType(IntPtr ptr, uint count); + + [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleSource_New_SWIG_0")] + internal static extern global::System.IntPtr New(ParticleSourceInitInvokerType initInvoker, ParticleSourceUpdateInvokerType updateInvoker, out IntPtr refObject); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs b/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs new file mode 100644 index 00000000000..5315592867b --- /dev/null +++ b/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs @@ -0,0 +1,500 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; +using global::System.Runtime.InteropServices; +using System.ComponentModel; +using System.Reflection; + +namespace Tizen.NUI.ParticleSystem +{ + using Tizen.NUI.BaseComponents; + + /// + /// Declares types of default streams + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public enum ParticleStream + { + Position = 1 << 0, // Vector3, Position of particle + Rotation = 1 << 1, // Vector4, Rotation of particle (quaternion) + Scale = 1 << 2, // Vector3, Scale of particle + Size = 1 << 3, // Vector3, size of particle + Color = 1 << 4, // Vector4/Color - Color of particle, (RGBA) + Opacity = 1 << 5, // float, opacity (0.0-1.0) + Velocity = 1 << 6, // Vector3, vector of velocity + Lifetime = 1 << 7, // float, remaining lifetime + Lifetime_Base = 1 << 8, // float, initial lifetime + } + + /// + /// Particle class provides interface to particle data streams + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class Particle + { + /// + /// StreamView provides functionality allowing particle + /// data manipulation (read/write). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class StreamView + { + internal StreamView(HandleRef list, uint particleIndex, uint streamIndex) + { + mParticleIndex = particleIndex; + mStreamIndex = (int)streamIndex; + mEmitterRef = list; + } + + internal StreamView(HandleRef list, uint particleIndex, ParticleStream builtInStream) + { + mEmitterRef = list; + mParticleIndex = particleIndex; + mStreamIndex = Interop.ParticleEmitter.GetDefaultStreamIndex(mEmitterRef, (uint)(builtInStream)); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + private struct Value + { + internal float valueFloat; + internal Vector2 valueVector2; + internal Vector3 valueVector3; + internal Vector4 valueVector4; + } + + internal StreamView(float f) + { + value.valueFloat = f; + type = typeof(float); + } + + internal StreamView(Vector2 f) + { + value.valueVector2 = f; + type = typeof(Vector2); + } + + internal StreamView(Vector3 f) + { + value.valueVector3 = f; + type = typeof(Vector3); + } + + internal StreamView(Vector4 f) + { + value.valueVector4 = f; + type = typeof(Vector4); + } + + /// + /// Conversion operator to float value + /// + /// StreamView object + /// Converted value + [EditorBrowsable(EditorBrowsableState.Never)] + public static implicit operator float(StreamView sv) + { + var ret = sv.mStreamIndex >= 0 ? Interop.Particle.ReadFloat(sv.mEmitterRef, (uint)sv.mStreamIndex, sv.mParticleIndex) : 0.0f; + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + + /// + /// Conversion operator to Vector2 value + /// + /// StreamView object + /// Converted value + [EditorBrowsable(EditorBrowsableState.Never)] + public static implicit operator Vector2(StreamView sv) { + var ret = sv.mStreamIndex >= 0 ? new Vector2(Interop.Particle.ReadVector2(sv.mEmitterRef, (uint)sv.mStreamIndex, sv.mParticleIndex), true) : Vector2.Zero; + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + + /// + /// Conversion operator to Vector3 value + /// + /// StreamView object + /// Converted value + [EditorBrowsable(EditorBrowsableState.Never)] + public static implicit operator Vector3(StreamView sv) { + var ret = sv.mStreamIndex >= 0 ? new Vector3(Interop.Particle.ReadVector3(sv.mEmitterRef, (uint)sv.mStreamIndex, sv.mParticleIndex), true) : Vector3.Zero; + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + + /// + /// Conversion operator to Vecto4 value + /// + /// StreamView object + /// Converted value + [EditorBrowsable(EditorBrowsableState.Never)] + public static implicit operator Vector4(StreamView sv) { + + var ret = sv.mStreamIndex >= 0 ? new Vector4(Interop.Particle.ReadVector4(sv.mEmitterRef, (uint)sv.mStreamIndex, sv.mParticleIndex), true) : Vector4.Zero; + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + + private int mStreamIndex; + private uint mParticleIndex; + private HandleRef mEmitterRef; + private Value value; + private System.Type type; + } + + /// + /// Create an initialized Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal Particle(HandleRef emitter, uint index) + { + mIndex = index; + mEmitterRef = emitter; + } + + /// + /// Returns value from specified data stream (default/custom) + /// + /// Index of stream to get value from + /// StreamView object + [EditorBrowsable(EditorBrowsableState.Never)] + public StreamView GetStreamValue(uint streamIndex) + { + return new StreamView(mEmitterRef, mIndex, streamIndex); + } + + /// + /// Returns value from specified default streamIndex + /// + /// Index of stream to get value from + /// StreamView object + [EditorBrowsable(EditorBrowsableState.Never)] + public StreamView GetStreamValue(ParticleStream streamIndex) + { + return new StreamView(mEmitterRef, mIndex, streamIndex); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Index of stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(float value, uint streamIndex) + { + Interop.Particle.WriteFloat(mEmitterRef, streamIndex, mIndex, value); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Index of stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(Vector2 value, uint streamIndex) + { + Interop.Particle.WriteVector2(mEmitterRef, streamIndex, mIndex, value.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Index of stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(Vector3 value, uint streamIndex) + { + Interop.Particle.WriteVector3(mEmitterRef, streamIndex, mIndex, value.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Index of stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(Vector4 value, uint streamIndex) + { + Interop.Particle.WriteVector4(mEmitterRef, streamIndex, mIndex, value.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(float value, ParticleStream particleStream) + { + uint streamIndex = (uint)(Interop.ParticleEmitter.GetDefaultStreamIndex(mEmitterRef, (uint)(particleStream))); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + Interop.Particle.WriteFloat(mEmitterRef, streamIndex, mIndex, value); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(Vector2 value, ParticleStream particleStream) + { + uint streamIndex = (uint)(Interop.ParticleEmitter.GetDefaultStreamIndex(mEmitterRef, (uint)(particleStream))); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + Interop.Particle.WriteVector2(mEmitterRef, streamIndex, mIndex, value.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(Vector3 value, ParticleStream particleStream) + { + uint streamIndex = (uint)(Interop.ParticleEmitter.GetDefaultStreamIndex(mEmitterRef, (uint)(particleStream))); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + Interop.Particle.WriteVector3(mEmitterRef, streamIndex, mIndex, value.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Sets value on the specified data stream + /// + /// Value to set + /// Stream to get value from + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetStreamValue(Vector4 value, ParticleStream particleStream) + { + uint streamIndex = (uint)(Interop.ParticleEmitter.GetDefaultStreamIndex(mEmitterRef, (uint)(particleStream))); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + Interop.Particle.WriteVector4(mEmitterRef, streamIndex, mIndex, value.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + + /// + /// Returns index of one of default streams. + /// + /// Stream to get index + /// Index of stream within emitter + [EditorBrowsable(EditorBrowsableState.Never)] + private uint GetStreamIndex(ParticleStream streamBit) + { + uint streamIndex = (uint)(Interop.ParticleEmitter.GetDefaultStreamIndex(mEmitterRef, (uint)(streamBit))); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return streamIndex; + } + + /// + /// Position of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 Position + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Position); + var ret = new Vector3(Interop.Particle.ReadVector3(mEmitterRef, (uint)streamIndex, mIndex), true); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Position); + } + } + + /// + /// Color of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector4 Color + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Color); + var ret = new Vector4(Interop.Particle.ReadVector4(mEmitterRef, (uint)streamIndex, mIndex), true); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Color); + } + } + + /// + /// Velocity of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 Velocity + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Velocity); + var ret = new Vector3(Interop.Particle.ReadVector3(mEmitterRef, (uint)streamIndex, mIndex), true); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Velocity); + } + } + + /// + /// Scale of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 Scale + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Scale); + var ret = new Vector3(Interop.Particle.ReadVector3(mEmitterRef, (uint)streamIndex, mIndex), true); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Scale); + } + } + + /// + /// Rotation of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector4 Rotation + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Rotation); + var ret = new Vector4(Interop.Particle.ReadVector4(mEmitterRef, (uint)streamIndex, mIndex), true); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Rotation); + } + } + + /// + /// Opacity of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float Opacity + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Opacity); + var ret = Interop.Particle.ReadFloat(mEmitterRef, (uint)streamIndex, mIndex); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Opacity); + } + } + + /// + /// Lifetime of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float Lifetime + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Lifetime); + var ret = Interop.Particle.ReadFloat(mEmitterRef, (uint)streamIndex, mIndex); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Lifetime); + } + } + + /// + /// Initial lifetime of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float LifetimeBase + { + get + { + var streamIndex = GetStreamIndex(ParticleStream.Lifetime_Base); + var ret = Interop.Particle.ReadFloat(mEmitterRef, (uint)streamIndex, mIndex); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + set + { + SetStreamValue( value, ParticleStream.Lifetime_Base); + } + } + + /// + /// Index of the Particle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal uint Index + { + get => mIndex; + set + { + mIndex = value; + } + } + + private uint mIndex; + private readonly HandleRef mEmitterRef; + } + +} \ No newline at end of file diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs new file mode 100644 index 00000000000..498f7f8f7d6 --- /dev/null +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -0,0 +1,575 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.ComponentModel; + +namespace Tizen.NUI.ParticleSystem +{ + using Tizen.NUI.BaseComponents; + + /// + /// Enum defining blending options when rendering the particles. + /// + public enum ParticleBlendingMode + { + Additive = 0, + Screen = 1, + Default = Additive + } + + /// + /// Internal class defining data types stored in the data streams + /// + internal enum StreamType + { + Float = 0, + FloatVector2 = 1, + FloatVector3 = 2, + FloatVector4 = 3, + Integer = 4, + IntVector2 = 5, + IntVector3 = 6, + IntVector4 = 7, + } + + /// + /// Class ParticleEmitter creates a single emitter attached to a specified + /// View. ParticleEmitter is responsible for spawning and updating particles. + /// + /// Emitter must contain: + /// ParticleSource - responsible for spawning new particles + /// ParticleModifier(s) - responsible for updating particles in the system + /// + /// ParticleSource and ParticleModifier callback interfaces should not be accessing + /// Event side (NUI) objects. Both callbacks are executed on Update thread. + /// + public class ParticleEmitter : BaseHandle + { + internal ParticleEmitter(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + { + } + + /// + /// Create an initialized ParticleEmitter. + /// + /// View to attach the particle emitter. + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleEmitter(View view) : this(Interop.ParticleEmitter.New(view.SwigCPtr), true) + { + mProxy = new ParticleEmitterProxy(this); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Copy constructor. + /// + /// Source object to copy. + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleEmitter( ParticleEmitter particleEmitter) : this(Interop. ParticleEmitter.New( ParticleEmitter.getCPtr(particleEmitter)), true) + { + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Assignment operator. + /// + /// Source object to be assigned. + /// Reference to this. + internal ParticleEmitter Assign( ParticleEmitter particleEmitter) + { + ParticleEmitter ret = new ParticleEmitter(Interop.ParticleEmitter.Assign(SwigCPtr, ParticleEmitter.getCPtr(particleEmitter)), false); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + + /// + /// Raises the window to the top of the window stack. + /// + /// Source object to copy. + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetSource(ParticleSource source) where T : ParticleSourceInterface, new() + { + // update interface + source.SetEmitter(this); + + // Set native source + Interop.ParticleEmitter.SetSource(SwigCPtr, source.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Maximum particle count + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public uint ParticleCount + { + get + { + var value = Interop.ParticleEmitter.GetParticleCount(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + return value; + } + set + { + Interop.ParticleEmitter.SetParticleCount(SwigCPtr, value); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + } + + /// + /// Rate of emission per second + /// + /// + /// EmissionRate defines number of particles emitted per second. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public uint EmissionRate + { + get + { + var value = Interop.ParticleEmitter.GetEmissionRate(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return value; + } + set + { + Interop.ParticleEmitter.SetEmissionRate(SwigCPtr, value); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + } + + /// + /// Initial particle count + /// + /// + /// Initial number of particles to be emitted immediately after emitter starts. It allows + /// initial burst emission. By default it's set to 0. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public uint InitialParticleCount + { + get + { + var value = Interop.ParticleEmitter.GetInitialParticleCount(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return value; + } + set + { + Interop.ParticleEmitter.SetInitialParticleCount(SwigCPtr, value); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + } + + /// + /// Limit of active particles in the system + /// + /// + /// Active particles in the system can be limited without changing . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public uint ActiveParticleLimit + { + get{ + var value = Interop.ParticleEmitter.GetActiveParticlesLimit(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return value; + } + set + { + Interop.ParticleEmitter.SetActiveParticlesLimit(SwigCPtr, value); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + } + + /// + /// Gets/sets blending mode for particle renderer + /// + /// + /// Currently two blending modes are supported: Additive and Screen (advanced blending mode). + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleBlendingMode RendererBlendingMode + { + get + { + var value = Interop.ParticleEmitter.GetBlendingMode(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return (ParticleBlendingMode)value; + } + set + { + Interop.ParticleEmitter.SetBlendingMode(SwigCPtr, value); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + } + + /// + /// Gets/sets texture to be used by the renderer + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Texture RendererTexture + { + set + { + Interop.ParticleEmitter.SetTexture(SwigCPtr, value.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + } + + /// + /// Adds ParticleModifier to the stack + /// + /// + /// ParticleEmitter implements a stack of modifiers which are responsible for + /// updating particles in the system. The stack is processed such as result of + /// previous modifier is an input for next modifier. + /// + /// Valid modifier object + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddModifier(ParticleModifier modifier) where T : ParticleModifierInterface, new() + { + // update interface + modifier.SetEmitter(this); + + Interop.ParticleEmitter.AddModifier(SwigCPtr, modifier.SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Returns associated ParticleSource object + /// + /// Valid ParticleSource object or null + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleSource GetSource() where T : ParticleSourceInterface, new() + { + IntPtr cPtr = Interop.ParticleEmitter.GetSource(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + ParticleSource ret = (cPtr == IntPtr.Zero) ? null : Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ParticleSource; + return ret; + } + + /// + /// Returns modifier at specified index + /// + /// Index within modifier stack + /// Valid ParticleModifier object or null + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleModifier GetModifierAt(uint index) + { + IntPtr cPtr = Interop.ParticleEmitter.GetModifierAt(SwigCPtr, index); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + ParticleModifier ret = (cPtr == IntPtr.Zero) ? null : Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ParticleModifier; + return ret; + } + + /// + /// Starts emission of particles. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Start() + { + Interop.ParticleEmitter.Start(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Stops emission of particles. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Stop() + { + Interop.ParticleEmitter.Stop(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Adds local (not used by shader) data stream to the particle emitter + /// + /// + /// Adds new stream of float type. + /// + /// Default value to fill the stream with + /// Index of newly created data stream + [EditorBrowsable(EditorBrowsableState.Never)] + public unsafe uint AddLocalStreamFloat(float defaultValue) + { + var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.Float, &defaultValue, sizeof(float)); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return result; + } + + /// + /// Adds local (not used by shader) data stream to the particle emitter + /// + /// + /// Adds new stream of Vector2 type. + /// + /// Default value to fill the stream with + /// Index of newly created data stream + [EditorBrowsable(EditorBrowsableState.Never)] + public unsafe uint AddLocalStreamVector2(Vector2 defaultValue) + { + var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.FloatVector2, (void*)defaultValue.SwigCPtr.Handle, sizeof(float)*2); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return result; + } + + /// + /// Adds local (not used by shader) data stream to the particle emitter + /// + /// + /// Adds new stream of Vector3 type. + /// + /// Default value to fill the stream with + /// Index of newly created data stream + [EditorBrowsable(EditorBrowsableState.Never)] + public unsafe uint AddLocalStreamVector3(Vector3 defaultValue) + { + var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.FloatVector3, (void*)defaultValue.SwigCPtr.Handle, sizeof(float)*3); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return result; + } + + /// + /// Adds local (not used by shader) data stream to the particle emitter + /// + /// + /// Adds new stream of Vector4 type. + /// + /// Default value to fill the stream with + /// Index of newly created data stream + [EditorBrowsable(EditorBrowsableState.Never)] + public unsafe uint AddLocalStreamVector4(Vector4 defaultValue) + { + var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.FloatVector4, (void*)defaultValue.SwigCPtr.Handle, sizeof(float)*4); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return result; + } + + // Internal proxy object to be used on the update thread + internal ParticleEmitterProxy EmitterProxy => mProxy; + private ParticleEmitterProxy mProxy = null; + } + + /// + /// This class provides functionality that can be used inside the Source/Modifier callbacks. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class ParticleEmitterProxy + { + internal ParticleEmitterProxy(ParticleEmitter emitter) + { + mEmitterBasePtr = emitter.SwigCPtr.Handle; + mEmitter = emitter; + } + + /// + /// Creates new particle + /// + /// + /// Function may fail and return null if current number of particles exceeds limits of emitter. + /// Particle is valid only inside the callback and must not be stored and used anywhere else. Otherwise + /// the behaviour is undefined. + /// + /// Lifetime of the particle in seconds + /// New Particle object or null + [EditorBrowsable(EditorBrowsableState.Never)] + public Particle NewParticle( float lifetime ) + { + var result = Interop.ParticleEmitter.NewParticle(mEmitterBasePtr, lifetime); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + if (result >= 0) + { + // TODO: new particles should be coming form cached queue + return new Particle(mEmitter.SwigCPtr, (uint)result); + } + return null; + } + + /// + /// Acquires list of Particles of specified length + /// + /// + /// The function should be use internally only. Native side passes list of indices of particles (int[]). + /// Before calling the callback the indices must be marshalled and converted into the Particle objects. + /// + /// Internal Particle cache is used to speed up acquiring new Particle. + /// + /// Native pointer to the list of indices (int32) + /// Number of elements + /// List of Particle objects + [EditorBrowsable(EditorBrowsableState.Never)] + internal List AcquireParticleList(IntPtr nativePtr, uint count) + { + // Populate enough particles into cache + while(mParticleCache.Count < count) + { + mParticleCache.Push(new Particle(mEmitter.SwigCPtr, 0)); + } + + List retval = new List(); + for (var i = 0; i < count; ++i) + { + var particleIndex = Marshal.ReadInt32(nativePtr, i * 4); + Particle p = mParticleCache.Pop(); + p.Index = (uint)particleIndex; + retval.Add(p); + } + + return retval; + } + + /// + /// Releases list of Particles back into the pool + /// + /// + /// Acquired particles come from internal pool and must be returned so then they can + /// be recycled. + /// + /// List of particles to be returned + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ReleaseParticleList(List particles) + { + // return particles back into the pull + for(var i = 0; i < particles.Count; ++i) + { + mParticleCache.Push(particles[i]); + } + + // clear the list (probably not needed?) + particles.Clear(); + } + + /// + /// Adds local particle data stream of float values + /// + /// Default value + /// Index of new stream + [EditorBrowsable(EditorBrowsableState.Never)] + public uint AddLocalStreamFloat(float defaultValue) + { + return mEmitter.AddLocalStreamFloat(defaultValue); + } + + /// + /// Adds local particle data stream of Vector2 values + /// + /// Default value + /// Index of new stream + [EditorBrowsable(EditorBrowsableState.Never)] + public uint AddLocalStreamVector2(Vector2 defaultValue) + { + return mEmitter.AddLocalStreamVector2(defaultValue); + } + + /// + /// Adds local particle data stream of Vector3 values + /// + /// Default value + /// Index of new stream + [EditorBrowsable(EditorBrowsableState.Never)] + public uint AddLocalStreamVector3(Vector3 defaultValue) + { + return mEmitter.AddLocalStreamVector3(defaultValue); + } + + /// + /// Adds local particle data stream of Vector4 values + /// + /// Default value + /// Index of new stream + [EditorBrowsable(EditorBrowsableState.Never)] + public uint AddLocalStreamVector4(Vector4 defaultValue) + { + return mEmitter.AddLocalStreamVector4(defaultValue); + } + + // Stack of cached particles + private Stack mParticleCache = new Stack(); + + private IntPtr mEmitterBasePtr; + private ParticleEmitter mEmitter; + + } + + /// + /// Register binding Source/Modifier interface to the pointer of a native counterpart + /// + /// Class type of objects to be stored in the register + internal class ParticleInterfaceRegister where T : class + { + internal void Register(IntPtr cPtr, T iface) + { + lock (mBasePtr) + { + mBasePtr.Add(cPtr); + mInterfaces.Add(iface); + } + } + + internal bool Remove(IntPtr cPtr) + { + lock (mBasePtr) + { + var result = mBasePtr.FindIndex(0, x => x == cPtr); + if (result >= 0) + { + mBasePtr.RemoveAt(result); + mInterfaces.RemoveAt(result); + } + + return result >= 0; + } + } + + internal bool Remove(T iface) + { + lock (mBasePtr) + { + var result = mInterfaces.FindIndex(0, x => x.Equals(iface)); + if (result >= 0) + { + mBasePtr.RemoveAt(result); + mInterfaces.RemoveAt(result); + } + + return result >= 0; + } + } + + internal T Get(IntPtr cPtr) + { + var result = mBasePtr.FindIndex(0, x => x == cPtr ); + if (result >= 0) + { + return mInterfaces[result]; + } + + return null; + } + + private List mBasePtr = new List(); + private List mInterfaces = new List(); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs new file mode 100644 index 00000000000..b19ed3969d7 --- /dev/null +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs @@ -0,0 +1,166 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System.Reflection; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.ParticleSystem +{ + /// + /// ParticleModifierInterface provides callbacks in order to define + /// how particles in the system should be modified + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class ParticleModifierInterface + { + /// + /// Constructor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleModifierInterface() + { + } + + /// + /// Second constructor + /// + /// + /// Second constructor should be overriden by the implementation. + /// It allows passing variable number of arguments for processing. + /// It is called immediately following the class constructor. + /// + /// List of arguments + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void Construct(params object[] list) + { + } + + /// + /// Updates the ParticleModifier. + /// + /// + /// This callback is responsible for updating particles in the system. + /// + /// This callback runs on the Update thread! It should avoid using NUI objects. + /// + /// + /// Proxy to the ParticleEmitter object + /// List of particles to be updated by the modifier + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void Update(ParticleEmitterProxy emitterProxy, List particleList) + { + } + + /// + /// ParticleEmitter proxy that can be accessed by the user implementation + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleEmitterProxy Emitter; + } + + + /// + /// Class represents particle modifier + /// + /// + /// ParticleModifier modifies existing particles in the system. + /// Modifiers can be stacked (more than one can be added to the ParticleEmitter). + /// Output of one modifier becomes input for next modifier. + /// + /// Modifier calls into the implementation of class. + /// + /// + /// Class of interface that derives from + [EditorBrowsable(EditorBrowsableState.Never)] + public partial class ParticleModifier : BaseHandle where T : ParticleModifierInterface, new() + { + // static cache for modifiers (binding between native side and interfaces) + static ParticleInterfaceRegister gModifierInterfaceRegister = new ParticleInterfaceRegister(); + + /// + /// Destructor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ~ParticleModifier() + { + gModifierInterfaceRegister.Remove(mInterface); + } + + /// + /// Invoker for ParticleModifierInterface.Update() + /// + /// Native pointer of ParticleModifier base object + /// C-style array of integers + /// First particle to be modified (now always 0) + /// Number of particles to be modified + [EditorBrowsable(EditorBrowsableState.Never)] + static void OnUpdateInvoker(IntPtr cPtr, IntPtr listPtr, uint first, uint count) + { + if (count > 0) + { + T modifier = (cPtr == IntPtr.Zero) ? null : gModifierInterfaceRegister.Get(cPtr) as T; + var list = modifier?.Emitter.AcquireParticleList(listPtr, count); + modifier?.Update(modifier.Emitter, list); + modifier?.Emitter.ReleaseParticleList(list); + } + } + + + internal ParticleModifier(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + { + } + + + /// + /// Constructor of ParticleModifier + /// + /// + /// ParticleModifier is a generic type that will call back into the given ParticleModifierInterface + /// instance. + /// The instance of T (derived from ParticleModifierInterface) is created internally and own by the + /// ParticleModifier. + /// The constructor takes variable number of arguments which is processed when called ParticleModifierInterface.Construct() + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleModifier(params object[] list) : this(Interop.ParticleModifier.New(mOnUpdateInvoker, out gRefObjectPtr), true) + { + // Create interface on the C# side (no direct connection with C++) + mInterface = new T(); + mInterface.Construct(list); + + // Register interface using base ptr + gModifierInterfaceRegister.Register(gRefObjectPtr, mInterface); + + // Initialise native side for this interface + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + internal void SetEmitter(ParticleEmitter emitter) + { + mInterface.Emitter = new ParticleEmitterProxy(emitter); + } + + private static Interop.ParticleModifier.ParticleModifierUpdateInvokerType mOnUpdateInvoker = OnUpdateInvoker; + private ParticleModifierInterface mInterface = null; + private static IntPtr gRefObjectPtr; + } +} \ No newline at end of file diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs new file mode 100644 index 00000000000..0fab75fd1d3 --- /dev/null +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs @@ -0,0 +1,206 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.ParticleSystem +{ + using Tizen.NUI.BaseComponents; + + /// + /// ParticleSourceInterface provides callbacks in order to define + /// how new particles are emitted. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class ParticleSourceInterface + { + /// + /// Constructor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleSourceInterface() + { + } + + /// + /// Second constructor + /// + /// + /// Second constructor should be overriden by the implementation. + /// It allows passing variable number of arguments for processing. + /// It is called immediately following the class constructor. + /// + /// List of arguments + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void Construct(params object[] list) + { + } + + /// + /// Updates the ParticleSource. + /// + /// + /// This callback is responsible for spawning new particles. To spawn new particle, + /// emitter.NewParticle() must be call. Number of particles to emit is given as 'count'. + /// + /// This callback runs on the Update thread! It should avoid using NUI objects. + /// + /// + /// Proxy to the ParticleEmitter object + /// Number of particles emitter expects to be spawned during call + /// Number of spawned particles + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual uint Update(ParticleEmitterProxy emitterProxy, uint count) + { + return 0; + } + + /// + /// Initializes ParticleSource + /// + /// + /// This callback should be overriden in order to initialise the ParticleSource. + /// It is called after ParticleEmitter.SetSource() and runs on the Event thread. + /// It is the only place where ParticleSource may use NUI objects. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void Init() + { + + } + + /// + /// ParticleEmitter proxy that can be accessed by the user implementation + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleEmitterProxy Emitter; + } + + /// + /// Class represents the particle source + /// + /// + /// ParticleSource is responsible for emission of particles. + /// It calls the implementation of class. + /// The callback runs on update thread. + /// + /// Class of interface that derives from + [EditorBrowsable(EditorBrowsableState.Never)] + public partial class ParticleSource : BaseHandle where T : ParticleSourceInterface, new() + { + // static cache for sources (binding between native side and interfaces) + private static ParticleInterfaceRegister gSourceInterfaceRegister = new ParticleInterfaceRegister(); + + /// + /// Destructor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ~ParticleSource() + { + gSourceInterfaceRegister.Remove(mInterface); + } + + /// + /// Invoker for ParticleSourceInterface.Init() + /// + /// + /// Function is called from the native side + /// + /// Native pointer of ParticleSource base object + [EditorBrowsable(EditorBrowsableState.Never)] + static void OnInitInvoker(IntPtr cPtr) + { + // This function runs on Event thread + T source = gSourceInterfaceRegister.Get(cPtr) as T; + source?.Init(); + } + + /// + /// Invoker for ParticleSourceInterface.Update() + /// + /// + /// Function is called from the native side + /// + /// Native pointer of ParticleSource base object + /// Number of particles to emit + /// Number of emitted particles + [EditorBrowsable(EditorBrowsableState.Never)] + static uint OnUpdateInvoker(IntPtr cPtr, uint count) + { + T source = gSourceInterfaceRegister.Get(cPtr) as T; + var retval= source?.Update(source.Emitter, count); + return retval.HasValue ? retval.Value : 0; + } + + internal ParticleSource(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + { + } + + /// + /// Constructor of ParticleSource + /// + /// + /// ParticleSource is a generic type that will call back into the given ParticleSourceInterface + /// instance. + /// The instance of T (derived from ParticleSourceInterface) is created internally and own by the + /// ParticleSource. + /// The constructor takes variable number of arguments which is processed when called ParticleSourceInterface.Construct() + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ParticleSource(params object[] list) : this(Interop.ParticleSource.New( mOnInitInvoker, mOnUpdateInvoker, out gRefObjectPtr ), true) + { + // Create interface on the C# side (no direct connection with C++) + mInterface = new T(); + mInterface.Construct(list); + + // Register interface using base ptr + gSourceInterfaceRegister.Register(gRefObjectPtr, mInterface); + + // Initialise native side for this interface + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Returns associated source callback interface + /// + /// Source callback interface + [EditorBrowsable(EditorBrowsableState.Never)] + private T GetCallbackInterface() + { + return mInterface as T; + } + + /// + /// Returns associated source callback interface + /// + /// Source callback interface + [EditorBrowsable(EditorBrowsableState.Never)] + public T Callback => GetCallbackInterface(); + + internal void SetEmitter(ParticleEmitter emitter) + { + mInterface.Emitter = new ParticleEmitterProxy(emitter); + } + + // private fields + private static Interop.ParticleSource.ParticleSourceInitInvokerType mOnInitInvoker = OnInitInvoker; + private static Interop.ParticleSource.ParticleSourceUpdateInvokerType mOnUpdateInvoker = OnUpdateInvoker; + private ParticleSourceInterface mInterface = null; + private static IntPtr gRefObjectPtr; + } +} \ No newline at end of file diff --git a/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs b/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs new file mode 100644 index 00000000000..550dc6c76ba --- /dev/null +++ b/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; +using Tizen.NUI.ParticleSystem; + +namespace Tizen.NUI.ParticleSystem.Sample +{ + // SparkleEffectSource spawns particle from the middle of the + // window. + class SparkleEffectSource : ParticleSourceInterface + { + public override void Construct(params object[] list) + { + base.Construct(list); + mRadius = new Vector2(list[0] as Vector2); + } + + public override uint Update(ParticleEmitterProxy emitterProxy, uint count) + { + if(mStreamBasePos == 0 || mStreamBaseAngle == 0) // streams must exist + { + return 0u; + } + + while(count > 0) + { + // Create new particle (lifetime 5 seconds of each) + var particle = emitterProxy.NewParticle(5.0f); + if(particle == null) + { + return 0u; + } + + UpdateParticle(ref particle); + + count--; + } + return 0; + } + + public override void Init() + { + // Add local stream of Vector3 type + mStreamBasePos = Emitter.AddLocalStreamVector3(Vector3.Zero); + + // Add local stream of float type + mStreamBaseAngle = Emitter.AddLocalStreamFloat(0.0f); + } + + void UpdateParticle(ref Particle p) + { + float posRadians = ((mRandom.Next() % 360) * (float)Math.PI) / 180.0f; + p.Position = new Vector3(mRadius.X * (float)Math.Sin(posRadians), mRadius.Y * (float)Math.Cos(posRadians), 0.0f); + p.SetStreamValue(p.Position, mStreamBasePos); + p.Color = Vector4.One; + p.SetStreamValue(mAngle, mStreamBaseAngle); + mAngle = ((mAngle+5)%360); + float rad = ((mRandom.Next() % 360) * (float)Math.PI) / 180.0f; + float speed = ((mRandom.Next() % 5) + 5); + p.Velocity = new Vector3((float)Math.Sin(rad) * speed, (float)Math.Cos(rad) * speed, 0); + + // Random initial scale + float initialScale = (float)(mRandom.Next() % 32) + 32; + p.Scale = new Vector3(initialScale, initialScale, 1.0f); + } + + private static float mAngle = 0; + private Random mRandom = new Random(); + public uint mStreamBasePos = 0; + public uint mStreamBaseAngle = 0; + private Vector2 mRadius; + } + + // SparkleEffectModifier spawns particle from the middle of the + // window. + class SparkleEffectModifier : ParticleModifierInterface + { + public override void Construct(params object[] list) + { + base.Construct(list); + mSource = list[0] as SparkleEffectSource; + } + + public override void Update(ParticleEmitterProxy proxy, List particles) + { + if (particles.Count == 0) + { + return; + } + + if (mStreamBasePos == 0) + { + mStreamBasePos = mSource.mStreamBasePos; + } + + if (mStreamBaseAngle == 0) + { + mStreamBaseAngle = mSource.mStreamBaseAngle; + } + + if (mStreamBasePos == 0) + { + return; + } + + for (uint i = 0; i < particles.Count; ++i) + { + var p = particles[(int)i]; + + float angle = p.GetStreamValue(mStreamBaseAngle); + Vector3 basePos = p.GetStreamValue(mStreamBaseAngle); + float radians = (float)((angle * Math.PI)/180.0f); + float lifetime = p.Lifetime; + Vector3 pos = p.Position; + var vel = p.Velocity; + p.Position = new Vector3(pos.X + vel.X * (float)Math.Cos(radians),pos.Y + vel.Y * (float)Math.Sin(radians), + pos.Z); + + p.Velocity = (vel * 0.990f); + float normalizedTime = (lifetime / p.LifetimeBase); + + var color = new Vector4( 1, 1, 1, normalizedTime); + p.Color = color; + p.Scale = new Vector3(64.0f*(normalizedTime * normalizedTime * normalizedTime * normalizedTime), 64.0f*(normalizedTime * normalizedTime * normalizedTime * normalizedTime), 1.0f); + + } + } + + private uint mStreamBasePos = 0; + private uint mStreamBaseAngle = 0; + private SparkleEffectSource mSource; + + } + + class ParticleSystemSample : NUIApplication + { + static string IMAGE_DIR = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "image/"; + + private Window mWindow; + + private ParticleEmitter mEmitter; + private ParticleSource mSource; + private ParticleModifier mModifier; + + public void Activate() + { + mWindow = Window.Instance; + mWindow.BackgroundColor = Color.Black; + + var view = new View(); + view.BackgroundColor = Color.Wheat; + view.Size = new Size(1, 1); + view.PivotPoint = new Position(0, 0); + view.Position2D = new Position2D(mWindow.Size.Width/2, mWindow.Size.Height/2); + mWindow.Add(view); + // Attach emitter to view + mEmitter = new ParticleEmitter(view) + { + ParticleCount = 10000, + EmissionRate = 500, + InitialParticleCount = 0, + RendererBlendingMode = ParticleBlendingMode.Screen + }; + + mSource = new ParticleSource(new Vector2(50, 50)); + mModifier = new ParticleModifier(mSource.Callback); + + mEmitter.SetSource(mSource); + mEmitter.AddModifier(mModifier); + + // Load texture + var pixelBuffer = ImageLoader.LoadImageFromFile(IMAGE_DIR + "/blue-part2.png"); + Texture tex = new Texture(TextureType.TEXTURE_2D, PixelFormat.RGBA8888, pixelBuffer.GetWidth(), + pixelBuffer.GetHeight()); + tex.Upload(pixelBuffer.CreatePixelData()); + + mEmitter.RendererTexture = tex; + mEmitter.Start(); + } + + protected override void OnCreate() + { + // Up call to the Base class first + base.OnCreate(); + Activate(); + } + + /// + /// The main entry point for the application. + /// + [STAThread] // Forces app to use one thread to access NUI + static void Main(string[] args) + { + ParticleSystemSample example = new ParticleSystemSample(); + example.Run(args); + } + } +} diff --git a/test/Tizen.NUI.ParticleSystem.Sample/Tizen.NUI.ParticleSystem.Sample.csproj b/test/Tizen.NUI.ParticleSystem.Sample/Tizen.NUI.ParticleSystem.Sample.csproj new file mode 100644 index 00000000000..8dcd2b34a2c --- /dev/null +++ b/test/Tizen.NUI.ParticleSystem.Sample/Tizen.NUI.ParticleSystem.Sample.csproj @@ -0,0 +1,24 @@ + + + + Exe + net6.0 + + + + true + + + + + + + + + PreserveNewest + + + + True + + diff --git a/test/Tizen.NUI.ParticleSystem.Sample/res/image/blue-part2.png b/test/Tizen.NUI.ParticleSystem.Sample/res/image/blue-part2.png new file mode 100644 index 0000000000000000000000000000000000000000..3f41b4379a0fe87178c01980ef7e67d4df5add5c GIT binary patch literal 28050 zcmeIbWmH^S*6&?NaCdiy0EN3lfMCHr6z=Z9-5o;V8Z3BlcMT9ANO0ExfndQdIp_3g zx}WYR?|sMpm^~$1G zk;gZ9duc5v000s5=L-UmmVpNV@DN$3YC3Dm%kdf6*)W5Q?F>zr-EHh2)c}Biu)96T z$jZc-%+SQl!d8&txTS-F%)(fZLW5JDRo-6Q#N0yK)6qo5Q$f|p)5?g~m_k?xLBO5w zF@TMUGlkGOn~_RnG#3bH>W&Q^jHqCXRoY04{+iQ74vka03|J~v`z z1Cnv`G6Oj|c!5ABGB#EqI}4DNg^l+)5Xi^D%?IQn`|F?(LU^y*}~42>}On%p`DAfAO*$GM1LQDotKUM--&FU{$lq?k;NTk&jMs-W%*A|#zuep z*tVJ0iKLeRafSgT)9)}{wbJoW%UR59mA14it<$ZB#yBWpQ)Xr4aix@!Ukk!!eVc0CcyH~ z!Y9hV2Na*Uowc3gW3xjBc|BuiTc1A8gC(2);jsGu0 zKXLybp%oo19v3-~^%Kp{*8kt8_zz+JM=EIxr^lh`@npz84%|PMF%=Vse=Yq-g|)>W z%aJ|E(aGfJWD}(L$87t1{rY=(`swq>q~!w{{ana|jDF4q6Jr6Ee<}TEv;Ow{%gy5d zZwLMv|B3s5&*5fnV*9^Ms6Rvfq5AJZoa{`U-9U~eqGpd{;uq8W&w&5x@$ZoZSbnbg z))xQT2Y;6SYuEf^u>Q}k6!^K6@jVWM$0mXPzz-B)`5$Hf%>1Wb^JjNjyZoW&W@CLk z9zXLQkH1`>R{y)J*8lGMwEEv&|LLh_YvC-!_E)xlD}LhjbG`j@MNoO%8kh)iadNVA z3b6cp@xOa0S-6{6Yf4x=PF<&;0}{x_^Ow`V*ZfCMt^exzq~Lg5S8F()gwQ8`m!pJr(@M^_0dh?ccb5iRh`|H?F5Nerf;4 z^-Dxg1;24UrSVJqH?ChIdMfyh>nV+2+P`uA646t^Z(L7l{L=o7>z9b03V!2yO5>OI zZ(P4b^i=R0*Haq5w14CJC8DQ--?*OA_@({7;zIc6BY!5gkI(tJJwDJ^Op6fr_%I-u zk+iZr0N_de_)uXW0C4^A_`U}KxUd2M`vw32Un&5AYnSl4PYM9wIFXSMRdxT8k!h7c z$!{Cn73xW|{ooGk8a2CqXVq+J9no&_l_-#{?Av*fO+wq6(SW{CR^!SdmNrZj)o25sq}{tT9)MUu%SVMrX_h zSM~^!ZguY3-R~FRC`M(UA1H29YXc8(zRlkirUr*Lg?>(X&351ULt#d<@y*%tHZpyo zs@D6sXY9=81hUJ6VRUorw+mkhWa({~bvFaH-z1GQthA1Nhc28+%YNIh^6mP-!Ft9k zyKc_&VbugOva!AQR{xqWUvx-V*qTpxaXe9l&XhE=Ub|dpxe5%)k=Bg*$nYg-?TEN9GC=4J*O0H4m~Oc(Lj|%~+VbxgOF|8JiJO zgOh&bOAy_YI=VzDINv&kfgWS!;u*E#Zg7s~i^C>+XYC$&g(niEMQ>VuAFlI|IB+Ta z!wbw%$#@21Yny!}OkqgyfO`ro;9PyqDIp|vPDr#X}R52aslZZ*Ae|eo~tA1Gso^=hQmBeAO9qL~SKI4pv z)CF+93-I#SP~WkA4hJh)Y1VFvFG}NAlk@C4jG*@vaEsJv*nW`$?v^|wQ40~)wE|xc zAgGSLMv{Ncn=dem~cQ?7Ut?L-o}qQ<-= zY)J>Dg<{r_+Wzd4fw~X`TyS1fTkaSeM}2_4jd(BImKY5b;}#Z6?J+P?ClnnA!=JXE ze89+vcSF7BdYzd=y<@@rg!w$|3<@xz4MMK9Yys=C7h^ckY z$e=Wype&X7Wd7><8Kj}qx*6?|XuE|f4mg^|uBvVf)(!q{w6g?0y&G5gsj9Mdxc3T5 z_(|fyC$QDN520u$dKVEK%YkZX4F$QV|4C9_eGKAkYhnX zS%ao(ou{=m(3z3(b)GWfT@*GssNMb}H&|Zn1d1}pkapX!l_Qr^K_`l`mxiXFw(Lew z3-t$Wb#WCo<=(qo1A7hnIqxeXQ;t9Gs1s{haeDi1KI3%D+C(5UXLIsnt(EdCn$cbo zY@glX_xcdqLMQ!YU)OmcfJcb`l%Ik{lX`VgqAR0sRMzU_qM)A&8f$4GmT+#mZ|X>S zMxifS-j!aa?!72Oh~_&&JD?5)AUcJ4RzHHVB)^T=~|0HTw z-fcy}AWQU>d+$nz;I&&q?5w)XWjhAhgvg#A(IrqY7=Gr}k<1DZ`W6_0 zrMb15XF2qOj{d>4(^CR0d;Z6h1mC8eYH{P>YiLL2E zHbf}2zSQxZm-L0vz<#e09CToRqn|~=TL*$Ij#B3vW<)C_eh~(brY*&;W*_?-2Tx$N zyRP37Fs?jCug>d;jl#R>-5}|(F4n-&Z1C%3C^0`UxNZgkSKwH>ysnzJ=hC9Quo{Pb zB%x|dVl-T8o!_pSmm=lcN2cX(^9|z?dAo3tS%ig2>x0;*S-eM_jKPaa_q19Mi4aMo z7#)tq4y0%+d5x{zwY>|t6w>*_hiTxNq^R__ppe+O#8|Z4~mKHPD?0C=xrus1jFla{m*+inxa@}_^TdYY3XA8|_4%VQ8?hL@nbr5dv5a1Av zy*|6?=F=CB0DePw_+oC35Y| zmny`_6t}%XINOg)T7D}ml{-iIbu&|vMZl_b9#SXv5vfqm^=UT^^a=;CEn`|_@CF>+GNIpv zM);|9I#I4dY%j)Dk#^?UygH@!sD0MA(al~>>6KocL9L4}p#%)cL#v{2Bnx^!oFyDkQ6#*lRB4ub1Mlq380(TXaCT&XSO zW`IGYNlWq*Ukb7IewPbl*6T{T6G(nK_66C;@u#}GW04jqEzj=Z89pOF`PEz1R! z(ivgLftPplb!tmXk}|Vf!%W(ESj{rJ=V`8U=L8lur3x9$t_)R zxzn_nRVC2iM=|8zkU(&go~j=02Ty=g?ehu?o`f_wccOwNh((%CgqJEyy~34-9~#s%K5%@ z-HQQ_{up40V49<_$Z1OtS=$XXw&pH?w3-@i7CwGuQ;zM%LWhXSF2f=kHgB4+4;>`J z%DKvtn@o7aT*Nlfd#(XGm_yywGxdj1B@)9)xN+~LKD=Te zSp%s@hI(~2yM93_pDRyH>4YH^JsVN8SsT-bMgzwQHyX4Q#QVlmM%07hY-#czwyNc zCyM-Cc%E;7ny8cJ-N};@G2QoHBCx||sgCR-g9_dSaOo*ZvGNBK?=Ee>O68AxLCZwZ zrZ7d0b%>Kq-nps|*5$>dVd_-JuGvf4UG^f)2CS}M$)kY2wh^*FY(lTzIGU~efEgr5 z%5DLMvH=A>AXL5HVCQHF!jf{-N}Z}VU7>a=pa;CbhLqw0m9{o!k!*A`h)}UQ@{Yn_ zB^eMWRYm7XDst(4O_S^$8}D;Ffzx1qDT^mtPvt{%$=Z^=Nfqa)PBXC~R_DZ3%%dqL zXGWkGU*P?b=sVQ-5=z)gbaGkwik!ROBz`zSvr+s|5v(~FXLA|_S3lupyV-Npha~nK zs#jG0nb7f52DBpOvThl~UA;Fu-ESl~+-UiEEcEx%YG2q>Gw>z~Yj{+40qM-|0N2Zy+nL`M>O*b1%P7;;Pfa`Jib?0M6ox134>1{T7 z0ULO=yM{KFs#>5rEZ9tm4Zb&eWP%M~Ht>E2@ymz3dqFq6f#&TadAS@pyH0qDY;19d zOC)$?iC2!q^=$Sj@m*|*1*q=%&Q!T%cu3ur<%Nh*?nEM+$PzCOcu3#Y@w{pDNbLOhaf;_;{heP@YkL^8XaYBXS)#`om*MDQ@H5~_9Ii>jIFF?ea(+CCP)o2& z`-6cedz(0h5^-d!G=~Ttlpr+jk)bCSlrYdKU`vaqW$y7BNMcypTHr&7V#`QS=c_>? zpTWZe&{}${FY}KtYiAE_-amSoXs@{m2SlWLYZSkA@2Y?7qtp!OJ(&W7AGQx7!F?`z zCKTQ=mzTQM6Wy?8u(irzcCuBGZ~5e9)L0V{Yi@%nhT-($tV*hUVdwJ(N82p)KE~ko zXE5qeSpm1QfPmCc+m5!HPeNGJb%*==VB{L?4q_i9{`#nmC z|MDBROS$HL=bPYkdd5-hGP9bLpm7U0qnT4h7()qkaFPP*lqQN{^X@d7&aN@6MjoJL z8I2um{VA9Uqlo)5o%_<_@~m18K%G0f5FxYkQf6=sL9K@`@|%I6X5-AJ4R#68RD}Zj``( zN>H(vvLFY|*ci5Uq*fIa&vCZ*oX9wlF!O;`vH+@}VJLSjL^6S#%7~dZ;`5N+3R};c z>q2aRXl6d`U}h}gr+4D!D;HI*P}T)YVo@j!-2j|5iUZd?-^9gFH6Dqa-YMRNNsKH4 zm}0qv#tE8r>2Ez`VhB>TC<0`UbmLe~Lb=2d-`pPVt0%?#qt%pxeN;5&US!8ajYnGr zW1#NpVN*6IzhMoM8c)CzH9Q|g_4EvATJ;vn?oU#KNbG%|osJ=21kpNYElY=k*pe#b zM6NAy<)Vjs5~!QRXcynI;G#!~-a3RN8^}D^#4y~()zdFB#%UTxWFew;55#g}#ja!w zyHV87b;ch;$+fI(hvpBGKH3LKRStG;V}47-0#f)c7_y&bBWhWdSIRN5-`JJ6u_YDY zPDsQZQm{uZ-&8iWl!=rBH+)Cuj`zN>hdW-TIlP|e2liKmRRQ}4t2;Zf?M9`H`_ z8v6mym?w4=DLHLm$0w>`R9G#2uu_L7Yo-F6w-vQSHosc=-m#L&R`n-|s=8qnkKx~` zX;JN<0y{pIp7aGDw{@^Fk#QJHTR`HJE3;C(zg*5i)a*Ko1om^fEu?-pW~%M){bp5O zr$1Zw4YMEbl~rBAIW+zT)b{g3A!>>sbDt$-@lTWM^Dr{v)JosL>X zlygNwP?}ZpIA<&1WgsIT&V+=2S=Kg`^u6(+#;$_tbxpl3+hx(5NKYOcTwPIDvEy>FJE_z_ShUJ@5j5vvR z=yN->Al5uJocftzy!-$TZT~%f0$$PMA~zPFy>7ne2-E1lU*<>7^Pa-85{!!1vidkwK2CCn*JD*a z8+0p`@WNDJ{IJdb1Zqk`=GL5iDs9#UIVMu{R@tayLtmdr-2_g06v7G!(0ZfaQj=Fp zZ2d(ZvMZk`1W~Mb+5f^C;7m7pR6aQ_?0AocQS(7(Rqei?q|z#N}~t74MC&ZKAtyv8sTA))Fu)WTRO+2y}ajeXS`@Cu#Ny}DyHOD zG@g=8cuk<{-7*{GQZI_c{_6mr{kJa}c~G2wY)$MVbJ(hX5V01f2*F2~!ySAsWaRdu z|8?I|1NhD@C~|gl$%P|6?K?^8mBV0QxxQi;m)oswae;QSqV%0>SuLBkw(n50zCkDV z@T}i~22z@Oy(Pp(TFS?|89x7aYQa%JX66bX;iQI_N~H%x*-7RMYswZ~L4ma8Lkcy_ z7<>`x(OM0O%3}}PZfj$T`Mb3kyJtHg86fhIVwAMbN#u$zsYKDh<*>fT>#~XiPfEAO z36-i*h=iqQ7mDf0P^2tarCH32r0&>de9~aBcfM~!z?snGRw9ICny1hh{!N@$=g@sJ z2+HNG6iqvf!E)>*kleaXcy$H)YRYLe^I>?l0NpFEcNi59rxYbQ3(1f8=LL~o-Tsx< zk2WB=$*haRP9+LulEe?)#?OE>pZof`gt_<(qgn)fvcghZcBgdFNrb(%59!P`7F!|^ zlxH8rPF)zcP}-pQpK}Z}P%+WPD54cp#xyLyN%5|`yk~S178E_c)7XZCPUJue%Th8n zg5`8~xr`KvZFzGnSi|_Z_%FA#tsGmK9>aqMjIWJR5;hE7Jh5l@>BSK?_rz7DYl#oF zJ3w0GI-ozmpbLSjyN7Ftx0);X{4%gBHMg70mLGT2W=fnI2X$| zRzfrA%6vCa6kOOjzOmW|(t{0``u%to9LERE>*t<#1V)E^yenTfowo-USq5OKTChL&+}UW6QC<2G+(}1*9bl4)#vd(vvW^@7~+UWRpON_Y4-i z;Dz$Q1n=dqbT~k;L0Ffc&mNoy(7NX;Rz2QLZSIsD#b8wvc{jT7cAqA7{!R0xc{x6G zkxseGsAwt|;md<;igJ zMkVg>oP4mFO&ldi1uEO#-W@ zr#zhcz5M0*GrSi%R^B0gz)G7{PjCGZG5;Y(_eSmoCArD2np^(jX`TXe+*B%KG~(m& z({VdC2gibl?oL;h6Xy%IDaZ zB{(Z<4yLzda`JrYhD43u8r09ex|g8AL>B%6-((n zVsH-o6Y`)Wz8-Xzcz-()zan;5R!rzC$!};H8mfjD{+fBC>%;TnR6&H3Z(9KdFv!?l z1Adm}<@M@9W@gE(k!z$eMX_a#ELsFT3i^dhs*p}@$AcA_$Yk;DHl0MuusInL#R`Pf zuyR31^51p^;tPn14RuH4wY-x3yRR9O^v5UR-V?l${to%&O0wDC)4d>`u#~4W_r~3l zCGqN0l1RcJIYxgh?e5*V<@tG;_VH&+AfrZVN1N{Pt1oK93(LoDW5^03)VM&lY3w)YHI<@p@F&49}NY^d|t5s(gj~40#cwxx@F7LU%A*Btduw76C~_qSfo^ zFL=C~XwCA5)@962T)jDsw%bxc*wLS^|*GYe&ZZXBmcC^1$)O!QgUc)VXgH=|Q6Ap2E) zXxD+8qWtDc5UBd&1ALZ}=Cd!~k%E70dYF)iq${M01PyuAVQHe^Des%2}8#__@Mc;ZeECsL<&OB&`1C^8KdwO`k;~|ke|fEZfn(b-NGy}OTlp1 zqQ*qL1O?W_A?XJ<`0{Husq2yG&gBOqakrbbA@Lz3TsFiy6uNdG?q5RcY)kS zauF@XVcMT1c_%tPT(&mZl)uUT5Tqa_iTA^KIeHT(G5{xOVDw6bxs!!%Gc?ZWEa8I#M6?qIB`wLD!Z9Bg(qrKAgPt}# z`_0QbeHxTikV9~^ul{3x#`f+Vx(U3;y@-w7NFbTtN6aF{!K;gcB}GkItRr`8>GkxF zx$zsX9m&j;J3@l?A%G)aja4Eft>#@{Uf}g4G?%*!)89;I&)ZEby+5tg)T}rRyAs+B z$bw>bM?_CUbp3c#;SC1AiLTW5ye3MqCfT-Yu=3izTe-KGn1V}rG1xbHDHsgbyCbh^ z*?)J4&Gg0fo*T0v;XO;1dBUMVoXiLM0gDO&6g#DRn0zBb3_QehEYVuuo`JiT?5 zfl11TXolhbMp|;yU3I!2yAUIuJ5cPTbQxXhcIT3wy{y+QfS;X_sT+o(5L)@x?3JpQ z6fKXjb9>0>c25PW82^}wDt@90kO}N{zvRQDJI41h6?=E>N6Zm!OOBE#M;c3 z?8{(dxH>|SWZf~;pFJOYHtst`u#AtR92u&Q)YPNY4I^lsVuQETz6Q&Nj-|xfqKP6V z5Fn=U4N$2=U+Ah1;VA9cH4&&NlT0(LL+@R)1)Vs$s?<72-jY(}7#X=(wVc zf~Y!x7ilVJc5#rg>~SVx^TA2a{Tqi;qJ$lpZ)3&5kKuvGO=J(+%nF$(l?p8`&9+QI z#iGE(iTL&X=qh_r&O32}=P<%Br&ysksQ7;LI^1!vsC23MM$3ejT%QW3-{p%sU?fLq zIg0ct(`84^`|BU4!f6g3X+PK4MBpN&9boZ1?m$a}v?P`k2bcn8zl^b-;Mm0h(<>ef zV>+K0X?k$pI=Gz;P`xI9Z`OR+IoG;SS>)@ssn0_+RzL?&q#FMj^u1jU|5zNu| z?^9$mQuwhw_u0IB-bL@zo0aK0TG1($$3#Un;sb|1KEZDEecR4Q&0#VaGQ(~vrP>#V zPIPp3%8$Pkt?~@8K(gAgg5&MI{f+?Df%+`fd2MP+meEZdnw+_53u9fL?)DqlBn|>i zTTxpkIg!mhE9Mk7#gprOV{V-;`QsHS;d>+#Shp4BDEJm9t8x8VHJZ?e!4Kep>+%_9 zUSH=jC-ed5*}X3t%@vp50r-#=-y!8toE$@8y1?QPF$yqw8!&Q8v7o?kGVNYj6lB|B zuU02jo?!R_wF-RG!-?xWJ9?yg53MMT9sg*UJ(mFx;@+f+ubGGm<~)k>V1vG=6G|Wko-(u8%~8k1 zobx<3isCN++FVf?W_~7t5*xOxJ;K|8JA_$K9oga>{f&LYjp~hpVrLMVeqH>1Y zh-h*)?KjACK`xMm4PDQcNkZAKkzKHr?RfX*i^!eLKa-3A;gFL(dM!V7_~ZC+vZF}y zorbf`e<%sACD%M_QWYQdXa@GvC5C3JG=CoLCmN`ax@n5vCP&^l_iWoW1pmk)EmzY@j z+WzAJ)rk^=&6+_-D)hT{IK09LX`1K>yg?#RjyP}Qfj_D_&93>)B-}0QX(4R}t2N69 zbnTE8NOWa*p0S!rSQMQUl`=6ub>su@BDfk1qIaKouf7IKXTBwQ{api=ts`i z78>~QkZh!5Flzmx((uATnmDV1f1xyHlLfT1cJz47gM$^_JJA=(w1q+uh;RAfTOVtL zp4Hqr4IlD-r{jVGhxm2Vsb7pR997`w3!^DPvt?dxKUDiL8s3-)qoG%;A?kR54#C`Y z^YXTLj31rcz4kBWRo9G}bm%sbC>O|vUkrKk7WcEGpYjmc%+?TP$Y(##s+A-{$IW@2 z7idQS5d|W$y!v`JbplQ2NW#F`p*sAz(e%b~+n+S7J%xnqvw)n=bsl1Bs;FtQd=nsv z9D8KJ^^IpmlI2HMR@@$C5}W0!M1~=PX=4lMw^=o%cg+>lChYN&G4GHG0Bu-NhLKzN zD`28+UtV6Owm`;_n!T?2Qzht3q@gT!S~Qe^o;KJLgMIR=C9YEy%V&X1=Fk}SWY9X% z{mh{CAA1V2^g^&<3_`}Eo4_P8NX|n!33e_$zY>r5B*ckv_^Nm&#reT>;4885iE#;R+>5brVl}RD ztE?^3SofDyH6N>7!s}lXRe6~u$H9|$UQ>P&4GKc^^(9UaNpTkk%L_CBhDvFoXr*j3 z;2Kk@7vafeA+hT01?lF2L|sAgo9MJHVS~C^BZ-MMj=Pftp3wa(xy}~s+fJ7n@OD-- z)}9fJgfGnP%-Sc&H?6z3I8JBi~#C$cYI{=MrnAbmGxl=mVOw(#O>HS<*1UN)I$@$x-ag;1~FrJX5H_6f$ z3X1rlN}_LBtS6mvx(Q-11#7j#?q|i=1WW>51~9^jJ&3smP*HKhNaT*X-Ij(2Gke>6 z<-KjRi9?z&md_lDQKqG%WOEOok(lUi;Qg)N^!X%6TyX8T@G0N`FT%OY*~A@|Dd*AVU+QbB;h(M=W-PFcD4hmr#irr4AsBDZ{=4|e zqCs5cMjri2Ttzzest_cGTo_7O4%R}|*=nxBq)jOI>|yz-Q)wa{hgqqkSWPey*weh&t8*jnnAqU z(NKybh>fvPq2-UaAj4jrbp6JQ2i{Wm5kfK3wA`HkzSfnLWZY75 zQ2w2DZ~i7%WjBJb6OW6Ae?p5u0S@2A=pC_YukF=?zj#${=!LhOmo!^DeGu#Y*=9*R zQ}$soeILOK@R=9H&U_s^<#+*`wpArlaE=0wW7d)%MG5dyWUM;IfOfY_NF=N0Ws1uF zIb=e+2ViSLh92((B?FyD9SM@@+Z`N#B4cXH(z%Pov!+Jnwv(!|=kQc1#yp%+P_a7l zEJLpsVclo6xSBfqr&!o53l`){P9@e&kF#m5w!^g!7T?%oKn)CknV!!ju?q{Z0NuQu zmAT{#Pqu67;#RAGMVLvB1ayzY1+OFsQ#oxUeRnYUZp`ss&iJesM8W7+-3zLjPrq9b zCMbIOVJJUoees*4wS7Fqt4!Y=zarA@J7n2>e@tnGX3PcSn$_K5ALQwMt69Bll(BuT z_LXB64DP`*Grbrd#rp>|7+W%#O_Uh%rUo%+OcmlQ34MD@2-JGt`7s#t22k&J*E`k^ zO?^nlm!;Nq221!iyqg=ASYSEO3!!ftRuN*#0XPLJvyEBPPGjA**OV}ro&rR>I}1U~ zgN&YNP?*n`zV@y(pmlyb7C#$!Mxf3yVNwL^c3}~8w<-vC(q{??z#kA@3@@^VMdcUK zsN4cW^9)gpbayJ{%Ofr4@}wPk0-#I4s8r8{mhMK$xe7lr5zj+lk`)-CBe}50s?JCF zi_etT-OSj>J1V$UA`)8TKl?Jy>>^~b7NP*+YKu^1V)l5o+shSGQjHBsf+Z{$l*Ro@ z27|5Z@N)-C=p`%CbLDI8SB$}hP_x?s9-$vZ#bXtQ(h-X5NBMq4^2?c%4UQ> zY)p~ec{|mC73Fy%4vKEbg3n>2sCB12c$AHZY^Yyp^L-FsAE zo(fEUCtA5Q57EHV6MM^rSQp|U?gD_M#PldFN&q%d+`S(k=)Vr4yOf0In)AA^C_kCPp+yexZxjCdVmfJ!&HfCqFhJhe=&o zRJ6?t6&jlH_g&HXSQeC5?5}mq2;DtG1r%dV$i}FhOJL~mw$KWSd5%UkUDsC&%UwS1 zy^i;e?dggXFSaIUFyl53BiG&22y%8fmg*kJ+fJ4-peSQj=1rfJuJ=cMzQP003c(M^ zsVaKz7z_}_K(QSd3f~-jrFUrGzDiR_vx7D;m61gf$26o&gjXZ8$8g%JVkKfk<4@>s zq=5(}BwM89B^{z(>912uKSbSGL{^`Ti)ifwb zNW_KT@>=vPd)kg)boe_7oCTD1P8YFv+@Z^odB#q`ySQx_J-mjZsQ4n?t)NOo?y8(V zJnK^>#}E+=aJfa03>g?YPL1K+RigCN$>6!XCf{|?SsE9MtNEq+#7BoAQJJ!YRn&JL^-AAH{m0y(UV+SYem1}`$KO~7D1c0zO_Hxs+N{W(Hn-6m87!Jc}V z;;=`3!ivlfKP5kEt34%us!G<>6KWND!H^>?=P#;#QxF=VCzSGvP?%k?iELGHS#jZ+ zkUG{r_%hrC2>5`yA_BDFUl6z)%3q|+>4Wh`-0-1(eNsE}L2sYFA=1izv=hGi$o zxI0;u!>GmkLt8YtSQrFTSnzfFyMFClK?M;l^^*b2yvl_k0!^$nBuQE*? zeN*YDyvP7!)^46r@kD-v2Uz=Whv+#(GQ)*=P$lAe-g7^j+&qf^OzHh>?2gcNlYmu5 zaSZ*U7lOv6mCi^S0x#Z;o^Qc-aMg~u4@wqaxz^58lz}`yQ#fU465VUE?|xJJ1kiv& z_DML&?{Y)DgI+fs7M{0TTkAzf6AvaZD9`chsboVsIb0_3dc~O>l`6Y<|FTArf+|lx zRQ&fOER;R9UeKZy+&&)U(W3b>68an~GxfzrlUPu|MlPmVXs_tAyao@EJa=95q_BMn zglk{>uWyrLVe~dWW5{!k24(Juz^MUG{R$y+!x#5(`68d)@@7_!*k)Liol|MsT%P)E ze6b|DPb3$Fv$ex)r>)tsbA9maKt}MXN=fX@3Aa8l{2nJqkwsPQe;RnGX5c2D_m+$hjPe2y_s`R|>iaz15T8Z5>L!p@T``sCDqG z6JI+Kw{ly!hSS*sDSaRCO@r!1wGHGB73P20*3?4m2+U0rcP^r^mvi|9fhx`?R&QHY znyw@ecZfSNNK{Erfzo$;m>P=YuTCFpRLVr5-9}R<*b={R5}p^yYOGEvuHb+w>Zs_h zAfVua76}h?)SFElJmr?~2h;JAabEAe~w%A3wCipx%E27iEFRUC9)yWN^FgXtww%3^>#c2zJg{!q^ zbv5xq^q%OlSPmiV=4tALCXL>TooK0&js!LaUW(dAE$%^z>K<{mDVm-?&6mnNli zslkzfy03zWtvzD60+lW@@dT%@BYPJ6)k$7fxN4X2bl!AA+~1R)VSOFMuIot`%DM{Q z9`9e-$PI7&1V*w!#$hU^7Zw%8x5?i2HqcPCwdBeVVf7C`+*rFxK%L5MkqDsr9e0{B2fbCsc-wkG#8{K8WxYPRTk}BOcMaYS;O%!?& z(rW-IsS#cXpU2exTEC>_g%LsthQ>HK@+o2h9l1SQi>U)27fMSF0^+sAVd3|v$-2gz ztqIR}rQxpEhujYLMcEtt`S&*+4YA11?4xUfpaIx2<>`qWWi3+X_luN+dRr0a?Bdb& zw2f9AAr#Qa$-1BfmrfGfLqqzec^BP9XmwK5mJH|130>*tkgbVN0=f0Vx!y&N_T_rD z9S`~CMMCS?rf&0Br{W3Ursn-#DCE>A7IPM7=Re;O_vII%7A7_t;Dvmfju-mlUJ7a> z$;pzI$PXV=&X90f6%y`6(|6t)*De0H;)NF~>jP(`AC!wR5n`&U4AED@4Frzn1~e%O z^N3}!NlMzEuLlLl6G(qi8Pt5ertAXaqr!xquWd9Ew)S!f%cR5+N6bJsvua+qX%&)i zWLIR4gQ|9qnn9)jmg;*^&~eJvk5fo<5HlMj;4DO{i zQY^K1PTR(WHkn>vkT#%^tq#OTM+x~2MI$Exfbr8M7vK>p_d^h26iuZ+} zp47nZ@sCm*-BB)K=+-#u+oST54A=S=yM-i{izH5X*nIN54mN7sC07@byP#Hlt3!iv zY@JOg9Nr#+vP@kGHL)>*Nwp_*Y#nwh(?9sWjeDml8XxS_d*BgEmTx6Y?I@h&HGWg4 zS$#5(90gZau32L0w12^^WqgesG>YF&2}f?U-qa|LS}WyaUlt0cfB88%R?YCi_$Dr6 z_)u`*-Gl`rMO2B=(SlNl?13;qil%UzX7c($XWHnNWk1Mt5e)AO7MU2pSI|H+73$W$ z*?gv+r5kf6Bj(U|scw0W9f&1g-l~uWsn`Hw55G Date: Mon, 11 Sep 2023 14:41:45 +0900 Subject: [PATCH 04/82] [NUI] Hide ParticleBlendingMode and ParticleEmitter --- src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index 498f7f8f7d6..cf6246a2cbf 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -27,6 +27,7 @@ namespace Tizen.NUI.ParticleSystem /// /// Enum defining blending options when rendering the particles. /// + [EditorBrowsable(EditorBrowsableState.Never)] public enum ParticleBlendingMode { Additive = 0, @@ -60,6 +61,7 @@ internal enum StreamType /// ParticleSource and ParticleModifier callback interfaces should not be accessing /// Event side (NUI) objects. Both callbacks are executed on Update thread. /// + [EditorBrowsable(EditorBrowsableState.Never)] public class ParticleEmitter : BaseHandle { internal ParticleEmitter(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) @@ -572,4 +574,4 @@ internal T Get(IntPtr cPtr) private List mBasePtr = new List(); private List mInterfaces = new List(); } -} \ No newline at end of file +} From 3a2a2124f0420a5525476cf78c78ebed607bd1f2 Mon Sep 17 00:00:00 2001 From: jmm Date: Mon, 11 Sep 2023 16:39:59 +0900 Subject: [PATCH 05/82] [NUI] Fix partial update issue --- .../ParticleSystemSample.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs b/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs index 550dc6c76ba..ba306597a8e 100644 --- a/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs +++ b/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs @@ -151,9 +151,10 @@ public void Activate() var view = new View(); view.BackgroundColor = Color.Wheat; - view.Size = new Size(1, 1); - view.PivotPoint = new Position(0, 0); - view.Position2D = new Position2D(mWindow.Size.Width/2, mWindow.Size.Height/2); + view.Size = new Size(mWindow.Size.Width, mWindow.Size.Height); + view.PivotPoint = PivotPoint.Center; + view.ParentOrigin = ParentOrigin.TopLeft; + view.Position2D = new Position2D(0, 0); mWindow.Add(view); // Attach emitter to view mEmitter = new ParticleEmitter(view) From 506452a8e21eaf4f2e3d5b9a5f019d7183c5f251 Mon Sep 17 00:00:00 2001 From: jmm Date: Wed, 13 Sep 2023 16:20:43 +0900 Subject: [PATCH 06/82] [NUI] Add Dispose() --- .../src/public/ParticleSystem/Particle.cs | 3 +-- .../src/public/ParticleSystem/ParticleEmitter.cs | 14 ++++++++++++-- .../src/public/ParticleSystem/ParticleModifier.cs | 9 +++++---- .../src/public/ParticleSystem/ParticleSource.cs | 9 +++++---- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs b/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs index 5315592867b..c5234f79481 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs @@ -496,5 +496,4 @@ internal uint Index private uint mIndex; private readonly HandleRef mEmitterRef; } - -} \ No newline at end of file +} diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index cf6246a2cbf..44c32d59b86 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -34,7 +34,7 @@ public enum ParticleBlendingMode Screen = 1, Default = Additive } - + /// /// Internal class defining data types stored in the data streams /// @@ -89,6 +89,16 @@ public ParticleEmitter( ParticleEmitter particleEmitter) : this(Interop. Particl if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } + /// + /// Dispose. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void Dispose(DisposeTypes type) + { + if (disposed) return; + base.Dispose(type); + } + /// /// Assignment operator. /// @@ -227,7 +237,7 @@ public ParticleBlendingMode RendererBlendingMode } /// - /// Gets/sets texture to be used by the renderer + /// Sets texture to be used by the renderer /// [EditorBrowsable(EditorBrowsableState.Never)] public Texture RendererTexture diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs index b19ed3969d7..2660ec755e0 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs @@ -96,12 +96,13 @@ public virtual void Update(ParticleEmitterProxy emitterProxy, List par static ParticleInterfaceRegister gModifierInterfaceRegister = new ParticleInterfaceRegister(); /// - /// Destructor + /// Dispose. /// [EditorBrowsable(EditorBrowsableState.Never)] - ~ParticleModifier() + protected override void Dispose(DisposeTypes type) { - gModifierInterfaceRegister.Remove(mInterface); + if (disposed) return; + base.Dispose(type); } /// @@ -163,4 +164,4 @@ internal void SetEmitter(ParticleEmitter emitter) private ParticleModifierInterface mInterface = null; private static IntPtr gRefObjectPtr; } -} \ No newline at end of file +} diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs index 0fab75fd1d3..2635aa003ca 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs @@ -107,12 +107,13 @@ public virtual void Init() private static ParticleInterfaceRegister gSourceInterfaceRegister = new ParticleInterfaceRegister(); /// - /// Destructor + /// Dispose. /// [EditorBrowsable(EditorBrowsableState.Never)] - ~ParticleSource() + protected override void Dispose(DisposeTypes type) { - gSourceInterfaceRegister.Remove(mInterface); + if (disposed) return; + base.Dispose(type); } /// @@ -203,4 +204,4 @@ internal void SetEmitter(ParticleEmitter emitter) private ParticleSourceInterface mInterface = null; private static IntPtr gRefObjectPtr; } -} \ No newline at end of file +} From 4b75e58e6881e5cf1e34fdab0b8751161c4c4805 Mon Sep 17 00:00:00 2001 From: jmm Date: Wed, 13 Sep 2023 21:21:56 +0900 Subject: [PATCH 07/82] [NUI] Remove unsafe functions --- .../Interop/Interop.ParticleEmitter.cs | 18 +++++++++++++++--- .../public/ParticleSystem/ParticleEmitter.cs | 16 ++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs index c463e81df86..b6e04aea68a 100644 --- a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs @@ -112,11 +112,23 @@ internal static partial class ParticleEmitter internal static extern int NewParticle(global::System.IntPtr emitter, float lifetime); // ParticleList - [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream")] - internal unsafe static extern uint AddLocalStream(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, void* defaultValue, uint typeSize ); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreami_Int")] + internal static extern uint AddLocalStream_Int(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, int defaultValue, uint typeSize ); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Float")] + internal static extern uint AddLocalStream_Float(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, float defaultValue, uint typeSize ); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector2")] + internal static extern uint AddLocalStream_Vector2(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, global::System.IntPtr defaultValue, uint typeSize ); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector3")] + internal static extern uint AddLocalStream_Vector3(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, global::System.IntPtr defaultValue, uint typeSize ); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector4")] + internal static extern uint AddLocalStream_Vector4(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, global::System.IntPtr defaultValue, uint typeSize ); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_GetDefaultStreamIndex")] - internal unsafe static extern int GetDefaultStreamIndex(global::System.Runtime.InteropServices.HandleRef jarg1, uint builtInStream ); + internal static extern int GetDefaultStreamIndex(global::System.Runtime.InteropServices.HandleRef jarg1, uint builtInStream ); } } diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index 44c32d59b86..1a0660c5242 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -324,9 +324,9 @@ public void Stop() /// Default value to fill the stream with /// Index of newly created data stream [EditorBrowsable(EditorBrowsableState.Never)] - public unsafe uint AddLocalStreamFloat(float defaultValue) + public uint AddLocalStreamFloat(float defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.Float, &defaultValue, sizeof(float)); + var result = Interop.ParticleEmitter.AddLocalStream_Float(SwigCPtr, (uint)StreamType.Float, defaultValue, sizeof(float)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -340,9 +340,9 @@ public unsafe uint AddLocalStreamFloat(float defaultValue) /// Default value to fill the stream with /// Index of newly created data stream [EditorBrowsable(EditorBrowsableState.Never)] - public unsafe uint AddLocalStreamVector2(Vector2 defaultValue) + public uint AddLocalStreamVector2(Vector2 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.FloatVector2, (void*)defaultValue.SwigCPtr.Handle, sizeof(float)*2); + var result = Interop.ParticleEmitter.AddLocalStream_Vector2(SwigCPtr, (uint)StreamType.FloatVector2, defaultValue.SwigCPtr.Handle, sizeof(float)*2); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -356,9 +356,9 @@ public unsafe uint AddLocalStreamVector2(Vector2 defaultValue) /// Default value to fill the stream with /// Index of newly created data stream [EditorBrowsable(EditorBrowsableState.Never)] - public unsafe uint AddLocalStreamVector3(Vector3 defaultValue) + public uint AddLocalStreamVector3(Vector3 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.FloatVector3, (void*)defaultValue.SwigCPtr.Handle, sizeof(float)*3); + var result = Interop.ParticleEmitter.AddLocalStream_Vector3(SwigCPtr, (uint)StreamType.FloatVector3, defaultValue.SwigCPtr.Handle, sizeof(float)*3); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -372,9 +372,9 @@ public unsafe uint AddLocalStreamVector3(Vector3 defaultValue) /// Default value to fill the stream with /// Index of newly created data stream [EditorBrowsable(EditorBrowsableState.Never)] - public unsafe uint AddLocalStreamVector4(Vector4 defaultValue) + public uint AddLocalStreamVector4(Vector4 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream(SwigCPtr, (uint)StreamType.FloatVector4, (void*)defaultValue.SwigCPtr.Handle, sizeof(float)*4); + var result = Interop.ParticleEmitter.AddLocalStream_Vector4(SwigCPtr, (uint)StreamType.FloatVector4, defaultValue.SwigCPtr.Handle, sizeof(float)*4); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } From 9f10983f0bd481562bfc1cf3c7c48d54f77a2b86 Mon Sep 17 00:00:00 2001 From: jmm Date: Wed, 13 Sep 2023 21:47:12 +0900 Subject: [PATCH 08/82] [NUI] Remove unused arguments and enum for AddLocalStream(). --- .../Interop/Interop.ParticleEmitter.cs | 10 ++++---- .../public/ParticleSystem/ParticleEmitter.cs | 23 ++++--------------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs index b6e04aea68a..ff888433ae9 100644 --- a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs @@ -113,19 +113,19 @@ internal static partial class ParticleEmitter // ParticleList [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreami_Int")] - internal static extern uint AddLocalStream_Int(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, int defaultValue, uint typeSize ); + internal static extern uint AddLocalStream_Int(global::System.Runtime.InteropServices.HandleRef jarg1, int defaultValue); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Float")] - internal static extern uint AddLocalStream_Float(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, float defaultValue, uint typeSize ); + internal static extern uint AddLocalStream_Float(global::System.Runtime.InteropServices.HandleRef jarg1, float defaultValue); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector2")] - internal static extern uint AddLocalStream_Vector2(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, global::System.IntPtr defaultValue, uint typeSize ); + internal static extern uint AddLocalStream_Vector2(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector3")] - internal static extern uint AddLocalStream_Vector3(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, global::System.IntPtr defaultValue, uint typeSize ); + internal static extern uint AddLocalStream_Vector3(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector4")] - internal static extern uint AddLocalStream_Vector4(global::System.Runtime.InteropServices.HandleRef jarg1, uint streamType, global::System.IntPtr defaultValue, uint typeSize ); + internal static extern uint AddLocalStream_Vector4(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_GetDefaultStreamIndex")] internal static extern int GetDefaultStreamIndex(global::System.Runtime.InteropServices.HandleRef jarg1, uint builtInStream ); diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index 1a0660c5242..acfde46ce31 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -35,21 +35,6 @@ public enum ParticleBlendingMode Default = Additive } - /// - /// Internal class defining data types stored in the data streams - /// - internal enum StreamType - { - Float = 0, - FloatVector2 = 1, - FloatVector3 = 2, - FloatVector4 = 3, - Integer = 4, - IntVector2 = 5, - IntVector3 = 6, - IntVector4 = 7, - } - /// /// Class ParticleEmitter creates a single emitter attached to a specified /// View. ParticleEmitter is responsible for spawning and updating particles. @@ -326,7 +311,7 @@ public void Stop() [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamFloat(float defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Float(SwigCPtr, (uint)StreamType.Float, defaultValue, sizeof(float)); + var result = Interop.ParticleEmitter.AddLocalStream_Float(SwigCPtr, defaultValue); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -342,7 +327,7 @@ public uint AddLocalStreamFloat(float defaultValue) [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamVector2(Vector2 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Vector2(SwigCPtr, (uint)StreamType.FloatVector2, defaultValue.SwigCPtr.Handle, sizeof(float)*2); + var result = Interop.ParticleEmitter.AddLocalStream_Vector2(SwigCPtr, defaultValue.SwigCPtr.Handle); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -358,7 +343,7 @@ public uint AddLocalStreamVector2(Vector2 defaultValue) [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamVector3(Vector3 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Vector3(SwigCPtr, (uint)StreamType.FloatVector3, defaultValue.SwigCPtr.Handle, sizeof(float)*3); + var result = Interop.ParticleEmitter.AddLocalStream_Vector3(SwigCPtr, defaultValue.SwigCPtr.Handle); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -374,7 +359,7 @@ public uint AddLocalStreamVector3(Vector3 defaultValue) [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamVector4(Vector4 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Vector4(SwigCPtr, (uint)StreamType.FloatVector4, defaultValue.SwigCPtr.Handle, sizeof(float)*4); + var result = Interop.ParticleEmitter.AddLocalStream_Vector4(SwigCPtr, defaultValue.SwigCPtr.Handle); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } From 2bb3c43f6c633b9c704bd9c7fa1dbbaeb796bbb0 Mon Sep 17 00:00:00 2001 From: jmm Date: Thu, 14 Sep 2023 10:29:06 +0900 Subject: [PATCH 09/82] [NUI] Remove underlines in function names --- .../Interop/Interop.ParticleEmitter.cs | 20 +++++++++---------- .../public/ParticleSystem/ParticleEmitter.cs | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs index ff888433ae9..de22393aeab 100644 --- a/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ParticleEmitter.cs @@ -112,20 +112,20 @@ internal static partial class ParticleEmitter internal static extern int NewParticle(global::System.IntPtr emitter, float lifetime); // ParticleList - [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreami_Int")] - internal static extern uint AddLocalStream_Int(global::System.Runtime.InteropServices.HandleRef jarg1, int defaultValue); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreamiInt")] + internal static extern uint AddLocalStreamInt(global::System.Runtime.InteropServices.HandleRef jarg1, int defaultValue); - [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Float")] - internal static extern uint AddLocalStream_Float(global::System.Runtime.InteropServices.HandleRef jarg1, float defaultValue); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreamFloat")] + internal static extern uint AddLocalStreamFloat(global::System.Runtime.InteropServices.HandleRef jarg1, float defaultValue); - [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector2")] - internal static extern uint AddLocalStream_Vector2(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreamVector2")] + internal static extern uint AddLocalStreamVector2(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); - [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector3")] - internal static extern uint AddLocalStream_Vector3(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreamVector3")] + internal static extern uint AddLocalStreamVector3(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); - [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStream_Vector4")] - internal static extern uint AddLocalStream_Vector4(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_AddLocalStreamVector4")] + internal static extern uint AddLocalStreamVector4(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.IntPtr defaultValue); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ParticleList_GetDefaultStreamIndex")] internal static extern int GetDefaultStreamIndex(global::System.Runtime.InteropServices.HandleRef jarg1, uint builtInStream ); diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index acfde46ce31..aae0f440907 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -311,7 +311,7 @@ public void Stop() [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamFloat(float defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Float(SwigCPtr, defaultValue); + var result = Interop.ParticleEmitter.AddLocalStreamFloat(SwigCPtr, defaultValue); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -327,7 +327,7 @@ public uint AddLocalStreamFloat(float defaultValue) [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamVector2(Vector2 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Vector2(SwigCPtr, defaultValue.SwigCPtr.Handle); + var result = Interop.ParticleEmitter.AddLocalStreamVector2(SwigCPtr, defaultValue.SwigCPtr.Handle); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -343,7 +343,7 @@ public uint AddLocalStreamVector2(Vector2 defaultValue) [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamVector3(Vector3 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Vector3(SwigCPtr, defaultValue.SwigCPtr.Handle); + var result = Interop.ParticleEmitter.AddLocalStreamVector3(SwigCPtr, defaultValue.SwigCPtr.Handle); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } @@ -359,7 +359,7 @@ public uint AddLocalStreamVector3(Vector3 defaultValue) [EditorBrowsable(EditorBrowsableState.Never)] public uint AddLocalStreamVector4(Vector4 defaultValue) { - var result = Interop.ParticleEmitter.AddLocalStream_Vector4(SwigCPtr, defaultValue.SwigCPtr.Handle); + var result = Interop.ParticleEmitter.AddLocalStreamVector4(SwigCPtr, defaultValue.SwigCPtr.Handle); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return result; } From 49e9719e151cc1a4ad4d168d89f2b432b54e7ea6 Mon Sep 17 00:00:00 2001 From: jmm Date: Thu, 14 Sep 2023 10:38:49 +0900 Subject: [PATCH 10/82] [NUI] Use Disposed instead of disposed. --- .../src/public/ParticleSystem/ParticleEmitter.cs | 11 +++++++++-- .../src/public/ParticleSystem/ParticleModifier.cs | 12 ++++++++++-- .../src/public/ParticleSystem/ParticleSource.cs | 12 ++++++++++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index aae0f440907..887152870d8 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -80,8 +80,15 @@ public ParticleEmitter( ParticleEmitter particleEmitter) : this(Interop. Particl [EditorBrowsable(EditorBrowsableState.Never)] protected override void Dispose(DisposeTypes type) { - if (disposed) return; - base.Dispose(type); + if (Disposed) + { + return; + } + + if (HasBody()) + { + base.Dispose(type); + } } /// diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs index 2660ec755e0..ea8e1acf4bc 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs @@ -101,8 +101,16 @@ public virtual void Update(ParticleEmitterProxy emitterProxy, List par [EditorBrowsable(EditorBrowsableState.Never)] protected override void Dispose(DisposeTypes type) { - if (disposed) return; - base.Dispose(type); + if (Disposed) + { + return; + } + + if (HasBody()) + { + gModifierInterfaceRegister.Remove(mInterface); + base.Dispose(type); + } } /// diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs index 2635aa003ca..03b99ee4de2 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs @@ -112,8 +112,16 @@ public virtual void Init() [EditorBrowsable(EditorBrowsableState.Never)] protected override void Dispose(DisposeTypes type) { - if (disposed) return; - base.Dispose(type); + if (Disposed) + { + return; + } + + if (HasBody()) + { + gSourceInterfaceRegister.Remove(mInterface); + base.Dispose(type); + } } /// From ed92cad7216d129b93f872530347f218e7c52c31 Mon Sep 17 00:00:00 2001 From: jmm Date: Thu, 14 Sep 2023 10:58:31 +0900 Subject: [PATCH 11/82] [NUI] Change RendererTexture(texture) into TextureResourceUrl(imageUrl) --- .../src/public/ParticleSystem/ParticleEmitter.cs | 11 +++++++++-- .../ParticleSystemSample.cs | 7 +------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index 887152870d8..182bd5ab13e 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -232,11 +232,18 @@ public ParticleBlendingMode RendererBlendingMode /// Sets texture to be used by the renderer /// [EditorBrowsable(EditorBrowsableState.Never)] - public Texture RendererTexture + public string TextureResourceUrl { set { - Interop.ParticleEmitter.SetTexture(SwigCPtr, value.SwigCPtr); + var pixelBuffer = ImageLoader.LoadImageFromFile(value); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + Texture tex = new Texture(TextureType.TEXTURE_2D, PixelFormat.RGBA8888, pixelBuffer.GetWidth(), + pixelBuffer.GetHeight()); + tex.Upload(pixelBuffer.CreatePixelData()); + + Interop.ParticleEmitter.SetTexture(SwigCPtr, tex.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } } diff --git a/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs b/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs index ba306597a8e..462ffe5465d 100644 --- a/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs +++ b/test/Tizen.NUI.ParticleSystem.Sample/ParticleSystemSample.cs @@ -172,12 +172,7 @@ public void Activate() mEmitter.AddModifier(mModifier); // Load texture - var pixelBuffer = ImageLoader.LoadImageFromFile(IMAGE_DIR + "/blue-part2.png"); - Texture tex = new Texture(TextureType.TEXTURE_2D, PixelFormat.RGBA8888, pixelBuffer.GetWidth(), - pixelBuffer.GetHeight()); - tex.Upload(pixelBuffer.CreatePixelData()); - - mEmitter.RendererTexture = tex; + mEmitter.TextureResourceUrl = IMAGE_DIR + "/blue-part2.png"; mEmitter.Start(); } From d552157dddac9a6f658fe3e807fd81f86897122b Mon Sep 17 00:00:00 2001 From: jmm Date: Thu, 14 Sep 2023 14:26:16 +0900 Subject: [PATCH 12/82] [NUI] Call base.Dispose(type) at derived class's Dispose. --- src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs | 5 +---- src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs | 2 +- src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index 182bd5ab13e..37d41f466bc 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -85,10 +85,7 @@ protected override void Dispose(DisposeTypes type) return; } - if (HasBody()) - { - base.Dispose(type); - } + base.Dispose(type); } /// diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs index ea8e1acf4bc..84350043a0a 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs @@ -109,8 +109,8 @@ protected override void Dispose(DisposeTypes type) if (HasBody()) { gModifierInterfaceRegister.Remove(mInterface); - base.Dispose(type); } + base.Dispose(type); } /// diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs index 03b99ee4de2..2257ea0b2b6 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleSource.cs @@ -120,8 +120,8 @@ protected override void Dispose(DisposeTypes type) if (HasBody()) { gSourceInterfaceRegister.Remove(mInterface); - base.Dispose(type); } + base.Dispose(type); } /// From 42cea847d6e54f535577c0c37531cb04a66c8405 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 12 Sep 2023 10:32:17 +0100 Subject: [PATCH 13/82] [NUI.Physics2D] Add binding for Chipmunk2D physics engine --- .../Properties/AssemblyInfo.cs | 4 + .../Tizen.NUI.Physics2D.csproj | 17 + .../Tizen.NUI.Physics2D.sln | 79 ++ .../internal/chipmunk/DelegateExtensions.cs | 304 ++++ .../src/internal/chipmunk/Delegates.cs | 304 ++++ .../src/internal/chipmunk/NativeInterop.cs | 125 ++ .../src/internal/chipmunk/NativeMethods.cs | 1228 +++++++++++++++++ .../internal/chipmunk/PostStepCallbackInfo.cs | 58 + .../internal/chipmunk/cpCollisionHandler.cs | 88 ++ .../src/internal/chipmunk/cpContactPoint.cs | 48 + .../internal/chipmunk/cpContactPointSet.cs | 53 + .../src/internal/chipmunk/cpPointQueryInfo.cs | 54 + .../src/internal/chipmunk/cpPolyline.cs | 50 + .../internal/chipmunk/cpSegmentQueryInfo.cs | 54 + .../chipmunk/cpSpaceDebugDrawOptions.cs | 226 +++ .../src/public/chipmunk/Arbiter.cs | 387 ++++++ .../src/public/chipmunk/AutoGeometry.cs | 117 ++ .../src/public/chipmunk/Body.cs | 767 ++++++++++ .../src/public/chipmunk/BodyType.cs | 67 + .../src/public/chipmunk/BoundingBox.cs | 161 +++ .../src/public/chipmunk/CollisionHandler.cs | 341 +++++ .../public/chipmunk/Constraints/Constraint.cs | 301 ++++ .../Constraints/DampedRotarySpring.cs | 143 ++ .../chipmunk/Constraints/DampedSpring.cs | 175 +++ .../public/chipmunk/Constraints/GearJoint.cs | 75 + .../chipmunk/Constraints/GrooveJoint.cs | 93 ++ .../public/chipmunk/Constraints/PinJoint.cs | 84 ++ .../public/chipmunk/Constraints/PivotJoint.cs | 94 ++ .../chipmunk/Constraints/RatchetJoint.cs | 86 ++ .../chipmunk/Constraints/RotaryLimitJoint.cs | 76 + .../chipmunk/Constraints/SimpleMotor.cs | 61 + .../public/chipmunk/Constraints/SlideJoint.cs | 96 ++ .../src/public/chipmunk/ContactPoint.cs | 174 +++ .../src/public/chipmunk/ContactPointSet.cs | 178 +++ .../src/public/chipmunk/DebugColor.cs | 160 +++ .../src/public/chipmunk/DebugDrawColors.cs | 67 + .../src/public/chipmunk/DebugDrawFlags.cs | 60 + .../src/public/chipmunk/HastySpace.cs | 75 + .../src/public/chipmunk/IDebugDraw.cs | 64 + .../src/public/chipmunk/MarchData.cs | 82 ++ .../src/public/chipmunk/PointQueryInfo.cs | 162 +++ .../src/public/chipmunk/SegmentQueryInfo.cs | 178 +++ .../src/public/chipmunk/ShapeFilter.cs | 117 ++ .../src/public/chipmunk/Shapes/Box.cs | 71 + .../src/public/chipmunk/Shapes/Circle.cs | 120 ++ .../src/public/chipmunk/Shapes/Polygon.cs | 194 +++ .../src/public/chipmunk/Shapes/Segment.cs | 115 ++ .../src/public/chipmunk/Shapes/Shape.cs | 327 +++++ .../src/public/chipmunk/Space.cs | 851 ++++++++++++ .../src/public/chipmunk/Transform.cs | 202 +++ .../chipmunk/Unsafe/CircleExtensions.cs | 52 + .../chipmunk/Unsafe/PolygonExtensions.cs | 67 + .../chipmunk/Unsafe/SegmentExtensions.cs | 53 + .../src/public/chipmunk/Vect.cs | 437 ++++++ .../Physics2DSample.cs | 216 +++ .../Tizen.NUI.Physics2D.Sample.csproj | 22 + .../tizen-manifest.xml | 13 + 57 files changed, 9873 insertions(+) create mode 100755 src/Tizen.NUI.Physics2D/Properties/AssemblyInfo.cs create mode 100755 src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj create mode 100755 src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.sln create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/DelegateExtensions.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/Delegates.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeMethods.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/PostStepCallbackInfo.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpCollisionHandler.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPointSet.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPointQueryInfo.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPolyline.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSegmentQueryInfo.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Arbiter.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/AutoGeometry.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/BodyType.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/CollisionHandler.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/Constraint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedRotarySpring.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedSpring.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GearJoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GrooveJoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PinJoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PivotJoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RatchetJoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RotaryLimitJoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SimpleMotor.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SlideJoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawColors.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawFlags.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/HastySpace.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/IDebugDraw.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/MarchData.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/PointQueryInfo.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs create mode 100755 src/Tizen.NUI.Physics2D/src/public/chipmunk/ShapeFilter.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Box.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Circle.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Polygon.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Segment.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Shape.cs create mode 100755 src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/CircleExtensions.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/PolygonExtensions.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/SegmentExtensions.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/Vect.cs create mode 100644 test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs create mode 100644 test/Tizen.NUI.Physics2D.Sample/Tizen.NUI.Physics2D.Sample.csproj create mode 100644 test/Tizen.NUI.Physics2D.Sample/tizen-manifest.xml diff --git a/src/Tizen.NUI.Physics2D/Properties/AssemblyInfo.cs b/src/Tizen.NUI.Physics2D/Properties/AssemblyInfo.cs new file mode 100755 index 00000000000..3110dbc1477 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/Properties/AssemblyInfo.cs @@ -0,0 +1,4 @@ +using Tizen.NUI; + +// Xamarin.Forms.Loader.dll Xamarin.Forms.Xaml.XamlLoader.Load(object, string), kzu@microsoft.com +[assembly: XmlnsDefinition("http://tizen.org/Tizen.NUI/2018/XAML", "Tizen.NUI.Physics2D")] diff --git a/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj new file mode 100755 index 00000000000..ab51d112c1a --- /dev/null +++ b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + $(NoWarn);CS0618;CA1054;CA1056 + + + + + + + + + + + + diff --git a/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.sln b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.sln new file mode 100755 index 00000000000..f72eb282365 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.sln @@ -0,0 +1,79 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31515.178 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.NUI.Physics2D", "Tizen.NUI.Physics2D.csproj", "{F6CEE887-775A-4623-8BF8-DCA18C363D62}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.NUI", "..\Tizen.NUI\Tizen.NUI.csproj", "{F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.Common", "..\Tizen.Applications.Common\Tizen.Applications.Common.csproj", "{CE90CD24-82F7-45A3-96B2-2E3C97D25C30}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.System.SystemSettings", "..\Tizen.System.SystemSettings\Tizen.System.SystemSettings.csproj", "{D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{6D5FFD69-6DCC-4953-85E9-C23AC18B190E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.System.Information", "..\Tizen.System.Information\Tizen.System.Information.csproj", "{A951EAFE-D191-4F45-9AEF-7D97C382A747}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{E1E30AEC-AD46-4E53-B9B1-780A68B59963}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.ComponentBased", "..\Tizen.Applications.ComponentBased\Tizen.Applications.ComponentBased.csproj", "{70341AA2-1324-4215-9DB8-BFB13389D932}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.ThemeManager", "..\Tizen.Applications.ThemeManager\Tizen.Applications.ThemeManager.csproj", "{F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Tracer", "..\Tizen.Tracer\Tizen.Tracer.csproj", "{6DABE78F-1816-4F2E-8966-F909173194C8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6CEE887-775A-4623-8BF8-DCA18C363D62}.Release|Any CPU.Build.0 = Release|Any CPU + {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9DAA9C3-593D-467E-B02C-FFF51F1BC8CD}.Release|Any CPU.Build.0 = Release|Any CPU + {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE90CD24-82F7-45A3-96B2-2E3C97D25C30}.Release|Any CPU.Build.0 = Release|Any CPU + {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D726EEB8-6382-4BA3-BE0C-D9E61B5D8374}.Release|Any CPU.Build.0 = Release|Any CPU + {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D5FFD69-6DCC-4953-85E9-C23AC18B190E}.Release|Any CPU.Build.0 = Release|Any CPU + {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A951EAFE-D191-4F45-9AEF-7D97C382A747}.Release|Any CPU.Build.0 = Release|Any CPU + {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1E30AEC-AD46-4E53-B9B1-780A68B59963}.Release|Any CPU.Build.0 = Release|Any CPU + {70341AA2-1324-4215-9DB8-BFB13389D932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70341AA2-1324-4215-9DB8-BFB13389D932}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70341AA2-1324-4215-9DB8-BFB13389D932}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70341AA2-1324-4215-9DB8-BFB13389D932}.Release|Any CPU.Build.0 = Release|Any CPU + {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6A776BF-6743-4C1D-A8AF-F3E9F8CEFA0A}.Release|Any CPU.Build.0 = Release|Any CPU + {6DABE78F-1816-4F2E-8966-F909173194C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6DABE78F-1816-4F2E-8966-F909173194C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6DABE78F-1816-4F2E-8966-F909173194C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6DABE78F-1816-4F2E-8966-F909173194C8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {83C85CFB-3AB8-403A-9F6D-CC2783C6C559} + EndGlobalSection +EndGlobal diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/DelegateExtensions.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/DelegateExtensions.cs new file mode 100644 index 00000000000..dc2aed0801c --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/DelegateExtensions.cs @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Create a ToFunctionPointer extension method for each delegate type. Unfortunately C# 7.0 + /// can't do something like that (you will need C# 7.3), thus we create one extension method for + /// each delegate public static IntPtr ToFunctionPointer T (this T d) where T : Delegate + /// + static internal class DelegateExtensions + { + public static IntPtr ToFunctionPointer(this BodyArbiterIteratorFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this BodyConstraintIteratorFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this BodyShapeIteratorFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this BodyVelocityFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this BodyPositionFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this CollisionBeginFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this CollisionPreSolveFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this CollisionPostSolveFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this CollisionSeparateFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this PostStepFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this SpaceSegmentQueryFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this SpacePointQueryFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this SpaceBBQueryFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this SpaceObjectIteratorFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this SpaceDebugDrawCircleImpl d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this SpaceDebugDrawSegmentImpl d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this SpaceDebugDrawFatSegmentImpl d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this SpaceDebugDrawPolygonImpl d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this SpaceDebugDrawDotImpl d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this SpaceDebugDrawColorForShapeImpl d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + + public static IntPtr ToFunctionPointer(this ConstraintSolveFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this DampedSpringForceFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this DampedRotarySpringTorqueFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this SpaceShapeQueryFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this MarchSegmentFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + + public static IntPtr ToFunctionPointer(this MarchSampleFunction d) + { + if (d == null) + { + return IntPtr.Zero; + } + + return Marshal.GetFunctionPointerForDelegate(d); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/Delegates.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/Delegates.cs new file mode 100644 index 00000000000..8c2d219040b --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/Delegates.cs @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.Runtime.InteropServices; +using System.Security; +using cpArbiter = System.IntPtr; +using cpBody = System.IntPtr; +using cpBool = System.Byte; +using cpConstraint = System.IntPtr; +using cpContactPointSetPointer = System.IntPtr; +using cpHandle = System.IntPtr; +using cpShape = System.IntPtr; +using cpSpace = System.IntPtr; +using cpVertPointer = System.IntPtr; +using voidptr_t = System.IntPtr; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Delegate method to iterate over arbiters. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void BodyArbiterIteratorFunction(cpBody body, cpArbiter arbiter, voidptr_t data); + + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void BodyVelocityFunction(cpBody body, Vect gravity, double damping, double dt); + + /// + /// Rigid body position update function type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void BodyPositionFunction(cpBody body, double dt); + + /// + /// Delegate method to iterate over constraints. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void BodyConstraintIteratorFunction(cpBody body, cpConstraint constraint, voidptr_t data); + + /// + /// Delegate method to iterate over shapes. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void BodyShapeIteratorFunction(cpBody body, cpShape shape, voidptr_t data); + + /// + /// Collision begin event function callback type. Returning false from a begin callback causes + /// the collision to be ignored until the the separate callback is called when the objects stop + /// colliding. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void CollisionBeginFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData); + + /// + /// Collision pre-solve event function callback type. Returning false from a pre-step callback + /// causes the collision to be ignored until the next step. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate cpBool CollisionPreSolveFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData); + + /// + /// Collision Post-Solve . + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void CollisionPostSolveFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData); + + /// + /// Collision separate event function callback type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void CollisionSeparateFunction(cpArbiter arbiter, cpSpace space, voidptr_t userData); + + /// + /// Post Step callback function type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void PostStepFunction(cpSpace space, voidptr_t key, voidptr_t data); + + /// + /// Nearest point query callback function type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpacePointQueryFunction(cpShape shape, Vect point, double distance, Vect gradient, voidptr_t data); + + /// + /// Segment query callback function type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceSegmentQueryFunction(cpShape shape, Vect point, Vect normal, double alpha, voidptr_t data); + + /// + /// Rectangle Query callback function type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceBBQueryFunction(cpShape shape, voidptr_t data); + + /// + /// Space/object iterator callback function type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceObjectIteratorFunction(cpHandle handle, voidptr_t data); + + /// + /// Callback type for a function that draws a filled, stroked circle. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceDebugDrawCircleImpl(Vect pos, double angle, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data); + + /// + /// Callback type for a function that draws a line segment. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceDebugDrawSegmentImpl(Vect a, Vect b, DebugColor color, voidptr_t data); + + /// + /// Callback type for a function that draws a thick line segment. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceDebugDrawFatSegmentImpl(Vect a, Vect b, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data); + + /// + /// Callback type for a function that draws a convex polygon. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceDebugDrawPolygonImpl(int count, cpVertPointer verts, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data); + + /// + /// Callback type for a function that draws a dot. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceDebugDrawDotImpl(double size, Vect pos, DebugColor color, voidptr_t data); + + /// + /// Callback type for a function that returns a color for a given shape. This gives you an + /// opportunity to color shapes based on how they are used in your engine. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate DebugColor SpaceDebugDrawColorForShapeImpl(cpShape shape, voidptr_t data); + + /// + /// Callback function type that gets called after/before solving a joint. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void ConstraintSolveFunction(cpConstraint constraint, cpSpace space); + + /// + /// Function type used for damped spring force callbacks. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate double DampedSpringForceFunction(cpConstraint spring, double dist); + + /// + /// Function type used for damped rotary spring force callbacks + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate double DampedRotarySpringTorqueFunction(cpConstraint spring, double relativeAngle); + + /// + /// Shape query callback function type. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void SpaceShapeQueryFunction(cpShape shape, cpContactPointSetPointer points, voidptr_t data); + + /// + /// Function type used as a callback from the marching squares algorithm to output a line + /// segment. It passes you the two endpoints and your context pointer. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate void MarchSegmentFunction(Vect v0, Vect v1, voidptr_t data); + + /// + /// Function type used as a callback from the marching squares algorithm to sample an image function. + /// It passes you the point to sample and your context pointer, and you return the density. + /// + [SuppressUnmanagedCodeSecurity] + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ + [MonoNativeFunctionWrapper] +#endif + internal delegate double MarchSampleFunction(Vect point, voidptr_t data); +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs new file mode 100644 index 00000000000..5859c0b618a --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + internal static class NativeInterop + { + public static IntPtr RegisterHandle(object obj) + { + var gcHandle = GCHandle.Alloc(obj); + return GCHandle.ToIntPtr(gcHandle); + } + + public static T FromIntPtr(IntPtr pointer) + { + Debug.Assert(pointer != IntPtr.Zero, "IntPtr parameter should never be Zero"); + + var handle = GCHandle.FromIntPtr(pointer); + + Debug.Assert(handle.IsAllocated, "GCHandle not allocated."); + Debug.Assert(handle.Target is T, "Target is not of type T."); + + return (T)handle.Target; + } + + public static void ReleaseHandle(IntPtr pointer) + { + Debug.Assert(pointer != IntPtr.Zero, "IntPtr parameter should never be Zero"); + + var handle = GCHandle.FromIntPtr(pointer); + + Debug.Assert(handle.IsAllocated, "GCHandle not allocated."); + + handle.Free(); + } + + public static T FromIntPtrAndFree(IntPtr pointer) + { + Debug.Assert(pointer != IntPtr.Zero, "IntPtr parameter should never be Zero"); + + var handle = GCHandle.FromIntPtr(pointer); + + Debug.Assert(handle.IsAllocated, "GCHandle not allocated."); + Debug.Assert(handle.Target is T, "Target is not of type T."); + T obj = (T)handle.Target; + + handle.Free(); + + return obj; + } + + public static int SizeOf() + { + return Marshal.SizeOf(); + } + + public static IntPtr AllocStructure() + { + int size = SizeOf(); + return Marshal.AllocHGlobal(size); + } + + public static void FreeStructure(IntPtr ptr) + { + Marshal.FreeHGlobal(ptr); + } + + public static T PtrToStructure(IntPtr intPtr) + { + return Marshal.PtrToStructure(intPtr); + } + + public static T[] PtrToStructureArray(IntPtr intPtr, int count) + { + var items = new T[count]; + var size = SizeOf(); + + for (var i = 0; i < count; i++) + { + var newPtr = new IntPtr(intPtr.ToInt64() + (i * size)); + items[i] = PtrToStructure(newPtr); + } + + return items; + } + + internal static IntPtr StructureArrayToPtr(IReadOnlyList items) + { + var size = SizeOf(); + var memory = Marshal.AllocHGlobal(size * items.Count); + + for (var i = 0; i < items.Count; i++) + { + var ptr = new IntPtr(memory.ToInt64() + (i * size)); + Marshal.StructureToPtr(items[i], ptr, true); + } + + return memory; + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeMethods.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeMethods.cs new file mode 100644 index 00000000000..305d4039506 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeMethods.cs @@ -0,0 +1,1228 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// ReSharper disable IdentifierTypo +using System; +using System.Runtime.InteropServices; +using System.Security; +using cpArbiter = System.IntPtr; +using cpBitmask = System.UInt32; +using cpBody = System.IntPtr; +using cpBodyArbiterIteratorFunc = System.IntPtr; +using cpBodyConstraintIteratorFunc = System.IntPtr; +using cpBodyPositionFunc = System.IntPtr; +using cpBodyShapeIteratorFunc = System.IntPtr; +using cpBodyType = System.Int32; +using cpBodyVelocityFunc = System.IntPtr; +using cpBool = System.Byte; +using cpCollisionHandlerPointer = System.IntPtr; +using cpCollisionType = System.UIntPtr; +using cpConstraint = System.IntPtr; +using cpConstraintPostSolveFunc = System.IntPtr; +using cpConstraintPreSolveFunc = System.IntPtr; +using cpDampedRotarySpringTorqueFunc = System.IntPtr; +using cpDampedSpringForceFunc = System.IntPtr; +using cpDataPointer = System.IntPtr; +using cpFloat = System.Double; +using cpGroup = System.UIntPtr; +using cpMarchSampleFunc = System.IntPtr; +using cpMarchSegmentFunc = System.IntPtr; +using cpPolyline = System.IntPtr; +using cpPolylineSet = System.IntPtr; +using cpPostStepFunc = System.IntPtr; +using cpShape = System.IntPtr; +using cpSpace = System.IntPtr; +using cpSpaceBBQueryFunc = System.IntPtr; +using cpSpaceBodyIteratorFunc = System.IntPtr; +using cpSpaceConstraintIteratorFunc = System.IntPtr; +using cpSpaceDebugDrawOptionsPointer = System.IntPtr; +using cpSpaceHash = System.IntPtr; +using cpSpacePointQueryFunc = System.IntPtr; +using cpSpaceSegmentQueryFunc = System.IntPtr; +using cpSpaceShapeIteratorFunc = System.IntPtr; +using cpSpaceShapeQueryFunc = System.IntPtr; +using cpSpatialIndex = System.IntPtr; +using cpSpatialIndexBBFunc = System.IntPtr; +using cpSpatialIndexQueryFunc = System.IntPtr; +using cpSweep1D = System.IntPtr; +using cpTimestamp = System.UInt32; +using cpVectPointer = System.IntPtr; +using VoidPointer = System.IntPtr; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + [SuppressUnmanagedCodeSecurity] + internal static class NativeMethods + { + +#pragma warning disable CA1823 // Unused field 'ChipmunkLibraryName' + +#if __MACOS__ + private const string ChipmunkLibraryName = "libchipmunk.dylib"; +#else + private const string ChipmunkLibraryName = "libchipmunk.so"; +#endif + +#pragma warning restore CA1823 // Unused field 'ChipmunkLibraryName' + +#pragma warning disable IDE1006 // Naming Styles + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterCallWildcardBeginA(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterCallWildcardBeginB(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterCallWildcardPostSolveA(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterCallWildcardPostSolveB(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpArbiterCallWildcardPreSolveA(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpArbiterCallWildcardPreSolveB(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterCallWildcardSeparateA(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterCallWildcardSeparateB(cpArbiter arb, cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterGetBodies(cpArbiter arb, out cpBody a, out cpBody b); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpContactPointSet cpArbiterGetContactPointSet(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int cpArbiterGetCount(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpArbiterGetDepth(cpArbiter arb, int i); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpArbiterGetFriction(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpArbiterGetNormal(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpArbiterGetPointA(cpArbiter arb, int i); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpArbiterGetPointB(cpArbiter arb, int i); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpArbiterGetRestitution(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterGetShapes(cpArbiter arb, out cpShape a, out cpShape b); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpArbiterGetSurfaceVelocity(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpDataPointer cpArbiterGetUserData(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpArbiterIgnore(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpArbiterIsFirstContact(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpArbiterIsRemoval(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterSetContactPointSet(cpArbiter arb, ref cpContactPointSet set); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterSetFriction(cpArbiter arb, cpFloat friction); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterSetRestitution(cpArbiter arb, cpFloat restitution); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterSetSurfaceVelocity(cpArbiter arb, Vect vr); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpArbiterSetUserData(cpArbiter arb, cpDataPointer userData); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpArbiterTotalImpulse(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpArbiterTotalKE(cpArbiter arb); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpAreaForPoly(int count, cpVectPointer verts, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpAreaForSegment(Vect a, Vect b, cpFloat radius); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpBBTree cpBBTreeAlloc(); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpatialIndex cpBBTreeInit(cpBBTree tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpatialIndex cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpBBTreeOptimize(cpSpatialIndex index); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpBBTreeSetVelocityFunc(cpSpatialIndex index, cpBBTreeVelocityFunc func); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyActivate(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyActivateStatic(cpBody body, cpShape filter); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpBody cpBodyAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyApplyForceAtLocalPoint(cpBody body, Vect force, Vect point); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyApplyForceAtWorldPoint(cpBody body, Vect force, Vect point); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyApplyTorque(cpBody body, cpFloat torque); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyApplyAngularImpulse(cpBody body, cpFloat impulse); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyApplyImpulseAtLocalPoint(cpBody body, Vect impulse, Vect point); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyApplyImpulseAtWorldPoint(cpBody body, Vect impulse, Vect point); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpBodyDestroy(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpBodyContactWith(cpBody bodyA, cpBody bodyB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyEachArbiter(cpBody body, cpBodyArbiterIteratorFunc func, VoidPointer data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyEachConstraint(cpBody body, cpBodyConstraintIteratorFunc func, VoidPointer data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyEachShape(cpBody body, cpBodyShapeIteratorFunc func, VoidPointer data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyFree(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpBodyGetAngle(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpBodyGetAngularVelocity(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyGetCenterOfGravity(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int cpBodyGetContactedBodiesCount(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyGetUserDataContactedBodies(cpBody body, IntPtr userDataArray); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBodyPositionFunc cpBodyGetDefaultPositionUpdateFunc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBodyVelocityFunc cpBodyGetDefaultVelocityUpdateFunc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyGetForce(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpBodyGetMass(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpBodyGetMoment(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyGetPosition(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyGetRotation(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpSpace cpBodyGetSpace(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyGetTransform(cpBody body, out Vect pos, out cpFloat angle); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpBodyGetTorque(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBodyType cpBodyGetType(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpDataPointer cpBodyGetUserData(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyGetVelocity(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyGetVelocityAtLocalPoint(cpBody body, Vect point); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyGetVelocityAtWorldPoint(cpBody body, Vect point); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpBody cpBodyInit(cpBody body, cpFloat mass, cpFloat moment); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpBodyIsSleeping(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpBodyKineticEnergy(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyLocalToWorld(cpBody body, Vect point); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpBodyNew(cpFloat mass, cpFloat moment); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpBodyNewKinematic(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpBodyNewStatic(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetAngle(cpBody body, cpFloat a); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetAngularVelocity(cpBody body, cpFloat angularVelocity); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetCenterOfGravity(cpBody body, Vect cog); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetForce(cpBody body, Vect force); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetMass(cpBody body, cpFloat m); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetMoment(cpBody body, cpFloat i); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetPosition(cpBody body, Vect pos); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetPositionUpdateFunc(cpBody body, cpBodyPositionFunc positionFunc); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetTransform(cpBody body, Vect pos, cpFloat angle); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetTorque(cpBody body, cpFloat torque); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetType(cpBody body, cpBodyType type); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetUserData(cpBody body, cpDataPointer userData); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetVelocity(cpBody body, Vect velocity); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySetVelocityUpdateFunc(cpBody body, cpBodyVelocityFunc velocityFunc); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySleep(cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodySleepWithGroup(cpBody body, cpBody group); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyUpdatePosition(cpBody body, cpFloat dt); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpBodyUpdateVelocity(cpBody body, Vect gravity, cpFloat damping, cpFloat dt); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpBodyWorldToLocal(cpBody body, Vect point); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPolyShape cpBoxShapeInit(cpPolyShape poly, cpBody body, cpFloat width, cpFloat height, cpFloat radius); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPolyShape cpBoxShapeInit2(cpPolyShape poly, cpBody body, BoundingBox box, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpBoxShapeNew(cpBody body, cpFloat width, cpFloat height, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpBoxShapeNew2(cpBody body, BoundingBox box, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpCentroidForPoly(int count, cpVectPointer verts); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpCircleShape cpCircleShapeAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpCircleShapeGetOffset(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpCircleShapeGetRadius(cpShape shape); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpCircleShape cpCircleShapeInit(cpCircleShape circle, cpBody body, cpFloat radius, Vect offset); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpCircleShapeNew(cpBody body, cpFloat radius, Vect offset); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpCircleShapeSetOffset(cpShape shape, Vect offset); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpCircleShapeSetRadius(cpShape shape, cpFloat radius); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpConstraintDestroy(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintFree(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpConstraintGetBodyA(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpConstraintGetBodyB(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintGetCollideBodies(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpConstraintGetErrorBias(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpConstraintGetImpulse(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpConstraintGetMaxBias(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpConstraintGetMaxForce(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpConstraintPostSolveFunc cpConstraintGetPostSolveFunc(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpConstraintPreSolveFunc cpConstraintGetPreSolveFunc(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpSpace cpConstraintGetSpace(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpDataPointer cpConstraintGetUserData(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsDampedRotarySpring(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsDampedSpring(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsGearJoint(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsGrooveJoint(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsPinJoint(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsPivotJoint(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsRatchetJoint(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsRotaryLimitJoint(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsSimpleMotor(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpConstraintIsSlideJoint(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintSetCollideBodies(cpConstraint constraint, cpBool collideBodies); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintSetErrorBias(cpConstraint constraint, cpFloat errorBias); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintSetMaxBias(cpConstraint constraint, cpFloat maxBias); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintSetMaxForce(cpConstraint constraint, cpFloat maxForce); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintSetPostSolveFunc(cpConstraint constraint, cpConstraintPostSolveFunc postSolveFunc); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintSetPreSolveFunc(cpConstraint constraint, cpConstraintPreSolveFunc preSolveFunc); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpConstraintSetUserData(cpConstraint constraint, cpDataPointer userData); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int cpConvexHull(int count, cpVectPointer verts, cpVectPointer result, IntPtr first, cpFloat tol); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpDampedRotarySpring cpDampedRotarySpringAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpDampedRotarySpringGetDamping(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpDampedRotarySpringGetRestAngle(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpDampedRotarySpringTorqueFunc cpDampedRotarySpringGetSpringTorqueFunc(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpDampedRotarySpringGetStiffness(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpDampedRotarySpring cpDampedRotarySpringInit(cpDampedRotarySpring joint, cpBody a, cpBody b, cpFloat restAngle, cpFloat stiffness, cpFloat damping); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpDampedRotarySpringNew(cpBody a, cpBody b, cpFloat restAngle, cpFloat stiffness, cpFloat damping); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedRotarySpringSetDamping(cpConstraint constraint, cpFloat damping); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedRotarySpringSetRestAngle(cpConstraint constraint, cpFloat restAngle); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedRotarySpringSetSpringTorqueFunc(cpConstraint constraint, cpDampedRotarySpringTorqueFunc springTorqueFunc); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedRotarySpringSetStiffness(cpConstraint constraint, cpFloat stiffness); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpDampedSpring cpDampedSpringAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpDampedSpringGetAnchorA(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpDampedSpringGetAnchorB(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpDampedSpringGetDamping(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpDampedSpringGetRestLength(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpDampedSpringForceFunc cpDampedSpringGetSpringForceFunc(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpDampedSpringGetStiffness(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpDampedSpring cpDampedSpringInit(cpDampedSpring joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat restLength, cpFloat stiffness, cpFloat damping); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpDampedSpringNew(cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat restLength, cpFloat stiffness, cpFloat damping); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedSpringSetAnchorA(cpConstraint constraint, Vect anchorA); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedSpringSetAnchorB(cpConstraint constraint, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedSpringSetDamping(cpConstraint constraint, cpFloat damping); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedSpringSetRestLength(cpConstraint constraint, cpFloat restLength); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedSpringSetSpringForceFunc(cpConstraint constraint, cpDampedSpringForceFunc springForceFunc); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpDampedSpringSetStiffness(cpConstraint constraint, cpFloat stiffness); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpGearJoint cpGearJointAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpGearJointGetPhase(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpGearJointGetRatio(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpGearJoint cpGearJointInit(cpGearJoint joint, cpBody a, cpBody b, cpFloat phase, cpFloat ratio); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpGearJointNew(cpBody a, cpBody b, cpFloat phase, cpFloat ratio); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpGearJointSetPhase(cpConstraint constraint, cpFloat phase); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpGearJointSetRatio(cpConstraint constraint, cpFloat ratio); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpGrooveJoint cpGrooveJointAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpGrooveJointGetAnchorB(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpGrooveJointGetGrooveA(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpGrooveJointGetGrooveB(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpGrooveJoint cpGrooveJointInit(cpGrooveJoint joint, cpBody a, cpBody b, Vect groove_a, Vect groove_b, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpGrooveJointNew(cpBody a, cpBody b, Vect groove_a, Vect groove_b, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpGrooveJointSetAnchorB(cpConstraint constraint, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpGrooveJointSetGrooveA(cpConstraint constraint, Vect grooveA); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpGrooveJointSetGrooveB(cpConstraint constraint, Vect grooveB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpHastySpaceFree(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint cpHastySpaceGetThreads(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpSpace cpHastySpaceNew(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpHastySpaceSetThreads(cpSpace space, uint threads); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpHastySpaceStep(cpSpace space, cpFloat dt); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpMarchHard( + BoundingBox bb, uint x_samples, uint y_samples, cpFloat threshold, + cpMarchSegmentFunc segment, IntPtr segment_data, + cpMarchSampleFunc sample, IntPtr sample_data + ); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpMarchSoft( + BoundingBox bb, uint x_samples, uint y_samples, cpFloat threshold, + cpMarchSegmentFunc segment, IntPtr segment_data, + cpMarchSampleFunc sample, IntPtr sample_data + ); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpMomentForBox2(cpFloat m, BoundingBox box); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, Vect offset); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpMomentForPoly(cpFloat m, int count, cpVectPointer verts, Vect offset, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpMomentForSegment(cpFloat m, Vect a, Vect b, cpFloat radius); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPinJoint cpPinJointAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpPinJointGetAnchorA(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpPinJointGetAnchorB(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpPinJointGetDist(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPinJoint cpPinJointInit(cpPinJoint joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpPinJointNew(cpBody a, cpBody b, Vect anchorA, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPinJointSetAnchorA(cpConstraint constraint, Vect anchorA); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPinJointSetAnchorB(cpConstraint constraint, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPinJointSetDist(cpConstraint constraint, cpFloat dist); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPivotJoint cpPivotJointAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpPivotJointGetAnchorA(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpPivotJointGetAnchorB(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPivotJoint cpPivotJointInit(cpPivotJoint joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpPivotJointNew(cpBody a, cpBody b, Vect pivot); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpPivotJointNew2(cpBody a, cpBody b, Vect anchorA, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPivotJointSetAnchorA(cpConstraint constraint, Vect anchorA); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPivotJointSetAnchorB(cpConstraint constraint, Vect anchorB); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPolyShape cpPolyShapeAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int cpPolyShapeGetCount(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpPolyShapeGetRadius(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpPolyShapeGetVert(cpShape shape, int index); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPolyShape cpPolyShapeInit(cpPolyShape poly, cpBody body, int count, cpVectPointer verts, Transform transform, cpFloat radius); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPolyShape cpPolyShapeInitRaw(cpPolyShape poly, cpBody body, int count, cpVectPointer verts, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpPolyShapeNew(cpBody body, int count, cpVectPointer verts, Transform transform, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpPolyShapeNewRaw(cpBody body, int count, cpVectPointer verts, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPolyShapeSetRadius(cpShape shape, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPolyShapeSetVerts(cpShape shape, int count, cpVectPointer verts, Transform transform); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPolyShapeSetVertsRaw(cpShape shape, int count, cpVectPointer verts); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpPolylineSet cpPolylineConvexDecomposition(cpPolyline line, cpFloat tol); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPolylineFree(cpPolyline line); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpPolyline cpPolylineSimplifyCurves(cpPolyline line, cpFloat tol); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpPolylineSet cpPolylineSetAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPolylineSetCollectSegment(Vect v0, Vect v1, cpPolylineSet lines); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpPolylineSetDestroy(cpPolylineSet set, cpBool freePolylines); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpPolylineSetFree(cpPolylineSet set, cpBool freePolylines); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpPolylineSet cpPolylineSetInit(cpPolylineSet set); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpPolylineSet cpPolylineSetNew(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpPolyline cpPolylineSimplifyVertexes(cpPolyline line, cpFloat tol); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpPolyline cpPolylineToConvexHull(cpPolyline line, cpFloat tol); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpRatchetJoint cpRatchetJointAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpRatchetJointGetAngle(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpRatchetJointGetPhase(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpRatchetJointGetRatchet(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpRatchetJoint cpRatchetJointInit(cpRatchetJoint joint, cpBody a, cpBody b, cpFloat phase, cpFloat ratchet); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpRatchetJointNew(cpBody a, cpBody b, cpFloat phase, cpFloat ratchet); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpRatchetJointSetAngle(cpConstraint constraint, cpFloat angle); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpRatchetJointSetPhase(cpConstraint constraint, cpFloat phase); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpRatchetJointSetRatchet(cpConstraint constraint, cpFloat ratchet); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpRotaryLimitJoint cpRotaryLimitJointAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpRotaryLimitJointGetMax(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpRotaryLimitJointGetMin(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpRotaryLimitJoint cpRotaryLimitJointInit(cpRotaryLimitJoint joint, cpBody a, cpBody b, cpFloat min, cpFloat max); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpRotaryLimitJointNew(cpBody a, cpBody b, cpFloat min, cpFloat max); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpRotaryLimitJointSetMax(cpConstraint constraint, cpFloat max); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpRotaryLimitJointSetMin(cpConstraint constraint, cpFloat min); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSegmentShape cpSegmentShapeAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpSegmentShapeGetA(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpSegmentShapeGetB(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpSegmentShapeGetNormal(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSegmentShapeGetRadius(cpShape shape); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSegmentShape cpSegmentShapeInit(cpSegmentShape seg, cpBody body, Vect a, Vect b, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpSegmentShapeNew(cpBody body, Vect a, Vect b, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSegmentShapeSetEndpoints(cpShape shape, Vect a, Vect b); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSegmentShapeSetNeighbors(cpShape shape, Vect prev, Vect next); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSegmentShapeSetRadius(cpShape shape, cpFloat radius); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern BoundingBox cpShapeCacheBB(cpShape shape); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpShapeDestroy(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeFree(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpShapeGetArea(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern BoundingBox cpShapeGetBB(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpShapeGetBody(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpShapeGetCenterOfGravity(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpCollisionType cpShapeGetCollisionType(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpShapeGetDensity(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpShapeGetElasticity(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpShapeGetFriction(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpShapeGetMass(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpShapeGetMoment(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpShapeGetSensor(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpSpace cpShapeGetSpace(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpShapeGetSurfaceVelocity(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpDataPointer cpShapeGetUserData(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern ShapeFilter cpShapeGetFilter(cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpShapePointQuery(cpShape shape, Vect p, ref cpPointQueryInfo output); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpShapeSegmentQuery(cpShape shape, Vect a, Vect b, cpFloat radius, ref cpSegmentQueryInfo info); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetBody(cpShape shape, cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetCollisionType(cpShape shape, cpCollisionType collisionType); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetDensity(cpShape shape, cpFloat density); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetElasticity(cpShape shape, cpFloat elasticity); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetFriction(cpShape shape, cpFloat friction); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetMass(cpShape shape, cpFloat mass); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetSensor(cpShape shape, cpBool sensor); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetSurfaceVelocity(cpShape shape, Vect surfaceVelocity); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpShapeSetUserData(cpShape shape, cpDataPointer userData); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpShapeSetFilter(cpShape shape, ShapeFilter filter); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern BoundingBox cpShapeUpdate(cpShape shape, Transform transform); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpContactPointSet cpShapesCollide(cpShape a, cpShape b); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSimpleMotor cpSimpleMotorAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSimpleMotorGetRate(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSimpleMotor cpSimpleMotorInit(cpSimpleMotor joint, cpBody a, cpBody b, cpFloat rate); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpSimpleMotorNew(cpBody a, cpBody b, cpFloat rate); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSimpleMotorSetRate(cpConstraint constraint, cpFloat rate); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSlideJoint cpSlideJointAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpSlideJointGetAnchorA(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpSlideJointGetAnchorB(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSlideJointGetMax(cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSlideJointGetMin(cpConstraint constraint); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSlideJoint cpSlideJointInit(cpSlideJoint joint, cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat min, cpFloat max); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpSlideJointNew(cpBody a, cpBody b, Vect anchorA, Vect anchorB, cpFloat min, cpFloat max); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSlideJointSetAnchorA(cpConstraint constraint, Vect anchorA); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSlideJointSetAnchorB(cpConstraint constraint, Vect anchorB); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSlideJointSetMax(cpConstraint constraint, cpFloat max); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSlideJointSetMin(cpConstraint constraint, cpFloat min); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpSpaceAddBody(cpSpace space, cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpCollisionHandlerPointer cpSpaceAddCollisionHandler(cpSpace space, cpCollisionType a, cpCollisionType b); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpConstraint cpSpaceAddConstraint(cpSpace space, cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpCollisionHandlerPointer cpSpaceAddDefaultCollisionHandler(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpSpaceAddPostStepCallback(cpSpace space, cpPostStepFunc func, IntPtr key, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpSpaceAddShape(cpSpace space, cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpCollisionHandlerPointer cpSpaceAddWildcardHandler(cpSpace space, cpCollisionType type); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpace cpSpaceAlloc(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceBBQuery(cpSpace space, BoundingBox bb, ShapeFilter filter, cpSpaceBBQueryFunc func, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpSpaceContainsShape(cpSpace space, cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpSpaceContainsBody(cpSpace space, cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpSpaceContainsConstraint(cpSpace space, cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceDebugDraw(cpSpace space, cpSpaceDebugDrawOptionsPointer options); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpSpaceDestroy(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceEachBody(cpSpace space, cpSpaceBodyIteratorFunc func, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceEachConstraint(cpSpace space, cpSpaceConstraintIteratorFunc func, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int cpSpaceGetBodyCount(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceGetBodiesUserDataArray(cpSpace space, IntPtr userDataArray); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int cpSpaceGetDynamicBodyCount(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceGetDynamicBodiesUserDataArray(cpSpace space, IntPtr userDataArray); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceEachShape(cpSpace space, cpSpaceShapeIteratorFunc func, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceFree(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSpaceGetCollisionBias(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpTimestamp cpSpaceGetCollisionPersistence(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSpaceGetCollisionSlop(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSpaceGetCurrentTimeStep(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSpaceGetDamping(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern Vect cpSpaceGetGravity(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSpaceGetIdleSpeedThreshold(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int cpSpaceGetIterations(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpFloat cpSpaceGetSleepTimeThreshold(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBody cpSpaceGetStaticBody(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpDataPointer cpSpaceGetUserData(cpSpace space); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpaceHash cpSpaceHashAlloc(); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpatialIndex cpSpaceHashInit(cpSpaceHash hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpatialIndex cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpSpaceHashResize(cpSpaceHash hash, cpFloat celldim, int numcells); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpace cpSpaceInit(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpSpaceIsLocked(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpSpace cpSpaceNew(); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpacePointQuery(cpSpace space, Vect point, cpFloat maxDistance, ShapeFilter filter, cpSpacePointQueryFunc func, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpSpacePointQueryNearest(cpSpace space, Vect point, cpFloat maxDistance, ShapeFilter filter, ref cpPointQueryInfo output); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceReindexShape(cpSpace space, cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceReindexShapesForBody(cpSpace space, cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceReindexStatic(cpSpace space); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceRemoveBody(cpSpace space, cpBody body); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceRemoveConstraint(cpSpace space, cpConstraint constraint); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceRemoveShape(cpSpace space, cpShape shape); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSegmentQuery(cpSpace space, Vect start, Vect end, cpFloat radius, ShapeFilter filter, cpSpaceSegmentQueryFunc func, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpShape cpSpaceSegmentQueryFirst(cpSpace space, Vect start, Vect end, cpFloat radius, ShapeFilter filter, ref cpSegmentQueryInfo output); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetCollisionBias(cpSpace space, cpFloat collisionBias); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetCollisionPersistence(cpSpace space, cpTimestamp collisionPersistence); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetCollisionSlop(cpSpace space, cpFloat collisionSlop); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetDamping(cpSpace space, cpFloat damping); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetGravity(cpSpace space, Vect gravity); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetIdleSpeedThreshold(cpSpace space, cpFloat idleSpeedThreshold); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetIterations(cpSpace space, int iterations); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetSleepTimeThreshold(cpSpace space, cpFloat sleepTimeThreshold); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceSetUserData(cpSpace space, cpDataPointer userData); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern cpBool cpSpaceShapeQuery(cpSpace space, cpShape shape, cpSpaceShapeQueryFunc func, IntPtr data); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceStep(cpSpace space, cpFloat dt); + + [DllImport(ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void cpSpaceUseSpatialHash(cpSpace space, cpFloat dim, int count); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpSpatialIndexCollideStatic(cpSpatialIndex dynamicIndex, cpSpatialIndex staticIndex, cpSpatialIndexQueryFunc func, IntPtr data); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern void cpSpatialIndexFree(cpSpatialIndex index); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSweep1D cpSweep1DAlloc(); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpatialIndex cpSweep1DInit(cpSweep1D sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex); + + //[DllImport (ChipmunkLibraryName, CallingConvention = CallingConvention.Cdecl)] + //internal static extern cpSpatialIndex cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex staticIndex); + +#pragma warning restore IDE1006 // Naming Styles + + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/PostStepCallbackInfo.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/PostStepCallbackInfo.cs new file mode 100644 index 00000000000..05cbdc1eb3c --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/PostStepCallbackInfo.cs @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// This class stores the data for the post-step callback. + /// + internal class PostStepCallbackInfo + { + Action callback; + object data; + + /// + /// Creates an instance of the PostStepCallbackInfo class. + /// + /// The post-step callback. + /// The data for the callback. + public PostStepCallbackInfo(Action c, object d) + { + callback = c; + data = d; + } + + /// + /// The post-step callback. + /// + public Action Callback => callback; + + /// + /// The data for the callback. + /// + public object Data => data; + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpCollisionHandler.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpCollisionHandler.cs new file mode 100644 index 00000000000..22a266e6d8d --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpCollisionHandler.cs @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.Runtime.InteropServices; +using cpCollisionFunction = System.IntPtr; +using cpCollisionHandlerPointer = System.IntPtr; +using cpCollisionType = System.UIntPtr; +using cpDataPointer = System.IntPtr; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Struct that holds function callback pointers to configure custom collision handling. + /// Collision handlers have a pair of types; + /// when a collision occurs between two shapes that have these types, the collision handler functions are triggered. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct cpCollisionHandler + { + /// + /// Collision type identifier of the first shape that this handler recognizes. + /// In the collision handler callback, the shape with this type will be the first argument. Read only. + /// + public cpCollisionType typeA; + + /// + /// Collision type identifier of the second shape that this handler recognizes. + /// In the collision handler callback, the shape with this type will be the second argument. Read only. + /// + public cpCollisionType typeB; + + /// + /// This function is called when two shapes with types that match this collision handler begin colliding. + /// + public cpCollisionFunction beginFunction; + + /// + /// This function is called each step when two shapes with types that match this collision handler are colliding. + /// It's called before the collision solver runs so that you can affect a collision's outcome. + /// + public cpCollisionFunction preSolveFunction; + + /// + /// This function is called each step when two shapes with types that match this collision handler are colliding. + /// It's called after the collision solver runs so that you can read back information about the collision to trigger events in your game. + /// + public cpCollisionFunction postSolveFunction; + + /// + /// This function is called when two shapes with types that match this collision handler stop colliding. + /// + public cpCollisionFunction separateFunction; + + /// + /// This is a user definable context pointer that is passed to all of the collision handler functions. + /// + public cpDataPointer userData; + + public static cpCollisionHandler FromHandle(cpCollisionHandlerPointer handle) + { + return Marshal.PtrToStructure(handle); + } + + internal static void ToPointer(cpCollisionHandler handler, cpCollisionFunction handle) + { + Marshal.StructureToPtr(handler, handle, false); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPoint.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPoint.cs new file mode 100644 index 00000000000..ed3f8ef9a81 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPoint.cs @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// The array of contact points. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct cpContactPoint + { + /// + /// The position of the contact on the surface of the first shape. + /// + public Vect pointA; + + /// + /// The position of the contact on the surface of the second shape. + /// + public Vect pointB; + + /// + /// Penetration distance of the two shapes. Overlapping means it will be negative. + /// + public double distance; + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPointSet.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPointSet.cs new file mode 100644 index 00000000000..82c0d8f81cb --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpContactPointSet.cs @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// A struct that wraps up the important collision data for an arbiter. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct cpContactPointSet + { + /// + /// The number of contact points in the set. + /// + public int count; + + /// + /// The normal of the collision. + /// + public Vect normal; + + /// + /// The first contact point. + /// + public cpContactPoint points0; + + /// + /// The second contact point. + /// + public cpContactPoint points1; + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPointQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPointQueryInfo.cs new file mode 100644 index 00000000000..fc9bfb5ed41 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPointQueryInfo.cs @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Point query info. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct cpPointQueryInfo + { + /// + /// The nearest shape, null if no shape was within range. + /// + public IntPtr shape; + + /// + /// The closest point on the shape's surface. (in world space coordinates) + /// + public Vect point; + + /// + /// The distance to the point. The distance is negative if the point is inside the shape. + /// + public double distance; + + /// + /// The gradient of the signed distance function. + /// + public Vect gradient; + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPolyline.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPolyline.cs new file mode 100644 index 00000000000..0278215e8ff --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpPolyline.cs @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Polylines are just arrays of vertices. + /// They are looped if the first vertex is equal to the last. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct cpPolyline + { + /// + /// The number of vertices. + /// + public int count; + + /// + /// The capacity of the vertex array. + /// + public int capacity; + + /// + /// The vertex array that stores the vertices. + /// + public IntPtr verts; + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSegmentQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSegmentQueryInfo.cs new file mode 100644 index 00000000000..2804746c085 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSegmentQueryInfo.cs @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Segment query info + /// + [StructLayout(LayoutKind.Sequential)] + internal struct cpSegmentQueryInfo + { + /// + /// The shape that was hit, or null if no collision occured. + /// + public IntPtr shape; + + /// + /// The point of impact. + /// + public Vect point; + + /// + /// The normal of the surface hit. + /// + public Vect normal; + + /// + /// The normalized distance along the query segment in the range [0, 1]. + /// + public double alpha; + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs new file mode 100644 index 00000000000..18e7fd70990 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Runtime.InteropServices; +using cpDataPointer = System.IntPtr; +using cpShape = System.IntPtr; +using cpSpaceDebugDrawCircleImpl = System.IntPtr; +using cpSpaceDebugDrawColorForShapeImpl = System.IntPtr; +using cpSpaceDebugDrawDotImpl = System.IntPtr; +using cpSpaceDebugDrawFatSegmentImpl = System.IntPtr; +using cpSpaceDebugDrawFlags = System.Int32; +using cpSpaceDebugDrawPolygonImpl = System.IntPtr; +using cpSpaceDebugDrawSegmentImpl = System.IntPtr; +using cpVertPointer = System.IntPtr; +using voidptr_t = System.IntPtr; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Struct used with Space.DebugDraw() containing drawing callbacks and other drawing settings. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct cpSpaceDebugDrawOptions + { + /// + /// Function that will be invoked to draw circles. + /// + cpSpaceDebugDrawCircleImpl drawCircle; + + /// + /// Function that will be invoked to draw line segments. + /// + cpSpaceDebugDrawSegmentImpl drawSegment; + + /// + /// Function that will be invoked to draw thick line segments. + /// + cpSpaceDebugDrawFatSegmentImpl drawFatSegment; + + /// + /// Function that will be invoked to draw convex polygons. + /// + cpSpaceDebugDrawPolygonImpl drawPolygon; + + /// + /// Function that will be invoked to draw dots. + /// + cpSpaceDebugDrawDotImpl drawDot; + + /// + /// Flags that request which things to draw (collision shapes, constraints, contact points). + /// + cpSpaceDebugDrawFlags flags; + + /// + /// Outline color passed to the drawing function. + /// + DebugColor shapeOutlineColor; + + /// + /// Function that decides what fill color to draw shapes using. + /// + cpSpaceDebugDrawColorForShapeImpl colorForShape; + + /// + /// Color passed to drawing functions for constraints. + /// + DebugColor constraintColor; + + /// + /// Color passed to drawing functions for collision points. + /// + DebugColor collisionPointColor; + + /// + /// User defined context pointer passed to all of the callback functions as the 'data' argument. + /// + cpDataPointer data; + + private IntPtr ToPointer() + { + IntPtr drawOptionsPtr = NativeInterop.AllocStructure(); + + Marshal.StructureToPtr(this, drawOptionsPtr, false); + return drawOptionsPtr; + } + + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceDebugDrawCircleImpl))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void SpaceDebugDrawCircleCallback(Vect pos, double angle, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data) + { + IDebugDraw debugDraw = NativeInterop.FromIntPtr(data); + + debugDraw.DrawCircle(pos, angle, radius, outlineColor, fillColor); + } + + private static SpaceDebugDrawCircleImpl spaceDebugDrawCircleCallback = SpaceDebugDrawCircleCallback; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceDebugDrawSegmentImpl))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void SpaceDebugDrawSegmentCallback(Vect a, Vect b, DebugColor color, voidptr_t data) + { + IDebugDraw debugDraw = NativeInterop.FromIntPtr(data); + + debugDraw.DrawSegment(a, b, color); + } + + private static SpaceDebugDrawSegmentImpl spaceDebugDrawSegmentCallback = SpaceDebugDrawSegmentCallback; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceDebugDrawFatSegmentImpl))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void SpaceDebugDrawFatSegmentCallback(Vect a, Vect b, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data) + { + IDebugDraw debugDraw = NativeInterop.FromIntPtr(data); + + debugDraw.DrawFatSegment(a, b, radius, outlineColor, fillColor); + } + + private static SpaceDebugDrawFatSegmentImpl spaceDebugDrawFatSegmentCallback = SpaceDebugDrawFatSegmentCallback; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceDebugDrawPolygonImpl))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void SpaceDebugDrawPolygonCallback(int count, cpVertPointer verts, double radius, DebugColor outlineColor, DebugColor fillColor, voidptr_t data) + { + IDebugDraw debugDraw = NativeInterop.FromIntPtr(data); + + Vect[] vectors = NativeInterop.PtrToStructureArray(verts, count); + + debugDraw.DrawPolygon(vectors, radius, outlineColor, fillColor); + } + + private static SpaceDebugDrawPolygonImpl spaceDebugDrawPolygonCallback = SpaceDebugDrawPolygonCallback; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceDebugDrawDotImpl))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void SpaceDebugDrawDotCallback(double size, Vect pos, DebugColor color, voidptr_t data) + { + IDebugDraw debugDraw = NativeInterop.FromIntPtr(data); + + debugDraw.DrawDot(size, pos, color); + } + + private static SpaceDebugDrawDotImpl spaceDebugDrawDotCallback = SpaceDebugDrawDotCallback; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceDebugDrawColorForShapeImpl))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static DebugColor SpaceDebugDrawColorForShapeCallback(cpShape handleShape, voidptr_t data) + { + IDebugDraw debugDraw = NativeInterop.FromIntPtr(data); + var shape = Shape.FromHandle(handleShape); + + return debugDraw.ColorForShape(shape); + } + + private static SpaceDebugDrawColorForShapeImpl spaceDebugDrawColorForShapeCallback = SpaceDebugDrawColorForShapeCallback; + + + public IntPtr AcquireDebugDrawOptions(IDebugDraw debugDraw, DebugDrawFlags flags, DebugDrawColors colors) + { + this.flags = (int)flags; + collisionPointColor = colors.CollisionPoint; + constraintColor = colors.Constraint; + shapeOutlineColor = colors.ShapeOutline; + + drawCircle = spaceDebugDrawCircleCallback.ToFunctionPointer(); + drawSegment = spaceDebugDrawSegmentCallback.ToFunctionPointer(); + drawFatSegment = spaceDebugDrawFatSegmentCallback.ToFunctionPointer(); + drawPolygon = spaceDebugDrawPolygonCallback.ToFunctionPointer(); + drawDot = spaceDebugDrawDotCallback.ToFunctionPointer(); + colorForShape = spaceDebugDrawColorForShapeCallback.ToFunctionPointer(); + + data = NativeInterop.RegisterHandle(debugDraw); + + return ToPointer(); + } + + public void ReleaseDebugDrawOptions(IntPtr debugDrawOptionsPointer) + { + NativeInterop.ReleaseHandle(data); + NativeInterop.FreeStructure(debugDrawOptionsPointer); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Arbiter.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Arbiter.cs new file mode 100644 index 00000000000..0a7a05a2f1f --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Arbiter.cs @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using cpArbiter = System.IntPtr; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// The object encapsulates a pair of colliding shapes and all of the data + /// about their collision. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public struct Arbiter : IEquatable + { +#pragma warning disable IDE0032 + readonly cpArbiter arbiter; +#pragma warning restore IDE0032 + + /// + /// Native handle of . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public cpArbiter Handle => arbiter; + + internal Arbiter(cpArbiter handle) + { + arbiter = handle; + } + + /// + /// The restitution (elasticity) that will be applied to the pair of colliding objects. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Restitution + { + get => NativeMethods.cpArbiterGetRestitution(arbiter); + set => NativeMethods.cpArbiterSetRestitution(arbiter, value); + } + + /// + /// Friction coefficient that will be applied to the pair of colliding objects. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Friction + { + get => NativeMethods.cpArbiterGetFriction(arbiter); + set => NativeMethods.cpArbiterSetFriction(arbiter, value); + } + + /// + /// The relative surface velocity of the two shapes in contact. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect SurfaceVelocity + { + get => NativeMethods.cpArbiterGetSurfaceVelocity(arbiter); + set => NativeMethods.cpArbiterSetSurfaceVelocity(arbiter, value); + } + + /// + /// Calculate the total impulse including the friction that was applied by this arbiter. + /// This function should only be called from a post-solve, post-step or cpBodyEachArbiter + /// callback. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect TotalImpulse => NativeMethods.cpArbiterTotalImpulse(arbiter); + + /// + /// Calculate the amount of energy lost in a collision including static, but not dynamic friction. + /// This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double TotalKE => NativeMethods.cpArbiterTotalKE(arbiter); + + /// + /// Mark a collision pair to be ignored until the two objects separate. Pre-solve and + /// post-solve callbacks will not be called, but the separate callback will be called. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Ignore() => NativeMethods.cpArbiterIgnore(arbiter) != 0; + + /// + /// Return the colliding shapes involved for this arbiter. The order of their + /// values will match the order set when the collision + /// handler was registered. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void GetShapes(out Shape a, out Shape b) + { + IntPtr ptrA; + IntPtr ptrB; + + NativeMethods.cpArbiterGetShapes(arbiter, out ptrA, out ptrB); + + a = Shape.FromHandle(ptrA); + b = Shape.FromHandle(ptrB); + } + + /// + /// Return the colliding bodies involved for this arbiter. The order of the + /// values the bodies are associated with will match the + /// order set when the collision handler was registered. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void GetBodies(out Body a, out Body b) + { + IntPtr ptrA; + IntPtr ptrB; + + NativeMethods.cpArbiterGetBodies(arbiter, out ptrA, out ptrB); + + a = Body.FromHandle(ptrA); + b = Body.FromHandle(ptrB); + } + + /// + /// The contact point set for an arbiter. This can be a very powerful feature, but use it + /// with caution! + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ContactPointSet ContactPointSet + { + get + { + cpContactPointSet pointSet = NativeMethods.cpArbiterGetContactPointSet(arbiter); + return ContactPointSet.FromContactPointSet(pointSet); + } + set + { + cpContactPointSet pointSet = value.ToContactPointSet(); + NativeMethods.cpArbiterSetContactPointSet(arbiter, ref pointSet); + } + } + + /// + /// Arbitrary user data. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object Data + { + get + { + IntPtr handle = NativeMethods.cpArbiterGetUserData(arbiter); + + if (handle == IntPtr.Zero) + { + return null; + } + + return NativeInterop.FromIntPtrAndFree(handle); + } + set + { + var gcHandle = IntPtr.Zero; + + if (value != null) + { + gcHandle = NativeInterop.RegisterHandle(value); + } + + NativeMethods.cpArbiterSetUserData(arbiter, gcHandle); + } + } + + /// + /// Returns true if this is the first step a pair of objects started colliding. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsFirstContact => NativeMethods.cpArbiterIsFirstContact(arbiter) != 0; + + /// + /// Returns true if the separate callback is due to a shape being removed from the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsRemoval => NativeMethods.cpArbiterIsRemoval(arbiter) != 0; + + /// + /// Get the number of contact points for this arbiter. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int Count => NativeMethods.cpArbiterGetCount(arbiter); + + /// + /// Get the normal of the collision. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Normal => NativeMethods.cpArbiterGetNormal(arbiter); + + /// + /// Get the position of the th contact point on the surface of the first + /// shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect GetPointA(int i) + { + return NativeMethods.cpArbiterGetPointA(arbiter, i); + } + + /// + /// Get the position of the th contact point on the surface of the + /// second shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect GetPointB(int i) + { + return NativeMethods.cpArbiterGetPointB(arbiter, i); + } + + /// + /// Get the depth (amount of overlap) of the th contact point. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double GetDepth(int i) + { + return NativeMethods.cpArbiterGetDepth(arbiter, i); + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the first collision + /// type, you must call this function explicitly. You must decide how to handle the + /// wildcard's return value since it may disagree with the other wildcard handler's return + /// value or your own. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void CallWildcardBeginA(Space space) + { + NativeMethods.cpArbiterCallWildcardBeginA(arbiter, space.Handle); + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the second collision + /// type, you must call this function explicitly. You must decide how to handle the + /// wildcard's return value since it may disagree with the other wildcard handler's return + /// value or your own. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void CallWildcardBeginB(Space space) + { + NativeMethods.cpArbiterCallWildcardBeginB(arbiter, space.Handle); + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the first collision + /// type, you must call this function explicitly. You must decide how to handle the + /// wildcard's return value since it may disagree with the other wildcard handler's return + /// value or your own. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool CallWildcardPreSolveA(Space space) + { + return NativeMethods.cpArbiterCallWildcardPreSolveA(arbiter, space.Handle) != 0; + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the second collision + /// type, you must call this function explicitly. You must decide how to handle the + /// wildcard's return value since it may disagree with the other wildcard handler's return + /// value or your own. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool CallWildcardPreSolveB(Space space) + { + return NativeMethods.cpArbiterCallWildcardPreSolveB(arbiter, space.Handle) != 0; + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the first collision + /// type, you must call this function explicitly. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void CallWildcardPostSolveA(Space space) + { + NativeMethods.cpArbiterCallWildcardPostSolveA(arbiter, space.Handle); + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the second collision + /// type, you must call this function explicitly. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void CallWildcardPostSolveB(Space space) + { + NativeMethods.cpArbiterCallWildcardPostSolveB(arbiter, space.Handle); + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the first collision + /// type, you must call this function explicitly. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void CallWildcardSeparateA(Space space) + { + NativeMethods.cpArbiterCallWildcardSeparateA(arbiter, space.Handle); + } + + /// + /// If you want a custom callback to invoke the wildcard callback for the second collision + /// type, you must call this function explicitly. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void CallWildcardSeparateB(Space space) + { + NativeMethods.cpArbiterCallWildcardSeparateB(arbiter, space.Handle); + } + + /// + /// Return true if an arbiter is equal to another. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(Arbiter other) + { + return arbiter == other.arbiter; + } + + /// + /// Check if an arbiter is equal to the given object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + var other = obj as Arbiter?; + + if (other == null) + return false; + + return Equals(other.Value); + } + + /// + /// Return the arbiter's handle prefixed by 'Handle: '. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() + { + return $"Handle: {arbiter}"; + } + + /// + /// Get the hash code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + return 932982278 + EqualityComparer.Default.GetHashCode(arbiter); + } + + /// + /// Check if one arbiter is equal to another. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(Arbiter left, Arbiter right) + { + return left.Equals(right); + } + + /// + /// Check if one arbiter is inequal to another. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(Arbiter left, Arbiter right) + { + return !(left == right); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/AutoGeometry.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/AutoGeometry.cs new file mode 100644 index 00000000000..2a8ba0b31c5 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/AutoGeometry.cs @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.InteropServices; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// This class contains functions for automatic generation of geometry. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class AutoGeometry + { +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(MarchSegmentFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void MarchSegmentFunctionCallback(Vect v0, Vect v1, IntPtr data) + { + var marchData = (MarchData)GCHandle.FromIntPtr(data).Target; + marchData.SegmentFunction(v0, v1, marchData.SegmentData); + } + + private static MarchSegmentFunction segmentFunctionCallback = MarchSegmentFunctionCallback; + +#if (__IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__) +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(MarchSampleFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static double MarchSampleFunctionCallBack(Vect point, IntPtr data) + { + var marchData = (MarchData)GCHandle.FromIntPtr(data).Target; + return marchData.SampleFunction(point, marchData.SampleData); + } + + private static MarchSampleFunction sampleFunctionCallBack = MarchSampleFunctionCallBack; + + /// + /// Trace an aliased curve of an image along a particular threshold. The given number of + /// samples will be taken and spread across the bounding box area using the sampling + /// function and context. The segment function will be called for each segment detected that + /// lies along the density contour for the threshold. Only the SegmentData and SampleData are + /// optional. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void MarchHard(MarchData data) + { + var gcHandle = GCHandle.Alloc(data); + IntPtr handlePtr = GCHandle.ToIntPtr(gcHandle); + + NativeMethods.cpMarchHard( + data.BoundingBox, + (uint)data.XSamples, + (uint)data.YSamples, + data.Threshold, + segmentFunctionCallback.ToFunctionPointer(), + handlePtr, + sampleFunctionCallBack.ToFunctionPointer(), + handlePtr); + + gcHandle.Free(); + } + + /// + /// Trace an anti-aliased contour of an image along a particular threshold. The given number + /// of samples will be taken and spread across the bounding box area using the sampling + /// function and context. The segment function will be called for each segment detected that + /// lies along the density contour for the threshold. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void MarchSoft(MarchData data) + { + var gcHandle = GCHandle.Alloc(data); + IntPtr handlePtr = GCHandle.ToIntPtr(gcHandle); + + NativeMethods.cpMarchSoft( + data.BoundingBox, + (uint)data.XSamples, + (uint)data.YSamples, + data.Threshold, + segmentFunctionCallback.ToFunctionPointer(), + handlePtr, + sampleFunctionCallBack.ToFunctionPointer(), + handlePtr); + + gcHandle.Free(); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs new file mode 100644 index 00000000000..850b2087d7f --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs @@ -0,0 +1,767 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +using cpBody = System.IntPtr; +using cpArbiter = System.IntPtr; +using cpConstraint = System.IntPtr; +using cpShape = System.IntPtr; +using cpSpace = System.IntPtr; +using cpDataPointer = System.IntPtr; +using System.Diagnostics; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Mass and moment are ignored when is + /// or . Guessing the mass for a body is usually fine, but guessing + /// a moment of inertia can lead to a very poor simulation. It’s recommended to use Chipmunk’s + /// moment-calculating functions to estimate the moment for you. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class Body : IDisposable + { +#pragma warning disable IDE0032 + private readonly cpBody body; +#pragma warning restore IDE0032 + + /// + /// The native handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public cpBody Handle => body; + + /// + /// Create a Dynamic Body with no mass and no moment. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body() + : this(BodyType.Dynamic) + { + } + + internal Body(cpBody handle) + { + body = handle; + RegisterUserData(); + } + + /// + /// Create a of the given . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body(BodyType type) + { + body = InitializeBody(type); + RegisterUserData(); + } + + /// + /// Creates a body with the given mass and moment. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body(double mass, double moment) : this(mass, moment, BodyType.Dynamic) + { + } + + /// + /// Creates a body with the given mass and moment, of the give . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body(double mass, double moment, BodyType type) + { + body = InitializeBody(type); + NativeMethods.cpBodySetMass(body, mass); + NativeMethods.cpBodySetMoment(body, moment); + RegisterUserData(); + } + + void RegisterUserData() + { + cpDataPointer pointer = NativeInterop.RegisterHandle(this); + NativeMethods.cpBodySetUserData(body, pointer); + } + + void ReleaseUserData() + { + cpDataPointer pointer = NativeMethods.cpBodyGetUserData(body); + NativeInterop.ReleaseHandle(pointer); + } + + /// + /// Get a object from a native cpBody handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Body FromHandle(cpBody body) + { + cpDataPointer handle = NativeMethods.cpBodyGetUserData(body); + return NativeInterop.FromIntPtr(handle); + } + + /// + /// Get the managed object from the native handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Body FromHandleSafe(cpBody nativeBodyHandle) + { + if (nativeBodyHandle == IntPtr.Zero) + { + return null; + } + + return FromHandle(nativeBodyHandle); + } + + private static cpBody InitializeBody(BodyType type) + { + if (type == BodyType.Kinematic) + { + return NativeMethods.cpBodyNewKinematic(); + } + + if (type == BodyType.Static) + { + return NativeMethods.cpBodyNewStatic(); + } + + return NativeMethods.cpBodyNew(0.0, 0.0); + } + + /// + /// Destroy and free the body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Free() + { + var space = Space; + + if (space != null) + space.RemoveBody(this); + + ReleaseUserData(); + NativeMethods.cpBodyFree(body); + } + + /// + /// Dispose the body. + /// + protected virtual void Dispose(bool dispose) + { + if (!dispose) + { + Debug.WriteLine("Disposing body {0} on finalizer... (consider Dispose explicitly)", body); + } + + Free(); + } + + /// + /// Dispose the body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + // Properties + + /// + /// Arbitrary user data. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object Data { get; set; } + + /// + /// Rotation of the body in radians. When changing the rotation, you may also want to call + /// to update the collision detection information + /// for the attached shapes if you plan to make any queries against the space. A body + /// rotates around its center of gravity, not its position. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Angle + { + get => NativeMethods.cpBodyGetAngle(body); + set => NativeMethods.cpBodySetAngle(body, value); + } + + /// + /// Set body position and rotation angle (in radians) + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetTransform(Vect position, double angle) + { + NativeMethods.cpBodySetTransform(body, position, angle); + } + + /// + /// Get body position and rotation angle (in radians) + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void GetTransform(out Vect position, out double angle) + { + NativeMethods.cpBodyGetTransform(body, out position, out angle); + } + + /// + /// The way the body behaves in physics simulations. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BodyType Type + { + get => (BodyType)NativeMethods.cpBodyGetType(body); + set => NativeMethods.cpBodySetType(body, (int)value); + } + + /// + /// Mass of the rigid body. Mass does not have to be expressed in any particular units, but + /// relative masses should be consistent. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Mass + { + get => NativeMethods.cpBodyGetMass(body); + set => NativeMethods.cpBodySetMass(body, value); + } + + /// + /// Moment of inertia of the body. The mass tells you how hard it is to push an object, + /// the MoI tells you how hard it is to spin the object. Don't try to guess the MoI, use the + /// MomentFor*() functions to estimate it, or the physics may behave strangely. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Moment + { + get => NativeMethods.cpBodyGetMoment(body); + set => NativeMethods.cpBodySetMoment(body, value); + } + + /// + /// Get the space this body is associated with, or null if it is not currently associated. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Space Space + { + get + { + cpSpace space = NativeMethods.cpBodyGetSpace(body); + return Space.FromHandleSafe(space); + } + } + + /// + /// Position of the body. When changing the position, you may also want to call + /// to update the collision detection information + /// for the attached shapes if you plan to make any queries against the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Position + { + get => NativeMethods.cpBodyGetPosition(body); + set => NativeMethods.cpBodySetPosition(body, value); + } + + /// + /// Location of the center of gravity in body-local coordinates. The default value is + /// (0, 0), meaning the center of gravity is the same as the position of the body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect CenterOfGravity + { + get => NativeMethods.cpBodyGetCenterOfGravity(body); + set => NativeMethods.cpBodySetCenterOfGravity(body, value); + } + + /// + /// Linear velocity of the center of gravity of the body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Velocity + { + get => NativeMethods.cpBodyGetVelocity(body); + set => NativeMethods.cpBodySetVelocity(body, value); + } + + /// + /// Force applied to the center of gravity of the body. This value is reset for every time + /// step. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Force + { + get => NativeMethods.cpBodyGetForce(body); + set => NativeMethods.cpBodySetForce(body, value); + } + + /// + /// The angular velocity of the body in radians per second. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double AngularVelocity + { + get => NativeMethods.cpBodyGetAngularVelocity(body); + set => NativeMethods.cpBodySetAngularVelocity(body, value); + } + + /// + /// The torque applied to the body. This value is reset for every time step. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Torque + { + get => NativeMethods.cpBodyGetTorque(body); + set => NativeMethods.cpBodySetTorque(body, value); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(BodyArbiterIteratorFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void AddEachArbiterToArray(cpBody body, cpArbiter arbiter, IntPtr data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + var a = new Arbiter(arbiter); + list.Add(a); + } + + private static BodyArbiterIteratorFunction eachArbiterFunc = AddEachArbiterToArray; + + /// + /// The rotation vector for the body. Can be used with cpvrotate() or cpvunrotate() to perform fast rotations. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Rotation => NativeMethods.cpBodyGetRotation(body); + + /// + /// Get the list of body Arbiters + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Arbiters + { + get + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + NativeMethods.cpBodyEachArbiter(body, eachArbiterFunc.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + gcHandle.Free(); + return list; + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(BodyArbiterIteratorFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void AddEachConstraintToArray(cpBody body, cpConstraint constraint, IntPtr data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + var c = Constraint.FromHandle(constraint); + list.Add(c); + } + + private static BodyConstraintIteratorFunction eachConstraintFunc = AddEachConstraintToArray; + + /// + /// All constraints attached to the body + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Constraints + { + get + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + NativeMethods.cpBodyEachConstraint(body, eachConstraintFunc.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + gcHandle.Free(); + return list.ToArray(); + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(BodyShapeIteratorFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void AddEachShapeToArray(cpBody body, cpShape shape, IntPtr data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + var s = Shape.FromHandle(shape); + list.Add(s); + } + + private static BodyShapeIteratorFunction eachShapeFunc = AddEachShapeToArray; + + /// + /// All shapes attached to the body + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Shapes + { + get + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + NativeMethods.cpBodyEachShape(body, eachShapeFunc.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + gcHandle.Free(); + return list.ToArray(); + } + } + + /// + /// Returns true if body is sleeping. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsSleeping => NativeMethods.cpBodyIsSleeping(body) != 0; + + // Actions + + /// + /// Reset the idle timer on a body. + /// If it was sleeping, wake it and any other bodies it was touching. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Activate() => NativeMethods.cpBodyActivate(body); + + /// + /// Similar in function to Activate(). Activates all bodies touching body. If filter is not NULL, then only bodies touching through filter will be awoken. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ActivateStatic(Shape filter) => NativeMethods.cpBodyActivateStatic(body, filter.Handle); + + /// + /// Add the local force force to body as if applied from the body local point. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ApplyForceAtLocalPoint(Vect force, Vect point) + { + NativeMethods.cpBodyApplyForceAtLocalPoint(body, force, point); + } + + /// + /// Apply torque. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ApplyTorque(double torque) + { + NativeMethods.cpBodyApplyTorque(body, torque); + } + + /// + /// Apply angular impulse. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ApplyAngularImpulse(double impulse) + { + NativeMethods.cpBodyApplyAngularImpulse(body, impulse); + } + + /// + /// Add the force force to body as if applied from the world point. + /// People are sometimes confused by the difference between a force and an impulse. + /// An impulse is a very large force applied over a very short period of time. + /// Some examples are a ball hitting a wall or cannon firing. + /// Chipmunk treats impulses as if they occur instantaneously by adding directly to the velocity of an object. + /// Both impulses and forces are affected the mass of an object. + /// Doubling the mass of the object will halve the effect. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ApplyForceAtWorldPoint(Vect force, Vect point) + { + NativeMethods.cpBodyApplyForceAtWorldPoint(body, force, point); + } + + /// + /// Apply an impulse to a body. Both the impulse and point are expressed in world coordinates. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ApplyImpulseAtWorldPoint(Vect impulse, Vect point) + { + NativeMethods.cpBodyApplyImpulseAtWorldPoint(body, impulse, point); + } + + /// + /// Apply an impulse to a body. Both the impulse and point are expressed in body local coordinates. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ApplyImpulseAtLocalPoint(Vect impulse, Vect point) + { + NativeMethods.cpBodyApplyImpulseAtLocalPoint(body, impulse, point); + } + + /// + /// Forces a body to fall asleep immediately even if it’s in midair. Cannot be called from a callback. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Sleep() + { + NativeMethods.cpBodySleep(body); + } + + /// + /// When objects in Chipmunk sleep, they sleep as a group of all objects that are touching or jointed together. + /// When an object is woken up, all of the objects in its group are woken up. + /// SleepWithGroup() allows you group sleeping objects together. It acts identically to Sleep() if you pass null as + /// group by starting a new group. + /// If you pass a sleeping body for group, body will be awoken when group is awoken. + /// You can use this to initialize levels and start stacks of objects in a pre-sleeping state. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void SleepWithGroup(Body group) + { + NativeMethods.cpBodySleepWithGroup(body, group != null ? group.Handle : IntPtr.Zero); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(BodyVelocityFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void BodyVelocityFunctionCallback(cpBody bodyHandle, Vect gravity, double damping, double dt) + { + var body = FromHandle(bodyHandle); + + body.velocityUpdateFunction(body, gravity, damping, dt); + } + + private static BodyVelocityFunction BodyVelocityFunctionCallbackDelegate = BodyVelocityFunctionCallback; + + private Action velocityUpdateFunction; + /// + /// Set the callback used to update a body's velocity. + /// Parameters: body, gravity, damping and deltaTime + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action VelocityUpdateFunction + { + get => velocityUpdateFunction; + set + { + velocityUpdateFunction = value; + + IntPtr callbackPointer; + + if (value == null) + callbackPointer = NativeMethods.cpBodyGetDefaultVelocityUpdateFunc(); + else + callbackPointer = BodyVelocityFunctionCallbackDelegate.ToFunctionPointer(); + + NativeMethods.cpBodySetVelocityUpdateFunc(body, callbackPointer); + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(BodyPositionFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void BodyPositionFunctionCallback(cpBody bodyHandle, double dt) + { + var body = FromHandle(bodyHandle); + + body.positionUpdateFunction(body, dt); + } + + private static BodyPositionFunction BodyUpdateFunctionCallbackDelegate = BodyPositionFunctionCallback; + + private Action positionUpdateFunction; + + /// + /// Set the callback used to update a body's position. + /// Parameters: body, deltaTime + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action PositionUpdateFunction + { + get => positionUpdateFunction; + set + { + positionUpdateFunction = value; + + IntPtr callbackPointer; + + if (value == null) + callbackPointer = NativeMethods.cpBodyGetDefaultPositionUpdateFunc(); + else + callbackPointer = BodyUpdateFunctionCallbackDelegate.ToFunctionPointer(); + + NativeMethods.cpBodySetPositionUpdateFunc(body, callbackPointer); + } + } + + /// + /// Default velocity integration function.. + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void UpdateVelocity(Vect gravity, double damping, double dt) + { + NativeMethods.cpBodyUpdateVelocity(body, gravity, damping, dt); + } + + /// + /// Default position integration function. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void UpdatePosition(double dt) + { + NativeMethods.cpBodyUpdatePosition(body, dt); + } + + /// + /// Convert body relative/local coordinates to absolute/world coordinates. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect LocalToWorld(Vect point) + { + return NativeMethods.cpBodyLocalToWorld(body, point); + } + + /// + /// Convert body absolute/world coordinates to relative/local coordinates. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect WorldToLocal(Vect point) + { + return NativeMethods.cpBodyWorldToLocal(body, point); + } + + /// + /// Get the velocity on a body (in world units) at a point on the body in world coordinates. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect GetVelocityAtWorldPoint(Vect point) + { + return NativeMethods.cpBodyGetVelocityAtWorldPoint(body, point); + } + + /// + /// Get the velocity on a body (in world units) at a point on the body in local coordinates. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect GetVelocityAtLocalPoint(Vect point) + { + return NativeMethods.cpBodyGetVelocityAtLocalPoint(body, point); + } + + /// + /// Get the kinetic energy of a body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double KineticEnergy => NativeMethods.cpBodyKineticEnergy(body); + + /// + /// Calculate the moment of inertia for a solid box centered on the body. + /// + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double MomentForBox(double mass, double width, double height) + { + return NativeMethods.cpMomentForBox(mass, width, height); + } + + /// + /// Get the list of all bodies in contact with this one + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList AllContactedBodies + { + get + { + int count = NativeMethods.cpBodyGetContactedBodiesCount(body); + + if (count == 0) + return Array.Empty(); + + IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + NativeMethods.cpBodyGetUserDataContactedBodies(body, ptrBodies); + + IntPtr[] userDataArray = new IntPtr[count]; + + Marshal.Copy(ptrBodies, userDataArray, 0, count); + + Marshal.FreeHGlobal(ptrBodies); + + Body[] bodies = new Body[count]; + + for (int i = 0; i < count; i++) + { + Body b = NativeInterop.FromIntPtr(userDataArray[i]); + bodies[i] = b; + } + + return bodies; + } + } + + /// + /// Check if a Body is in contact with another + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ContactWith(Body other) + { + return NativeMethods.cpBodyContactWith(body, other.body) != 0; + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/BodyType.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BodyType.cs new file mode 100644 index 00000000000..ebf2a9314d9 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BodyType.cs @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Chipmunk supports three different types of bodies with unique behavioral and performance + /// characteristics. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public enum BodyType + { + /// + /// Dynamic bodies are the default body type. They react to collisions, are affected by + /// forces and gravity, and have a finite amount of mass. These are the type of bodies that + /// you want the physics engine to simulate for you. Dynamic bodies interact with all types + /// of bodies and can generate collision callbacks. + /// + Dynamic, + + /// + /// Kinematic bodies are bodies that are controlled from your code instead of from the + /// physics engine. They aren't affected by gravity and they have an infinite amount of + /// mass, so they don’t react to collisions or forces with other bodies. Kinematic bodies + /// are controlled by setting their velocity, which will cause them to move. Good examples + /// of kinematic bodies might include things like moving platforms. Objects that are + /// touching or jointed to a kinematic body are never allowed to fall asleep. + /// + Kinematic, + + /// + /// Static bodies are bodies that never (or rarely) move. Using static bodies for things + /// like terrain offers a big performance boost over other body types -- Chipmunk doesn't + /// need to check for collisions between static objects and it never needs to update their + /// collision information. Additionally, because static bodies don’t move, Chipmunk knows + /// it’s safe to let objects that are touching or jointed to them fall asleep. Generally, + /// all of your level geometry will be attached to a static body, except for things like + /// moving platforms or doors. Every space provides a built-in static body for your + /// convenience. Static bodies can be moved, but there is a performance penalty as the + /// collision information is recalculated. There is no penalty for having multiple static + /// bodies, and it can be useful in simplifying your code to allow different parts of your + /// static geometry to be initialized or moved separately. + /// + Static + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs new file mode 100644 index 00000000000..535bf4e258d --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; + +#pragma warning disable IDE1006 +#pragma warning disable IDE0032 + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Chipmunk's axis-aligned 2D bounding box type. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] + public struct BoundingBox : IEquatable + { + private double left; + private double bottom; + private double right; + private double top; + + /// + /// Create a bounding box with the given coordinates. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BoundingBox(double left, double bottom, double right, double top) + { + this.left = left; + this.bottom = bottom; + this.right = right; + this.top = top; + } + + /// + /// Left value of bounding box. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Left { get => left; set => left = value; } + + /// + /// Bottom value of bouding box. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Bottom { get => bottom; set => bottom = value; } + + /// + /// Right value of bouding box. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Right { get => right; set => right = value; } + + /// + /// Top value of bouding box. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Top { get => top; set => top = value; } + + /// + /// Return true if the dimensions of both bounding boxes are equal to another (within + /// distance of each other.) + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(BoundingBox other) + { + return Math.Abs(left - other.left) < float.Epsilon && + Math.Abs(bottom - other.bottom) < float.Epsilon && + Math.Abs(right - other.right) < float.Epsilon && + Math.Abs(top - other.top) < float.Epsilon; + } + + /// + /// Return true if the given object is reference-equal. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + var bb = obj as BoundingBox?; + if (bb == null) + { + return false; + } + + return this == bb.Value; + } + + /// + /// Get the bounding box hash code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + var hashCode = -1064806749; + +#pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()' + hashCode = hashCode * -1521134295 + left.GetHashCode(); + hashCode = hashCode * -1521134295 + bottom.GetHashCode(); + hashCode = hashCode * -1521134295 + right.GetHashCode(); + hashCode = hashCode * -1521134295 + top.GetHashCode(); +#pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()' + + return hashCode; + } + + /// + /// Return a string displaying coordinates formatted like (left, bottom, right, top). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() + { + return $"({left},{bottom},{right},{top})"; + } + + /// + /// Return true if the dimensions of both bounding boxes are within + /// of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(BoundingBox left, BoundingBox right) + { + return left.Equals(right); + } + + /// + /// Return true if the dimensions of both bounding boxes are not within + /// of each other. + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(BoundingBox left, BoundingBox right) + { + return !(left == right); + } + } +} + +#pragma warning restore IDE1006 +#pragma warning restore IDE0032 diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/CollisionHandler.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/CollisionHandler.cs new file mode 100644 index 00000000000..c325a6a1253 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/CollisionHandler.cs @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using cpArbiter = System.IntPtr; +using cpBool = System.Byte; +using cpCollisionHandlerPointer = System.IntPtr; +using cpSpace = System.IntPtr; +using voidptr_t = System.IntPtr; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// A collision handler is a set of 4 function callbacks for the different collision events that + /// Chipmunk recognizes. Collision callbacks are closely associated with + /// objects. You should familiarize yourself with those as well. Note #1: Shapes tagged as + /// sensors ( == true) never generate collisions that get processed, + /// so collisions between sensor shapes and other shapes will never call the post_solve() + /// callback. They still generate begin() and separate() callbacks, and the pre_solve() callback + /// is also called every frame even though there is no collision response. Note #2: pre_solve() + /// callbacks are called before the sleeping algorithm runs. If an object falls asleep, its + /// post_solve() callback won’t be called until it’s re-awoken. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class CollisionHandler + { + private readonly cpCollisionHandlerPointer handle; + + private static CollisionBeginFunction beginCallback = CollisionBeginFunctionCallback; + private static CollisionPreSolveFunction preSolveCallback = CollisionPreSolveFunctionCallback; + private static CollisionPostSolveFunction postSolveCallback = CollisionPostSolveFunctionCallback; + private static CollisionSeparateFunction separeteCallback = CollisionSeparateFunctionCallback; + + private static IntPtr DefaultBeginFunction; + private static IntPtr DefaultPreSolveFunction; + private static IntPtr DefaultPostSolveFunction; + private static IntPtr DefaultSeparateFunction; + + private CollisionHandler(cpCollisionHandlerPointer collisionHandle, ref cpCollisionHandler handler) + { + handle = collisionHandle; + + IntPtr data = NativeInterop.RegisterHandle(this); + + handler.userData = data; + + long typeA = (long)handler.typeA.ToUInt64(); + long typeB = (long)handler.typeB.ToUInt64(); + + TypeA = unchecked((int)typeA); + TypeB = unchecked((int)typeB); + + cpCollisionHandler.ToPointer(handler, handle); + } + + internal static CollisionHandler GetOrCreate(cpCollisionHandlerPointer collisionHandle) + { + Debug.Assert(collisionHandle != IntPtr.Zero, "CollisionHandle cannot be zero"); + + var handler = cpCollisionHandler.FromHandle(collisionHandle); + + if (handler.userData != IntPtr.Zero) + { + return NativeInterop.FromIntPtr(handler.userData); + } + + EnsureDefaultCallbackValues(handler); + + return new CollisionHandler(collisionHandle, ref handler); + } + + private static void EnsureDefaultCallbackValues(cpCollisionHandler handler) + { + if (DefaultBeginFunction != IntPtr.Zero) + return; + + DefaultBeginFunction = handler.beginFunction; + DefaultPreSolveFunction = handler.preSolveFunction; + DefaultPostSolveFunction = handler.postSolveFunction; + DefaultSeparateFunction = handler.separateFunction; + } + + private Action begin; + + /// + /// This function is called when two shapes with types that match this collision handler begin colliding + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action Begin + { + set + { + begin = value; + + var handler = cpCollisionHandler.FromHandle(handle); + + IntPtr callbackPointer; + + if (value == null) + { + callbackPointer = DefaultBeginFunction; + } + else + { + callbackPointer = beginCallback.ToFunctionPointer(); + } + + handler.beginFunction = callbackPointer; + + cpCollisionHandler.ToPointer(handler, handle); + } + get => begin; + } + + private Func preSolve; + + /// + /// This function is called each step when two shapes with types that match this collision + /// handler are colliding. It's called before the collision solver runs so that you can + /// affect a collision's outcome. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Func PreSolve + { + set + { + preSolve = value; + var handler = cpCollisionHandler.FromHandle(handle); + IntPtr callbackPointer; + + if (value == null) + { + callbackPointer = DefaultPreSolveFunction; + } + else + { + callbackPointer = preSolveCallback.ToFunctionPointer(); + } + + handler.preSolveFunction = callbackPointer; + cpCollisionHandler.ToPointer(handler, handle); + } + get => preSolve; + } + + private Action postSolve; + + /// + /// This function is called each step when two shapes with types that match this collision + /// handler are colliding. It's called after the collision solver runs so that you can read + /// back information about the collision to trigger events in your game. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action PostSolve + { + set + { + postSolve = value; + var handler = cpCollisionHandler.FromHandle(handle); + IntPtr callbackPointer; + + if (value == null) + { + callbackPointer = DefaultPostSolveFunction; + } + else + { + callbackPointer = postSolveCallback.ToFunctionPointer(); + } + + handler.postSolveFunction = callbackPointer; + cpCollisionHandler.ToPointer(handler, handle); + } + get => postSolve; + } + + private Action separate; + + /// + /// This function is called when two shapes with types that match this collision handler + /// stop colliding. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action Separate + { + set + { + separate = value; + var handler = cpCollisionHandler.FromHandle(handle); + IntPtr callbackPointer; + + if (value == null) + { + callbackPointer = DefaultSeparateFunction; + } + else + { + callbackPointer = separeteCallback.ToFunctionPointer(); + } + + handler.separateFunction = callbackPointer; + cpCollisionHandler.ToPointer(handler, handle); + } + get => separate; + } + + /// + /// User definable context pointer that is passed to all of the collision handler functions. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object Data { get; set; } + + /// + /// In the collision handler callback, the shape with this type will be the first argument. + /// Read only. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int TypeA { get; } + + /// + /// In the collision handler callback, the shape with this type will be the second argument. + /// Read only. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int TypeB { get; } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(CollisionBeginFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void CollisionBeginFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData) + { + var arbiter = new Arbiter(arbiterHandle); + var space = Space.FromHandle(spaceHandle); + + var handler = NativeInterop.FromIntPtr(userData); + var begin = handler.Begin; + + if (begin == null) + { + return; + } + + begin(arbiter, space, handler.Data); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(CollisionPreSolveFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static cpBool CollisionPreSolveFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData) + { + var arbiter = new Arbiter(arbiterHandle); + var space = Space.FromHandle(spaceHandle); + + var handler = NativeInterop.FromIntPtr(userData); + var preSolve = handler.PreSolve; + + if (preSolve == null) + { + return 1; + } + + if (preSolve(arbiter, space, handler.Data)) + { + return 1; + } + + return 0; + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(CollisionPostSolveFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void CollisionPostSolveFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData) + { + var arbiter = new Arbiter(arbiterHandle); + var space = Space.FromHandle(spaceHandle); + + var handler = NativeInterop.FromIntPtr(userData); + var postSolve = handler.PostSolve; + + if (postSolve == null) + { + return; + } + + postSolve(arbiter, space, handler.Data); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(CollisionSeparateFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void CollisionSeparateFunctionCallback(cpArbiter arbiterHandle, cpSpace spaceHandle, voidptr_t userData) + { + var arbiter = new Arbiter(arbiterHandle); + var space = Space.FromHandle(spaceHandle); + + var handler = NativeInterop.FromIntPtr(userData); + var separate = handler.Separate; + + if (separate == null) + { + return; + } + + separate(arbiter, space, handler.Data); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/Constraint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/Constraint.cs new file mode 100644 index 00000000000..bf57b7a341e --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/Constraint.cs @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Diagnostics; +using System.ComponentModel; +using cpBody = System.IntPtr; +using cpConstraint = System.IntPtr; +using cpDataPointer = System.IntPtr; +using cpSpace = System.IntPtr; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Base class of all constraints. + /// You usually don’t want to create instances of this class directly, but instead use one of + /// the specific constraints such as the . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public abstract class Constraint : IDisposable + { +#pragma warning disable IDE0032 + cpConstraint constraint; +#pragma warning restore IDE0032 + + /// + /// Construct a constraint with the given native handle. + /// + /// + internal protected Constraint(cpConstraint handle) + { + constraint = handle; + RegisterUserData(); + } + + /// + /// Native handle to constraint. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public cpConstraint Handle => constraint; + + /// + /// Register managed object to native user data. + /// + private void RegisterUserData() + { + cpDataPointer pointer = NativeInterop.RegisterHandle(this); + NativeMethods.cpConstraintSetUserData(constraint, pointer); + } + + void ReleaseUserData() + { + cpDataPointer pointer = NativeMethods.cpConstraintGetUserData(constraint); + NativeInterop.ReleaseHandle(pointer); + } + + /// + /// Get a Constraint object from a native handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Constraint FromHandle(cpConstraint constraint) + { + cpDataPointer handle = NativeMethods.cpConstraintGetUserData(constraint); + return NativeInterop.FromIntPtr(handle); + } + + /// + /// Dispose the constraint. + /// + protected virtual void Dispose(bool dispose) + { + if (!dispose) + { + Debug.WriteLine("Disposing constraint {0} on finalizer... (consider Dispose explicitly)", constraint); + } + + Free(); + } + + /// + /// Destroy and free the constraint. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Free() + { + ReleaseUserData(); + NativeMethods.cpConstraintFree(constraint); + } + + /// + /// Destroy the constraint + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Get the cpSpace this constraint is added to. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Space Space + { + get + { + cpSpace space = NativeMethods.cpConstraintGetSpace(constraint); + return Space.FromHandleSafe(space); + } + } + + /// + /// Get the first body the constraint is attached to. + /// + public Body BodyA + { + get + { + cpBody body = NativeMethods.cpConstraintGetBodyA(constraint); + return Body.FromHandleSafe(body); + } + } + + /// + /// Get the second body the constraint is attached to. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body BodyB + { + get + { + cpBody body = NativeMethods.cpConstraintGetBodyB(constraint); + return Body.FromHandleSafe(body); + } + } + + /// ; + /// The maximum force that this constraint is allowed to use. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double MaxForce + { + get => NativeMethods.cpConstraintGetMaxForce(constraint); + set => NativeMethods.cpConstraintSetMaxForce(constraint, value); + } + + /// + /// Rate at which joint error is corrected. + /// Defaults to pow(1.0 - 0.1, 60.0) meaning that it will + /// correct 10% of the error every 1/60th of a second. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double ErrorBias + { + get => NativeMethods.cpConstraintGetErrorBias(constraint); + set => NativeMethods.cpConstraintSetErrorBias(constraint, value); + } + + + /// + /// The maximum rate at which joint error is corrected. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double MaxBias + { + get => NativeMethods.cpConstraintGetMaxBias(constraint); + set => NativeMethods.cpConstraintSetMaxBias(constraint, value); + } + + /// + /// Whether the two bodies connected by the constraint are allowed to collide or not. + /// + /// When two bodies collide, Chipmunk ignores the collisions if this property is set to + /// False on any constraint that connects the two bodies. Defaults to True. This can be + /// used to create a chain that self-collides, but adjacent links in the chain do not collide. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool CollideBodies + { + get => NativeMethods.cpConstraintGetCollideBodies(constraint) != 0; + set => NativeMethods.cpConstraintSetCollideBodies(constraint, value ? (byte)1 : (byte)0); + } + + private static ConstraintSolveFunction preSolveFunctionCallback = ConstraintPreSolveFunctionCallback; + private static ConstraintSolveFunction postSolveFunctionCallback = ConstraintPostSolveFunctionCallback; + + private Action preSolve; + private Action postSolve; + + /// + /// Pre-solve function that is called before the solver runs. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action PreSolve + { + get => preSolve; + set + { + preSolve = value; + + IntPtr callbackPointer; + + if (value == null) + callbackPointer = IntPtr.Zero; + else + callbackPointer = preSolveFunctionCallback.ToFunctionPointer(); + + NativeMethods.cpConstraintSetPreSolveFunc(constraint, callbackPointer); + } + } + + /// + /// Post-solve function that is called after the solver runs. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action PostSolve + { + get => postSolve; + set + { + postSolve = value; + + IntPtr callbackPointer; + + if (value == null) + callbackPointer = IntPtr.Zero; + else + callbackPointer = postSolveFunctionCallback.ToFunctionPointer(); + + NativeMethods.cpConstraintSetPostSolveFunc(constraint, callbackPointer); + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(ConstraintSolveFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void ConstraintPreSolveFunctionCallback(cpConstraint constraintHandle, cpSpace spaceHandle) + { + var constraint = Constraint.FromHandle(constraintHandle); + var space = Space.FromHandle(spaceHandle); + + Action preSolve = constraint.PreSolve; + + preSolve(constraint, space); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(ConstraintSolveFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void ConstraintPostSolveFunctionCallback(cpConstraint constraintHandle, cpSpace spaceHandle) + { + var constraint = Constraint.FromHandle(constraintHandle); + var space = Space.FromHandle(spaceHandle); + + Action postSolve = constraint.PostSolve; + + postSolve(constraint, space); + } + + /// + /// The user-definable data pointer for this constraint. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object Data { get; set; } + + /// + /// Get the last impulse applied by this constraint. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Impulse => NativeMethods.cpConstraintGetImpulse(constraint); + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedRotarySpring.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedRotarySpring.cs new file mode 100644 index 00000000000..44ad728aaac --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedRotarySpring.cs @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +using cpConstraint = System.IntPtr; + + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// DampedRotarySpring works like , but in an angular fashion. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class DampedRotarySpring : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsDampedRotarySpring(Constraint constraint) => NativeMethods.cpConstraintIsDampedRotarySpring(constraint.Handle) != 0; + + /// + /// Create a damped rotary spring. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public DampedRotarySpring( + Body bodyA, + Body bodyB, + double restAngle, + double stiffness, + double damping) + : base( + NativeMethods.cpDampedRotarySpringNew( + bodyA.Handle, + bodyB.Handle, + restAngle, + stiffness, + damping)) + { + originalTorqueCallbackPointer = NativeMethods.cpDampedRotarySpringGetSpringTorqueFunc(Handle); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(DampedRotarySpringTorqueFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static double DampedRotarySpringTorqueCallback(cpConstraint springHandle, double relativeAngle) + { + var constraint = (DampedRotarySpring)FromHandle(springHandle); + + Func dampedRotarySpringTorqueFunction = constraint.TorqueFunction; + + return dampedRotarySpringTorqueFunction(constraint, relativeAngle); + } + + private static DampedRotarySpringTorqueFunction DampedRotarySpringForceCallback = DampedRotarySpringTorqueCallback; + + /// + /// The rest angle of the spring. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double RestAngle + { + get => NativeMethods.cpDampedRotarySpringGetRestAngle(Handle); + set => NativeMethods.cpDampedRotarySpringSetRestAngle(Handle, value); + } + + /// + /// The stiffness of the spring in force/distance. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Stiffness + { + get => NativeMethods.cpDampedRotarySpringGetStiffness(Handle); + set => NativeMethods.cpDampedRotarySpringSetStiffness(Handle, value); + } + + /// + /// The damping of the spring. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Damping + { + get => NativeMethods.cpDampedRotarySpringGetDamping(Handle); + set => NativeMethods.cpDampedRotarySpringSetDamping(Handle, value); + } + + private Func torqueFunction; + private IntPtr originalTorqueCallbackPointer; + + /// + /// Damped rotary spring torque custom function callback. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Func TorqueFunction + { + get => torqueFunction; + set + { + torqueFunction = value; + + IntPtr callbackPointer; + + if (value == null) + { + callbackPointer = originalTorqueCallbackPointer; + } + else + { + callbackPointer = DampedRotarySpringForceCallback.ToFunctionPointer(); + } + + NativeMethods.cpDampedRotarySpringSetSpringTorqueFunc(Handle, callbackPointer); + } + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedSpring.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedSpring.cs new file mode 100644 index 00000000000..9ffa3233f7a --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/DampedSpring.cs @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +using cpConstraint = System.IntPtr; + + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// is a damped spring. + /// The spring allows you to define the rest length, stiffness and damping. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class DampedSpring : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsDampedSpring(Constraint constraint) => NativeMethods.cpConstraintIsDampedSpring(constraint.Handle) != 0; + + /// + /// Defined much like a slide joint. + /// + /// The first connected body. + /// The second connected body. + /// Anchor point a, relative to body a. + /// Anchor point b, relative to body b. + /// The distance the spring wants to be. + /// The spring constant (Young’s modulus). + /// How soft to make the damping of the spring. + [EditorBrowsable(EditorBrowsableState.Never)] + public DampedSpring( + Body bodyA, + Body bodyB, + Vect anchorA, + Vect anchorB, + double restLength, + double stiffness, + double damping) + : base(NativeMethods.cpDampedSpringNew( + bodyA.Handle, + bodyB.Handle, + anchorA, + anchorB, + restLength, + stiffness, + damping)) + { + originalForceCallbackPointer = NativeMethods.cpDampedSpringGetSpringForceFunc(Handle); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(DampedSpringForceFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static double DampedSpringForceCallback(cpConstraint springHandle, double distance) + { + var constraint = (DampedSpring)Constraint.FromHandle(springHandle); + + Func dampedSpringForceFunction = constraint.forceFunction; + + return dampedSpringForceFunction(constraint, distance); + } + + private static DampedSpringForceFunction dampedSpringForceCallback = DampedSpringForceCallback; + + /// + /// The location of the first anchor relative to the first body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorA + { + get => NativeMethods.cpDampedSpringGetAnchorA(Handle); + set => NativeMethods.cpDampedSpringSetAnchorA(Handle, value); + } + + /// + /// The location of the second anchor relative to the second body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorB + { + get => NativeMethods.cpDampedSpringGetAnchorB(Handle); + set => NativeMethods.cpDampedSpringSetAnchorB(Handle, value); + } + + /// + /// The rest length of the spring. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double RestLength + { + get => NativeMethods.cpDampedSpringGetRestLength(Handle); + set => NativeMethods.cpDampedSpringSetRestLength(Handle, value); + } + + /// + /// The stiffness of the spring in force/distance. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Stiffness + { + get => NativeMethods.cpDampedSpringGetStiffness(Handle); + set => NativeMethods.cpDampedSpringSetStiffness(Handle, value); + } + + /// + /// The damping of the spring. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Damping + { + get => NativeMethods.cpDampedSpringGetDamping(Handle); + set => NativeMethods.cpDampedSpringSetDamping(Handle, value); + } + + private Func forceFunction; + + private IntPtr originalForceCallbackPointer; + + /// + /// Damped spring force custom function callback. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Func ForceFunction + { + get => forceFunction; + set + { + forceFunction = value; + + IntPtr callbackPointer; + + if (value == null) + { + callbackPointer = originalForceCallbackPointer; + } + else + { + callbackPointer = dampedSpringForceCallback.ToFunctionPointer(); + } + + NativeMethods.cpDampedSpringSetSpringForceFunc(Handle, callbackPointer); + } + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GearJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GearJoint.cs new file mode 100644 index 00000000000..601342ea6d6 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GearJoint.cs @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// keeps the angular velocity ratio of a pair of bodies constant. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class GearJoint : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsGearJoint(Constraint constraint) => NativeMethods.cpConstraintIsGearJoint(constraint.Handle) != 0; + + /// + /// Keeps the angular velocity ratio of a pair of bodies constant. + /// + /// The first connected body. + /// The second connected body. + /// The seconded connected body. + /// + /// Measured in absolute terms. It is currently not possible to set + /// the ratio in relation to a third body’s angular velocity. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public GearJoint(Body bodyA, Body bodyB, double phase, double ratio) : + base(NativeMethods.cpGearJointNew(bodyA.Handle, bodyB.Handle, phase, ratio)) + { + } + + /// + /// The phase offset of the gears. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Phase + { + get => NativeMethods.cpGearJointGetPhase(Handle); + set => NativeMethods.cpGearJointSetPhase(Handle, value); + } + + /// + /// The ratio of a gear joint. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Ratio + { + get => NativeMethods.cpGearJointGetRatio(Handle); + set => NativeMethods.cpGearJointSetRatio(Handle, value); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GrooveJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GrooveJoint.cs new file mode 100644 index 00000000000..e295b31645f --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/GrooveJoint.cs @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// is similar to a , but with a linear slide. + /// One of the anchor points is a line segment that the pivot can slide on instead of being fixed. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class GrooveJoint : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsGrooveJoint(Constraint constraint) => NativeMethods.cpConstraintIsGrooveJoint(constraint.Handle) != 0; + + /// + /// Create an anchor where can rotate similar to a + /// , except it's anchored at , which is a + /// point that can slide between and . + /// + /// The first connected body. + /// The second connected body. + /// + /// The start of the groove on . Coordinates are local to the body. + /// + /// + /// The end of the groove on . Coordinates are local to the body. + /// + /// + /// The location of the pivot on . Coordinates are local to the + /// body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public GrooveJoint(Body bodyA, Body bodyB, Vect grooveA, Vect grooveB, Vect anchorB) + : base(NativeMethods.cpGrooveJointNew(bodyA.Handle, bodyB.Handle, grooveA, grooveB, anchorB)) + { + } + + /// + /// The first endpoint of the groove relative to the first body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect GrooveA + { + get => NativeMethods.cpGrooveJointGetGrooveA(Handle); + set => NativeMethods.cpGrooveJointSetGrooveA(Handle, value); + } + + /// + /// The second endpoint of the groove relative to the first body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect GrooveB + { + get => NativeMethods.cpGrooveJointGetGrooveB(Handle); + set => NativeMethods.cpGrooveJointSetGrooveB(Handle, value); + } + + /// + /// The location of the second anchor relative to the second body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorB + { + get => NativeMethods.cpGrooveJointGetAnchorB(Handle); + set => NativeMethods.cpGrooveJointSetAnchorB(Handle, value); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PinJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PinJoint.cs new file mode 100644 index 00000000000..f0f9e943d74 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PinJoint.cs @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// links shapes with a solid bar or pin. Keeps the anchor points at a + /// set distance from one another. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class PinJoint : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsPinJoint(Constraint constraint) => NativeMethods.cpConstraintIsPinJoint(constraint.Handle) != 0; + + /// + /// The distance between the two anchor points is measured when the joint is created. If you + /// want to set a specific distance, use the setter function to override it. + /// + /// One of the two bodies to connect. + /// One of the two bodies to connect. + /// The anchor point for . + /// The anchor point for . + [EditorBrowsable(EditorBrowsableState.Never)] + public PinJoint(Body bodyA, Body bodyB, Vect anchorA, Vect anchorB) + : base(NativeMethods.cpPinJointNew(bodyA.Handle, bodyB.Handle, anchorA, anchorB)) + { + } + + /// + /// The location of the first anchor relative to the first body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorA + { + get => NativeMethods.cpPinJointGetAnchorA(Handle); + set => NativeMethods.cpPinJointSetAnchorA(Handle, value); + } + + /// + /// The location of the second anchor relative to the second body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorB + { + get => NativeMethods.cpPinJointGetAnchorB(Handle); + set => NativeMethods.cpPinJointSetAnchorB(Handle, value); + } + + /// + /// The distance the joint will maintain between the two anchors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Distance + { + get => NativeMethods.cpPinJointGetDist(Handle); + set => NativeMethods.cpPinJointSetDist(Handle, value); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PivotJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PivotJoint.cs new file mode 100644 index 00000000000..de7a9bdffb1 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/PivotJoint.cs @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// acts like a swivel, allowing two objects to pivot about a single + /// point. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class PivotJoint : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsPivotJoint(Constraint constraint) => NativeMethods.cpConstraintIsPivotJoint(constraint.Handle) != 0; + + /// + /// Initialize a pivot joint with two anchors. Since the anchors are provided in world + /// coordinates, the bodies must already be correctly positioned. The joint is fixed as soon + /// as the containing space is simulated. + /// + /// One of the two bodies to connect. + /// One of the two bodies to connect. + /// + /// The location of one of the anchors, specified in world coordinates. + /// + /// + /// The location of one of the anchors, specified in world coordinates. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PivotJoint(Body bodyA, Body bodyB, Vect anchorA, Vect anchorB) + : base(NativeMethods.cpPivotJointNew2(bodyA.Handle, bodyB.Handle, anchorA, anchorB)) + { + } + + /// + /// Initialize a pivot joint with one anchor. Since the pivot is provided in world + /// coordinates, the bodies must already be correctly positioned. + /// + /// One of the two bodies to connect. + /// One of the two bodies to connect. + /// The location of the pivot, specified in world coordinates. + [EditorBrowsable(EditorBrowsableState.Never)] + public PivotJoint(Body bodyA, Body bodyB, Vect anchor) : + base(NativeMethods.cpPivotJointNew(bodyA.Handle, bodyB.Handle, anchor)) + { + + } + + /// + /// The location of the first anchor relative to the first body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorA + { + get => NativeMethods.cpPivotJointGetAnchorA(Handle); + set => NativeMethods.cpPivotJointSetAnchorA(Handle, value); + } + + /// + /// The location of the second anchor relative to the second body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorB + { + get => NativeMethods.cpPivotJointGetAnchorB(Handle); + set => NativeMethods.cpPivotJointSetAnchorB(Handle, value); + } + + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RatchetJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RatchetJoint.cs new file mode 100644 index 00000000000..4c368ac6114 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RatchetJoint.cs @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// is a rotary ratchet, which works like a socket wrench. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class RatchetJoint : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsRatchetJoint(Constraint constraint) => NativeMethods.cpConstraintIsRatchetJoint(constraint.Handle) != 0; + + /// + /// Works like a socket wrench. + /// + /// One of the two bodies to connect. + /// One of the two bodies to connect. + /// + /// The initial offset to use when deciding where the ratchet angles are. + /// + /// + /// The distance between "clicks" (following the socket wrench analogy). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public RatchetJoint(Body bodyA, Body bodyB, double phase, double ratchet) + : base(NativeMethods.cpRatchetJointNew(bodyA.Handle, bodyB.Handle, phase, ratchet)) + { + } + + /// + /// The angle of the current ratchet tooth. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Angle + { + get => NativeMethods.cpRatchetJointGetAngle(Handle); + set => NativeMethods.cpRatchetJointSetAngle(Handle, value); + } + + /// + /// The phase offset of the ratchet. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Phase + { + get => NativeMethods.cpRatchetJointGetPhase(Handle); + set => NativeMethods.cpRatchetJointSetPhase(Handle, value); + } + + /// + /// The angular distance of each ratchet. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Rachet + { + get => NativeMethods.cpRatchetJointGetRatchet(Handle); + set => NativeMethods.cpRatchetJointSetRatchet(Handle, value); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RotaryLimitJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RotaryLimitJoint.cs new file mode 100644 index 00000000000..16b6fa174e0 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/RotaryLimitJoint.cs @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// constrains the relative rotations of two bodies. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class RotaryLimitJoint : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsRotaryLimitJoint(Constraint constraint) => NativeMethods.cpConstraintIsRotaryLimitJoint(constraint.Handle) != 0; + + /// + /// Constrains the relative rotations of two bodies. + /// + /// + /// + /// + /// The minimum angular limit in radians. May be greater than 1 backwards revolution. + /// + /// + /// The maximum angular limit in radians. May be greater than 1 revolution. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public RotaryLimitJoint(Body bodyA, Body bodyB, double mininum, double maximum) + : base(NativeMethods.cpRotaryLimitJointNew(bodyA.Handle, bodyB.Handle, mininum, maximum)) + { + } + + /// + /// The minimum distance the joint will maintain between the two anchors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Minimum + { + get => NativeMethods.cpRotaryLimitJointGetMin(Handle); + set => NativeMethods.cpRotaryLimitJointSetMin(Handle, value); + } + + /// + /// The maximum distance the joint will maintain between the two anchors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Maximum + { + get => NativeMethods.cpRotaryLimitJointGetMax(Handle); + set => NativeMethods.cpRotaryLimitJointSetMax(Handle, value); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SimpleMotor.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SimpleMotor.cs new file mode 100644 index 00000000000..a8c2d8011d5 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SimpleMotor.cs @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// keeps the relative angular velocity constant. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class SimpleMotor : Constraint + { + /// + /// Check if constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsSimpleMotor(Constraint constraint) => NativeMethods.cpConstraintIsSimpleMotor(constraint.Handle) != 0; + + /// + /// Rotate with a constant relative angular velocity constant between two bodies. + /// + /// One of the two bodies. + /// One of the two bodies. + /// The rate of rotation. + [EditorBrowsable(EditorBrowsableState.Never)] + public SimpleMotor(Body bodyA, Body bodyB, double rate) + : base(NativeMethods.cpSimpleMotorNew(bodyA.Handle, bodyB.Handle, rate)) + { + } + + /// + /// The rate of the motor. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Rate + { + get => NativeMethods.cpSimpleMotorGetRate(Handle); + set => NativeMethods.cpSimpleMotorSetRate(Handle, value); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SlideJoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SlideJoint.cs new file mode 100644 index 00000000000..9b4681f0ec6 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Constraints/SlideJoint.cs @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// is like a , but with a minimum and maximum + /// distance. A chain could be modeled using this joint. It keeps the anchor points from getting + /// too far apart, but will allow them to get closer together. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class SlideJoint : Constraint + { + /// + /// Check if a constraint is a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsSlideJoint(Constraint constraint) => NativeMethods.cpConstraintIsSlideJoint(constraint.Handle) != 0; + + /// + /// Create a slide constraint between two bodies. + /// + /// One of the two bodies to connect. + /// One of the two bodies to connect. + /// The anchor point for . + /// The anchor point for . + /// The minimum distance the anchor points can get to each other. + /// The maximum distance the anchor points can be apart. + [EditorBrowsable(EditorBrowsableState.Never)] + public SlideJoint(Body bodyA, Body bodyB, Vect anchorA, Vect anchorB, double min, double max) + : base(NativeMethods.cpSlideJointNew(bodyA.Handle, bodyB.Handle, anchorA, anchorB, min, max)) + { + } + + /// + /// The location of the first anchor relative to the first body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorA + { + get => NativeMethods.cpSlideJointGetAnchorA(Handle); + set => NativeMethods.cpSlideJointSetAnchorA(Handle, value); + } + + /// + /// The location of the second anchor relative to the second body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect AnchorB + { + get => NativeMethods.cpSlideJointGetAnchorB(Handle); + set => NativeMethods.cpSlideJointSetAnchorB(Handle, value); + } + + /// + /// The minimum distance the joint will maintain between the two anchors + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Minimum + { + get => NativeMethods.cpSlideJointGetMin(Handle); + set => NativeMethods.cpSlideJointSetMin(Handle, value); + } + + /// + /// The maximum distance the joint will maintain between the two anchors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Maximum + { + get => NativeMethods.cpSlideJointGetMax(Handle); + set => NativeMethods.cpSlideJointSetMax(Handle, value); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs new file mode 100644 index 00000000000..d1233d3cefb --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Contains information about a contact point. and + /// are the contact positions on the surface of each shape. is the + /// penetration distance of the two, which is a negative value. This value is calculated as + /// dot(point2 - point1), normal) and is ignored when you set the + /// . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class ContactPoint : IEquatable + { +#pragma warning disable IDE0032 + private readonly Vect pointA; + private readonly Vect pointB; + private readonly double distance; +#pragma warning restore IDE0032 + + /// + /// Point A in the contact point. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect PointA => pointA; + + /// + /// Point B in the contact point. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect PointB => pointB; + + /// + /// The penetration distance of the two shapes (as a negative value). This value is + /// calculated as dot(point2 - point1), normal) and is ignored when you set the + /// . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Distance => distance; + + private ContactPoint(Vect pointA, Vect pointB, double distance) + { + this.pointA = pointA; + this.pointB = pointB; + this.distance = distance; + } + + /// + /// Returns true if neither is null and the points are within + /// distance of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(ContactPoint other) + { + if (ReferenceEquals(other, null)) + { + return false; + } + + return other.pointA.Equals(pointA) + && other.pointB.Equals(pointB) + && Math.Abs(other.distance - distance) < float.Epsilon; + } + + + /// + /// Check if this is equal to an object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + var other = obj as ContactPoint; + + if (other == null) + { + return false; + } + + return Equals(other); + } + + /// + /// Get the hash set. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + var hashCode = -1285340573; + + hashCode = hashCode * -1521134295 + pointA.GetHashCode(); + hashCode = hashCode * -1521134295 + pointB.GetHashCode(); + hashCode = hashCode * -1521134295 + distance.GetHashCode(); + + return hashCode; + } + + /// + /// Returns a string in the format of "a: {pointA}, b: {pointB}, distance: {distance}". + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() + { + return $"a: {pointA}, b: {pointB}, distance: {distance}"; + } + + /// + /// Returns true if both s are the same object or the dimensions + /// are within distance of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(ContactPoint left, ContactPoint right) + { + if (ReferenceEquals(left, null)) + { + return ReferenceEquals(right, null); + } + + return left.Equals(right); + } + + /// + /// Returns false if both s are the same object or the dimensions + /// are within distance of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(ContactPoint left, ContactPoint right) + { + return !(left == right); + } + + internal static ContactPoint Empty => new ContactPoint(Vect.Zero, Vect.Zero, 0.0); + + internal static ContactPoint FromCollidePoint(cpContactPoint contactPoint) + { + return new ContactPoint( + contactPoint.pointA, + contactPoint.pointB, + contactPoint.distance); + } + + internal cpContactPoint ToContactPoint() + { + return new cpContactPoint + { + pointA = pointA, + pointB = pointB, + distance = distance + }; + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs new file mode 100644 index 00000000000..8a623f0157e --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Contact point sets make getting contact information simpler. There can be at most 2 contact + /// points. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class ContactPointSet : IEquatable + { +#pragma warning disable IDE0032 + private readonly int count; + private readonly Vect normal; + private readonly ContactPoint[] points; +#pragma warning restore IDE0032 + + private ContactPointSet(int count, Vect normal, ContactPoint[] points) + { + this.count = count; + this.normal = normal; + this.points = points; + } + + /// + /// Get the number of contact points in the contact set (maximum of two). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int Count => count; + + /// + /// Get the normal of the collision. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Normal => normal; + + /// + /// List of points in the contact point set + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Points => points; + + /// + /// Return true if the contact point set is sequence-equal to another. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(ContactPointSet other) + { + if (ReferenceEquals(other, null) + || count != other.count + || normal != other.normal + || points.Length != other.points.Length) + { + return false; + } + + return points.SequenceEqual(other.points); + } + + /// + /// Get the hash code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + var hashCode = -475635172; + + hashCode = hashCode * -1521134295 + count.GetHashCode(); + hashCode = hashCode * -1521134295 + normal.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(points); + + return hashCode; + } + + /// + /// Return true if the is sequence-equal to another. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + var other = obj as ContactPointSet; + + if (other == null) + { + return false; + } + + return Equals(other); + } + + /// + /// Return true if the contact point sets are sequence-equal. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(ContactPointSet left, ContactPointSet right) + { + if (ReferenceEquals(left, null)) + { + return ReferenceEquals(right, null); + } + + return left.Equals(right); + } + + /// + /// Return true if the contact point sets are sequence-inequal. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(ContactPointSet left, ContactPointSet right) + { + return !(left == right); + } + + internal static ContactPointSet FromContactPointSet(cpContactPointSet contactPointSet) + { + var points = new ContactPoint[2]; + + if (contactPointSet.count > 0) + { + points[0] = ContactPoint.FromCollidePoint(contactPointSet.points0); + } + else + { + points[0] = ContactPoint.Empty; + } + + if (contactPointSet.count > 1) + { + points[1] = ContactPoint.FromCollidePoint(contactPointSet.points1); + } + else + { + points[1] = ContactPoint.Empty; + } + + return new ContactPointSet( + contactPointSet.count, + contactPointSet.normal, + points); + } + + internal cpContactPointSet ToContactPointSet() + { + return new cpContactPointSet + { + normal = normal, + points0 = points[0].ToContactPoint(), + points1 = points[1].ToContactPoint(), + count = count + }; + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs new file mode 100644 index 00000000000..223e8698663 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// RGBA channels as floats used to represent the color for debug drawing. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] + public struct DebugColor : IEquatable + { +#pragma warning disable IDE0032 + private readonly float red; + private readonly float green; + private readonly float blue; + private readonly float alpha; +#pragma warning restore IDE0032 + + /// + /// Red component in the RGBA color space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float Red => red; + + /// + /// Green component in the RGBA color space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float Green => green; + + /// + /// Blue component in the RGBA color space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float Blue => blue; + + /// + /// Alpha component in the RGBA color space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float Alpha => alpha; + + /// + /// Create a with the given color channel values. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public DebugColor(float red, float green, float blue) + : this(red, green, blue, 1.0f) + { + } + + /// + /// Create a with the given color channel values. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public DebugColor(float red, float green, float blue, float alpha) + { + this.red = red; + this.green = green; + this.blue = blue; + this.alpha = alpha; + } + + /// + /// Check if a is equal to another object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + var other = obj as DebugColor?; + + if (other == null) + return false; + + return Equals(other.Value); + } + + /// + /// Check if a is reference-equal to the other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(DebugColor color) + { + return this == color; + } + + /// + /// Get the hash code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + var hashCode = -1813971818; + + hashCode = hashCode * -1521134295 + red.GetHashCode(); + hashCode = hashCode * -1521134295 + green.GetHashCode(); + hashCode = hashCode * -1521134295 + blue.GetHashCode(); + hashCode = hashCode * -1521134295 + alpha.GetHashCode(); + + return hashCode; + } + + /// + /// Return a string formatted as "(R, G, B, A)". + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() + { + return $"({red},{green},{blue},{alpha})"; + } + + /// + /// Return true if two are reference-equal. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(DebugColor a, DebugColor b) + { +#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator + return a.red == b.red && + a.green == b.green && + a.blue == b.blue && + a.alpha == b.alpha; +#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator + } + + + /// + /// Return true if two are not reference-equal. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(DebugColor a, DebugColor b) + { + return !(a == b); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawColors.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawColors.cs new file mode 100644 index 00000000000..a64e7eadcc6 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawColors.cs @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Default DebugColors for ShapeOutline, Constraint and CollisionPoint + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class DebugDrawColors + { +#pragma warning disable IDE0032 + static readonly DebugDrawColors defaultColors = new DebugDrawColors() + { + ShapeOutline = new DebugColor(1, 1, 1), + Constraint = new DebugColor(0, 1, 0), + CollisionPoint = new DebugColor(1, 0, 1) + }; +#pragma warning restore IDE0032 + + /// + /// Shape outline color. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public DebugColor ShapeOutline { get; set; } + + /// + /// Constraint color. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public DebugColor Constraint { get; set; } + + /// + /// Collision point color. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public DebugColor CollisionPoint { get; set; } + + /// + /// The Default DebugDrawColors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static DebugDrawColors Default => defaultColors; + + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawFlags.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawFlags.cs new file mode 100644 index 00000000000..31e13c98248 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugDrawFlags.cs @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Flags to enable or disable DebugDrawing. + /// + [Flags] + [EditorBrowsable(EditorBrowsableState.Never)] + public enum DebugDrawFlags + { + /// + /// Draw nothing. + /// + None = 0, + + /// + /// Draw Shapes. + /// + Shapes = 1 << 0, + + /// + /// Draw Constraints. + /// + Constraints = 1 << 1, + + /// + /// Draw Collision Points. + /// + CollisionPoints = 1 << 2, + + /// + /// Draw All. + /// + All = Shapes | Constraints | CollisionPoints + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/HastySpace.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/HastySpace.cs new file mode 100644 index 00000000000..5c0e1cea1f9 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/HastySpace.cs @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Similar to , but with ARM NEON optimizations in the solver. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class HastySpace : Space + { + /// + /// On ARM platforms that support NEON, this will enable the vectorized solver. + /// also supports multiple threads, but runs single threaded by + /// default for determinism. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public HastySpace() + : base(NativeMethods.cpHastySpaceNew()) + { + } + + /// + /// The number of threads to use for the solver. Currently Chipmunk is limited to 2 threads + /// as using more generally provides very minimal performance gains. Passing 0 as the thread + /// count on iOS or OS X will cause Chipmunk to automatically detect the number of threads + /// it should use. On other platforms passing 0 for the thread count will set 1 thread. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int Threads + { + get => (int)NativeMethods.cpHastySpaceGetThreads(Handle); + set => NativeMethods.cpHastySpaceSetThreads(Handle, (uint)value); + } + + /// + /// Step in the hasty space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed override void Step(double dt) + { + NativeMethods.cpHastySpaceStep(Handle, dt); + } + + /// + /// Destroy and free the hasty space. + /// + protected override void FreeSpace(IntPtr handle) + { + NativeMethods.cpHastySpaceFree(handle); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/IDebugDraw.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/IDebugDraw.cs new file mode 100644 index 00000000000..2ea82a50c74 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/IDebugDraw.cs @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Interface to draw debug primitives (circle, point, segment). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public interface IDebugDraw + { + /// + /// Draw stroked circle. + /// + void DrawCircle(Vect pos, double angle, double radius, DebugColor outlineColor, DebugColor fillColor); + + /// + /// Draws a line segment. + /// + void DrawSegment(Vect a, Vect b, DebugColor color); + + /// + /// Draws a thick line segment. + /// + void DrawFatSegment(Vect a, Vect b, double radius, DebugColor outlineColor, DebugColor fillColor); + + /// + /// Draws a convex polygon. + /// + void DrawPolygon(Vect[] vectors, double radius, DebugColor outlineColor, DebugColor fillColor); + + /// + /// Draws a dot. + /// + void DrawDot(double size, Vect pos, DebugColor color); + + /// + /// Returns a color for a given shape. This gives you an opportunity to color shapes based + /// on how they are used in your engine. + /// + DebugColor ColorForShape(Shape shape); + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/MarchData.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/MarchData.cs new file mode 100644 index 00000000000..c5e5d76b5bd --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/MarchData.cs @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// March data used for . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class MarchData + { + /// + /// The bounding box. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BoundingBox BoundingBox { get; set; } + + /// + /// The number of horizontal samples. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int XSamples { get; set; } + + /// + /// The number of vertical samples. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int YSamples { get; set; } + + /// + /// The threshold. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Threshold { get; set; } + + /// + /// Callback for sampling/ + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Func SampleFunction { get; set; } + + /// + /// Callback for segmentation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Action SegmentFunction { get; set; } + + /// + /// User sample data. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object SampleData { get; set; } + + /// + /// User segmentation data. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object SegmentData { get; set; } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/PointQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/PointQueryInfo.cs new file mode 100644 index 00000000000..aead09bf103 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/PointQueryInfo.cs @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// holds the result of a point query made on a + /// or . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class PointQueryInfo : IEquatable + { +#pragma warning disable IDE0032 + private readonly Shape shape; + private readonly Vect point; + private readonly double distance; + private readonly Vect gradient; +#pragma warning restore IDE0032 + + /// + /// The nearest shape, None if no shape was within range. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Shape Shape => shape; + + /// + /// The closest point on the shape’s surface (in world space coordinates). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Point => point; + + /// + /// The distance to the point. The distance is negative if the point is inside the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Distance => distance; + + /// + /// The gradient of the signed distance function. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Gradient => gradient; + + /// + /// Create a . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PointQueryInfo(Shape s, Vect p, double d, Vect g) + { + shape = s; + point = p; + distance = d; + gradient = g; + } + + /// + /// Return true if this object is reference-equal to the given + /// object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + var other = obj as PointQueryInfo; + + if (other == null) + { + return false; + } + + return this == other; + } + + /// + /// Get the hash code. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + return shape.Handle.ToInt32() ^ + point.GetHashCode() ^ + distance.GetHashCode() ^ + (gradient.GetHashCode() << 4); + } + + /// + /// Return true if this object is reference-equal to the given + /// object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(PointQueryInfo left, PointQueryInfo right) + { + if (ReferenceEquals(left, null)) + { + return ReferenceEquals(right, null); + } + + return left.Equals(right); + } + + /// + /// Return true if this object is not reference-equal to the + /// given object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(PointQueryInfo a, PointQueryInfo b) + { + return !(a == b); + } + + internal static PointQueryInfo FromQueryInfo(cpPointQueryInfo queryInfo) + { + var shape = Shape.FromHandle(queryInfo.shape); + + return new PointQueryInfo( + shape, + queryInfo.point, + queryInfo.distance, + queryInfo.gradient); + } + + /// + /// Return true if this object's distance is within + /// of the other and all other fields are equivalent. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(PointQueryInfo other) + { + if (ReferenceEquals(other, null) || + shape.Handle != other.shape.Handle || + point != other.point || + gradient != other.gradient) + { + return false; + } + + return Math.Abs(distance - other.distance) < float.Epsilon; + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs new file mode 100644 index 00000000000..2a9779095cf --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Segment queries return where a shape was hit and its surface normal at the point of contact. + /// Use == null to test if a shape was hit. Segment queries + /// are like ray casting, but because not all spatial indexes allow processing infinitely long + /// ray queries, it's limited to segments. In practice, this is still very fast and you don’t + /// need to worry too much about the performance as long as you aren’t using extremely long + /// segments for your queries. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class SegmentQueryInfo : IEquatable + { +#pragma warning disable IDE0032 + private readonly Shape shape; + private readonly Vect point; + private readonly Vect normal; + private readonly double alpha; +#pragma warning restore IDE0032 + + /// + /// Shape that was hit, or None if no collision occured. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Shape Shape => shape; + + /// + /// The point of impact. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Point => point; + + /// + /// The normal of the surface that was hit. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Normal => normal; + + /// + /// The normalized distance along the query segment in the range [0, 1] + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Alpha => alpha; + + /// + /// Construct a Segment query info. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public SegmentQueryInfo(Shape s, Vect p, Vect n, double a) + { + shape = s; + point = p; + normal = n; + alpha = a; + } + + /// + /// Return true if the given object is reference-equal to this one. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + var other = obj as SegmentQueryInfo; + + if (other == null) + { + return false; + } + + return this == other; + } + + /// + /// Return true if both objects are reference-equal to each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(SegmentQueryInfo left, SegmentQueryInfo right) + { + if (ReferenceEquals(left, null)) + { + return ReferenceEquals(right, null); + } + + return left.Equals(right); + } + + /// + /// Return true if both objects are not reference-equal to each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(SegmentQueryInfo a, SegmentQueryInfo b) + { + return !(a == b); + } + + /// + /// Create a SegmentQuery from a native struct cpSegmentQueryInfo. + /// + internal static SegmentQueryInfo FromQueryInfo(cpSegmentQueryInfo queryInfo) + { + Shape shape; + + if (queryInfo.shape == IntPtr.Zero) + { + shape = null; + } + else + { + shape = Shape.FromHandle(queryInfo.shape); + } + + return new SegmentQueryInfo( + shape, + queryInfo.point, + queryInfo.normal, + queryInfo.alpha); + } + + /// + /// Return true if the fields in both objects are equivalent and the + /// field is within of the other's. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(SegmentQueryInfo other) + { + if (ReferenceEquals(other, null) || + shape?.Handle != other.shape?.Handle || + point != other.point || + normal != other.normal) + { + return false; + } + + return Math.Abs(alpha - other.alpha) < float.Epsilon; + } + + /// + /// Get the hash code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + var hashCode = -1275187100; + hashCode = hashCode * -1521134295 + shape.GetHashCode(); + hashCode = hashCode * -1521134295 + point.GetHashCode(); + hashCode = hashCode * -1521134295 + normal.GetHashCode(); + hashCode = hashCode * -1521134295 + alpha.GetHashCode(); + return hashCode; + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ShapeFilter.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ShapeFilter.cs new file mode 100755 index 00000000000..45cb76b7230 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ShapeFilter.cs @@ -0,0 +1,117 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Fast collision filtering type that is used to determine if two objects collide before calling collision or query callbacks. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] + public struct ShapeFilter + { + private static readonly UIntPtr no_group = (UIntPtr)0; + private static readonly uint all_categories = (~(uint)0); + + private static readonly ShapeFilter filter_all = new ShapeFilter(no_group, all_categories, all_categories); + private static readonly ShapeFilter filter_none = new ShapeFilter(no_group, ~all_categories, ~all_categories); + + private UIntPtr group; + private uint categories; + private uint mask; + + /// + /// Group value + /// Two objects with the same non-zero group value do not collide. + /// This is generally used to group objects in a composite object together to disable self collisions. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public UIntPtr Group + { + get => group; + set => group = value; + } + + /// + /// Categories value + /// A bitmask of user definable categories that this object belongs to. + /// The category/mask combinations of both objects in a collision must agree for a collision to occur. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public uint Categories + { + get => categories; + set => categories = value; + } + + /// + /// Mask value + /// A bitmask of user definable category types that this object object collides with. + /// The category/mask combinations of both objects in a collision must agree for a collision to occur. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public uint Mask + { + get => mask; + set => mask = value; + } + + /// + /// Create a shape filter. + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ShapeFilter(UIntPtr group, uint categories, uint mask) + { + this.group = group; + this.categories = categories; + this.mask = mask; + } + + /// + /// Value for signifying that a shape is in no group. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static UIntPtr NO_GROUP => no_group; + + /// + /// Value for signifying that a shape is in every layer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static uint ALL_CATEGORIES => all_categories; + + /// + /// Collision filter value for a shape that will collide with anything except FILTER_NONE. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static ShapeFilter FILTER_ALL => filter_all; + + /// + /// Collision filter value for a shape that does not collide with anything. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static ShapeFilter FILTER_NONE => filter_none; + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Box.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Box.cs new file mode 100644 index 00000000000..1ffd9a10ee8 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Box.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// A retangular shape shape + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class Box : Shape + { + /// + /// Create and initialize a box polygon shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Box(Body body, double width, double height, double radius) + : base(NativeMethods.cpBoxShapeNew(body.Handle, width, height, radius)) + { + + } + + /// + /// Create and initialize an offset box polygon shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Box(Body body, BoundingBox box, double radius) + : base(NativeMethods.cpBoxShapeNew2(body.Handle, box, radius)) + { + + } + + /// + /// Calculate the moment of inertia for a solid box. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double MomentForBox(double mass, double width, double height) + { + return NativeMethods.cpMomentForBox(mass, width, height); + } + + /// + /// Calculate the moment of inertia for a solid box. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double MomentForBox(double mass, BoundingBox boundingBox) + { + return NativeMethods.cpMomentForBox2(mass, boundingBox); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Circle.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Circle.cs new file mode 100644 index 00000000000..252cf6718e2 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Circle.cs @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// A circle shape defined by a radius + /// This is the fastest and simplest collision shape + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class Circle : Shape + { + /// + /// Create and initialize a circle polygon shape. + /// + /// The body to attach the circle to. + /// The radius of the circle. + [EditorBrowsable(EditorBrowsableState.Never)] + public Circle(Body body, double radius) + : this(body, radius, Vect.Zero) + { + } + + /// + /// Create and initialize an offset circle polygon shape. + /// + /// The body to attach the circle to. + /// The radius of the circle. + /// + /// The offset from the body's center of gravity in coordinates local to the body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Circle(Body body, double radius, Vect offset) + : base(NativeMethods.cpCircleShapeNew(body.Handle, radius, offset)) + { + } + + /// + /// Get the offset of the circle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Offset => NativeMethods.cpCircleShapeGetOffset(Handle); + + /// + /// Get the radius of the circle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Radius => NativeMethods.cpCircleShapeGetRadius(Handle); + + /// + /// Get the calculated area of the circle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public new double Area => AreaForCircle(0.0, Radius); + + /// + /// Calculate the moment of the circle for the given mass. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double MomentForMass(double mass) + { + return MomentForCircle(mass, Radius, Offset); + } + + /// + /// Calculate the moment of inertia for the circle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double MomentForCircle(double mass, double innerRadius, double radius, Vect offset) + { + return NativeMethods.cpMomentForCircle(mass, innerRadius, radius, offset); + } + + /// + /// Calculate the moment of inertia for the circle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double MomentForCircle(double mass, double radius, Vect offset) + { + return NativeMethods.cpMomentForCircle(mass, 0.0, radius, offset); + } + + /// + /// Calculate the area of a circle or donut. + /// + /// + /// The radius of the 'donut hole', which defines the area missing. + /// + /// + /// The outer radius of the donut. This should be greater than the + /// . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double AreaForCircle(double innerRadius, double radius) + { + return NativeMethods.cpAreaForCircle(innerRadius, radius); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Polygon.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Polygon.cs new file mode 100644 index 00000000000..986f70f9705 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Polygon.cs @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// A polygon shape composed of connected vertices. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class Polygon : Shape + { + /// + /// A convex polygon shape. It's the slowest, but most flexible collision shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Polygon(Body body, IReadOnlyList verts, Transform transform, double radius) + : base(CreatePolygonShape(body, verts, transform, radius)) + { + } + + /// + /// Allocate and initialize a polygon shape with rounded corners. + /// The vertexes must be convex with a counter-clockwise winding. + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Polygon(Body body, Vect[] verts, double radius) + : base(CreatePolygonShape(body, verts, radius)) + { + + } + + private static IntPtr CreatePolygonShape(Body body, IReadOnlyList verts, Transform transform, double radius) + { + Debug.Assert(verts.Count > 2); + + IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(verts); + + IntPtr handle = NativeMethods.cpPolyShapeNew(body.Handle, verts.Count, ptrVectors, transform, radius); + + NativeInterop.FreeStructure(ptrVectors); + + return handle; + } + + private static IntPtr CreatePolygonShape(Body body, Vect[] verts, double radius) + { + Debug.Assert(verts.Length > 2); + + IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(verts); + + IntPtr handle = NativeMethods.cpPolyShapeNewRaw(body.Handle, verts.Length, ptrVectors, radius); + + NativeInterop.FreeStructure(ptrVectors); + + return handle; + } + + /// + /// Get the number of vertices in a polygon shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int Count => NativeMethods.cpPolyShapeGetCount(Handle); + + /// + /// Get the th vertex of a polygon shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect GetVertex(int i) + { + return NativeMethods.cpPolyShapeGetVert(Handle, i); + } + + /// + /// Get the vertices of the polygon. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Vertices + { + get + { + int count = Count; + if (count == 0) + return Array.Empty(); + + Vect[] vertices = new Vect[count]; + + for (int i = 0; i < count; i++) + { + vertices[i] = GetVertex(i); + } + + return vertices; + } + } + + /// + /// Get the radius of the polygon. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Radius => NativeMethods.cpPolyShapeGetRadius(Handle); + + /// + /// Get and calculate the signed area of this polygon. Vertices specified such that they connect in + /// a clockwise fashion (called winding) give a positive area measurement. This is probably + /// backwards to what you might expect. + /// + + /// + /// Get and calculate the signed area of the polygon. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public new double Area => AreaForPoly(Vertices, Radius); + + /// + /// Get and calculate the centroid of the polygon. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Centroid => CentroidForPoly(Vertices); + + /// + /// Calculate the moment of inertia for a solid polygon shape assuming its center of gravity + /// is at its centroid. The offset is added to each vertex. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double MomentForPolygon(double mass, IReadOnlyList vertices, Vect offset, double radius) + { + IntPtr verticesPtr = NativeInterop.StructureArrayToPtr(vertices); + double moment = NativeMethods.cpMomentForPoly(mass, vertices.Count, verticesPtr, offset, radius); + + NativeInterop.FreeStructure(verticesPtr); + + return moment; + } + + /// + /// Calculate the signed area of this polygon. Vertices specified such that they connect in + /// a clockwise fashion (called winding) give a positive area measurement. This is probably + /// backwards to what you might expect. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double AreaForPoly(IReadOnlyList vertices, double radius) + { + IntPtr verticesPtr = NativeInterop.StructureArrayToPtr(vertices); + + double area = NativeMethods.cpAreaForPoly(vertices.Count, verticesPtr, radius); + + NativeInterop.FreeStructure(verticesPtr); + + return area; + } + + /// + /// Calculate the natural centroid of a polygon. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Vect CentroidForPoly(IReadOnlyList vertices) + { + IntPtr verticesPtr = NativeInterop.StructureArrayToPtr(vertices); + + Vect centroid = NativeMethods.cpCentroidForPoly(vertices.Count, verticesPtr); + + NativeInterop.FreeStructure(verticesPtr); + + return centroid; + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Segment.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Segment.cs new file mode 100644 index 00000000000..66e8a4b24fe --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Segment.cs @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// A line segment shape between two points, which is mainly useful when it behaves statically, + /// though it can be beveled to give it thickness. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class Segment : Shape + { + /// + /// Create a line segment. + /// + /// The body to attach the segment to. + /// The first endpoint of the segment. + /// The second endpoint of the segment. + /// The thickness of the segment. + [EditorBrowsable(EditorBrowsableState.Never)] + public Segment(Body body, Vect a, Vect b, double radius) + : base(NativeMethods.cpSegmentShapeNew(body.Handle, a, b, radius)) + { + } + + /// + /// Let Chipmunk know about the geometry of adjacent segments to avoid colliding with endcaps. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetNeighbors(Vect prev, Vect next) + { + NativeMethods.cpSegmentShapeSetNeighbors(Handle, prev, next); + } + + /// + /// Get the first endpoint of the segment shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect A => NativeMethods.cpSegmentShapeGetA(Handle); + + /// + /// Get the second endpoint of the segment shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect B => NativeMethods.cpSegmentShapeGetB(Handle); + + /// + /// Get the normal of the segment shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Normal => NativeMethods.cpSegmentShapeGetNormal(Handle); + + /// + /// Get the segment radius. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Radius => NativeMethods.cpSegmentShapeGetRadius(Handle); + + /// + /// Calculate the area of the segment, assuming a thickness has been provided. The area is + /// calculated assuming the endpoints would be rounded, like a capsule. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public new double Area => AreaForSegment(A, B, Radius); + + /// + /// Calculate the moment of inertia of the segment. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double MomentForMass(double mass) + { + return MomentForSegment(mass, A, B, Radius); + } + + /// + /// Calculate the moment of inertia for the line segment. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double MomentForSegment(double mass, Vect a, Vect b, double radius) + { + return NativeMethods.cpMomentForSegment(mass, a, b, radius); + } + + /// + /// Calculate the area of a segment, assuming a thickness has been provided. The area is + /// calculated assuming the endpoints would be rounded, like a capsule. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static double AreaForSegment(Vect a, Vect b, double radius) + { + return NativeMethods.cpAreaForSegment(a, b, radius); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Shape.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Shape.cs new file mode 100644 index 00000000000..19259a0dea3 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Shapes/Shape.cs @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.InteropServices; +using cpBody = System.IntPtr; +using cpDataPointer = System.IntPtr; +using cpShape = System.IntPtr; +using cpSpace = System.IntPtr; + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Abstract Chipmunk Shape + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public abstract class Shape : IDisposable + { +#pragma warning disable IDE0032 + private readonly cpShape shape; +#pragma warning restore IDE0032 + + /// + /// Create a Shape with the given . + /// + /// The native shape handle. + internal protected Shape(cpShape shapeHandle) + { + shape = shapeHandle; + RegisterUserData(); + } + + /// + /// The native handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public cpShape Handle => shape; + + /// + /// Register managed object in the native user data. + /// + private void RegisterUserData() + { + cpDataPointer pointer = NativeInterop.RegisterHandle(this); + NativeMethods.cpShapeSetUserData(shape, pointer); + } + + void ReleaseUserData() + { + cpDataPointer pointer = NativeMethods.cpShapeGetUserData(shape); + NativeInterop.ReleaseHandle(pointer); + } + + /// + /// Get a managed Shape from a native handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Shape FromHandle(cpShape shape) + { + cpDataPointer handle = NativeMethods.cpShapeGetUserData(shape); + + return NativeInterop.FromIntPtr(handle); + } + + /// + /// Dispose the shape. + /// + protected virtual void Dispose(bool dispose) + { + if (!dispose) + { + Debug.WriteLine("Disposing shape {0} on finalizer... (consider Dispose explicitly)", shape); + } + + Free(); + } + + /// + /// Destroy and free the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Free() + { + ReleaseUserData(); + NativeMethods.cpShapeFree(shape); + } + + /// + /// Destroy and free the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + // Shape properties + + /// + /// Arbitrary user data. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object Data { get; set; } + + /// + /// Gets the space that this shape is registered within. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Space Space + { + get + { + cpSpace space = NativeMethods.cpShapeGetSpace(shape); + return Space.FromHandleSafe(space); + } + } + + /// + /// The body that this shape is associated with. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body Body + { + get + { + cpBody body = NativeMethods.cpShapeGetBody(shape); + return Body.FromHandleSafe(body); + } + set + { + Debug.Assert(value != null && Space == null, + "Body can't be null and you can only change body if the shape wasn't added to space"); + + NativeMethods.cpShapeSetBody(shape, value.Handle); + } + } + + /// + /// Mass of the shape to have Chipmunk calculate mass properties for you. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Mass + { + get => NativeMethods.cpShapeGetMass(shape); + set => NativeMethods.cpShapeSetMass(shape, value); + } + + /// + /// Density of the shape if you are having Chipmunk calculate mass properties for you. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Density + { + get => NativeMethods.cpShapeGetDensity(shape); + set => NativeMethods.cpShapeSetDensity(shape, value); + } + + /// + /// Get the calculated moment of inertia for the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Moment => NativeMethods.cpShapeGetMoment(shape); + + /// + /// Get the calculated area of the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Area => NativeMethods.cpShapeGetArea(shape); + + /// + /// Get the center of gravity of the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect CenterOfGravity => NativeMethods.cpShapeGetCenterOfGravity(shape); + + /// + /// Get the bounding box that contains the shape, given it's current position and angle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BoundingBox BoundingBox => NativeMethods.cpShapeGetBB(shape); + + /// + /// Whether the shape is a sensor. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Sensor + { + get => NativeMethods.cpShapeGetSensor(shape) != 0; + set => NativeMethods.cpShapeSetSensor(shape, value ? (byte)1 : (byte)0); + } + + /// + /// The elasticity of the shape. A value of 0.0 is perfectly inelastic (no bounce). A + /// value of 1.0 is perfectly elastic. Due to simulation inaccuracy, values of 1.0 or + /// greater are not recommended. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Elasticity + { + get => NativeMethods.cpShapeGetElasticity(shape); + set => NativeMethods.cpShapeSetElasticity(shape, value); + } + + /// + /// The friction coefficient, following the Coulomb friction model. A value of 0.0 is + /// frictionless. https://en.wikipedia.org/wiki/Friction#Coefficient_of_friction + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Friction + { + get => NativeMethods.cpShapeGetFriction(shape); + set => NativeMethods.cpShapeSetFriction(shape, value); + } + + /// + /// The surface velocity of the object. Useful for creating conveyor belts or players that + /// move around. This value is only used when calculating friction, not resolving the + /// collision. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect SurfaceVelocity + { + get => NativeMethods.cpShapeGetSurfaceVelocity(shape); + set => NativeMethods.cpShapeSetSurfaceVelocity(shape, value); + } + + /// + /// An arbitrary value representing the collision type of this shape. Only shapes with like + /// collision types will collide. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int CollisionType + { + get => (int)(uint)NativeMethods.cpShapeGetCollisionType(shape); + set => NativeMethods.cpShapeSetCollisionType(shape, (UIntPtr)(uint)value); + } + + /// + /// An arbitrary value representing the collision type of this shape. Only shapes with like + /// collision types will collide. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ShapeFilter Filter + { + get => (ShapeFilter)NativeMethods.cpShapeGetFilter(shape); + set => NativeMethods.cpShapeSetFilter(shape, (ShapeFilter)value); + } + + /// + /// Update, cache and return the bounding box of a shape based on the body it's attached to. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BoundingBox CacheBB() + { + return NativeMethods.cpShapeCacheBB(shape); + } + + /// + /// Update, cache and return the bounding box of a shape with an explicit transformation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BoundingBox Update(Transform transform) + { + return NativeMethods.cpShapeUpdate(shape, transform); + } + + /// + /// Finds the point on the surface of the shape which is closest to the given point. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PointQueryInfo PointQuery(Vect point) + { + var output = new cpPointQueryInfo(); + NativeMethods.cpShapePointQuery(shape, point, ref output); + + return PointQueryInfo.FromQueryInfo(output); + } + + /// + /// Perform a segment query against a shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public SegmentQueryInfo SegmentQuery(Vect a, Vect b, double radius) + { + var queryInfo = new cpSegmentQueryInfo(); + NativeMethods.cpShapeSegmentQuery(shape, a, b, radius, ref queryInfo); + + return SegmentQueryInfo.FromQueryInfo(queryInfo); + } + + /// + /// Get the contact information between two shapes. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ContactPointSet Collide(Shape other) + { + Debug.Assert(Marshal.SizeOf(typeof(cpContactPointSet)) == 104, + "check Chipmunk sizeof(cpContactPointSet)"); + + cpContactPointSet contactPointSet = NativeMethods.cpShapesCollide(shape, other.Handle); + + return ContactPointSet.FromContactPointSet(contactPointSet); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs new file mode 100755 index 00000000000..df8c661356b --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs @@ -0,0 +1,851 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.InteropServices; +using cpBody = System.IntPtr; +using cpCollisionHandlerPointer = System.IntPtr; +using cpCollisionType = System.UIntPtr; +using cpConstraint = System.IntPtr; +using cpDataPointer = System.IntPtr; +using cpShape = System.IntPtr; +using cpSpace = System.IntPtr; +using voidptr_t = System.IntPtr; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Spaces in Chipmunk are the basic unit of simulation. You add rigid bodies, shapes, and + /// constraints to the space and then step them all forward through time together. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class Space : IDisposable + { +#pragma warning disable IDE0032 + private readonly cpSpace space; +#pragma warning restore IDE0032 + + /// + /// Native handle cpSpace. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public cpSpace Handle => space; + + /// + /// Create a new Space object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Space() + { + space = NativeMethods.cpSpaceNew(); + RegisterUserData(); + } + + /// + /// Create a space from a native Handle (used by derived classes). + /// + /// + protected internal Space(cpSpace handle) + { + space = handle; + RegisterUserData(); + } + + /// + /// Destroys and frees. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Free() + { + ReleaseUserData(); + FreeSpace(space); + } + + /// + /// Destroy and free space. + /// + /// + protected virtual void FreeSpace(cpSpace handle) + { + NativeMethods.cpSpaceFree(handle); + } + + /// + /// Destroy and free space. + /// + protected virtual void Dispose(bool disposing) + { + Free(); + } + /// + /// Disposes the Space object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + void RegisterUserData() + { + cpDataPointer pointer = NativeInterop.RegisterHandle(this); + NativeMethods.cpSpaceSetUserData(space, pointer); + } + + void ReleaseUserData() + { + cpDataPointer pointer = NativeMethods.cpSpaceGetUserData(space); + NativeInterop.ReleaseHandle(pointer); + } + + /// + /// Get a Space object from native cpSpace handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Space FromHandle(cpSpace space) + { + cpDataPointer handle = NativeMethods.cpSpaceGetUserData(space); + return NativeInterop.FromIntPtr(handle); + } + + /// + /// Get a Space object from native cpSpace handle, but return null if the handle is 0. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Space FromHandleSafe(cpSpace space) + { + if (space == IntPtr.Zero) + { + return null; + } + + return FromHandle(space); + } + + // Properties + + /// + /// Arbitrary user data. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object Data { get; set; } + + /// + /// Number of iterations to use in the impulse solver to solve contacts and other + /// constraints. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int Iterations + { + get => NativeMethods.cpSpaceGetIterations(space); + set => NativeMethods.cpSpaceSetIterations(space, value); + } + + /// + /// Gravity to pass to rigid bodies when integrating velocity. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Gravity + { + get => NativeMethods.cpSpaceGetGravity(space); + set => NativeMethods.cpSpaceSetGravity(space, value); + } + + /// + /// Damping rate expressed as the fraction of velocity that bodies retain each second. A + /// value of 0.9 would mean that each body's velocity will drop 10% per second. The default + /// value is 1.0, meaning no damping is applied. Note: This damping value is different than + /// those of and . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Damping + { + get => NativeMethods.cpSpaceGetDamping(space); + set => NativeMethods.cpSpaceSetDamping(space, value); + } + + /// + /// Speed threshold for a body to be considered idle. The default value of 0 means to let + /// the space guess a good threshold based on gravity. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double IdleSpeedThreshold + { + get => NativeMethods.cpSpaceGetIdleSpeedThreshold(space); + set => NativeMethods.cpSpaceSetIdleSpeedThreshold(space, value); + } + + /// + /// Time a group of bodies must remain idle in order to fall asleep. Enabling sleeping also + /// implicitly enables the the contact graph. The default value of infinity disables the + /// sleeping algorithm. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double SleepTimeThreshold + { + get => NativeMethods.cpSpaceGetSleepTimeThreshold(space); + set => NativeMethods.cpSpaceSetSleepTimeThreshold(space, value); + } + + /// + /// Amount of encouraged penetration between colliding shapes. This is used to reduce + /// oscillating contacts and keep the collision cache warm. Defaults to 0.1. If you have + /// poor simulation quality, increase this number as much as possible without allowing + /// visible amounts of overlap. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double CollisionSlop + { + get => NativeMethods.cpSpaceGetCollisionSlop(space); + set => NativeMethods.cpSpaceSetCollisionSlop(space, value); + } + + /// + /// Determines how fast overlapping shapes are pushed apart. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double CollisionBias + { + get => NativeMethods.cpSpaceGetCollisionBias(space); + set => NativeMethods.cpSpaceSetCollisionBias(space, value); + } + + /// + /// Number of frames that contact information should persist. Defaults to 3. There is + /// probably never a reason to change this value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int CollisionPersistence + { + get => (int)NativeMethods.cpSpaceGetCollisionPersistence(space); + set => NativeMethods.cpSpaceSetCollisionPersistence(space, (uint)value); + } + + /// + /// The Space provided static body for a given . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body StaticBody + { + get + { + cpBody bodyHandle = NativeMethods.cpSpaceGetStaticBody(space); + cpDataPointer gcHandle = NativeMethods.cpBodyGetUserData(bodyHandle); + + if (gcHandle != IntPtr.Zero) + { + return NativeInterop.FromIntPtr(gcHandle); + } + + return new Body(bodyHandle); + } + } + + /// + /// Returns the current (or most recent) time step used with the given space. + /// Useful from callbacks if your time step is not a compile-time global. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double CurrentTimeStep => NativeMethods.cpSpaceGetCurrentTimeStep(space); + + /// + /// Returns true from inside a callback when objects cannot be added/removed. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsLocked => NativeMethods.cpSpaceIsLocked(space) != 0; + + + // Collision Handlers + + /// + /// Create or return the existing collision handler that is called for all collisions that are + /// not handled by a more specific collision handler. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CollisionHandler GetOrCreateDefaultCollisionHandler() + { + cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddDefaultCollisionHandler(space); + return CollisionHandler.GetOrCreate(collisionHandle); + } + + + /// + /// Create or return the existing collision handler for the specified pair of collision + /// types. If wildcard handlers are used with either of the collision types, it's the + /// responsibility of the custom handler to invoke the wildcard handlers. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CollisionHandler GetOrCreateCollisionHandler(int typeA, int typeB) + { + uint utypeA = unchecked((uint)typeA); + uint utypeB = unchecked((uint)typeB); + + cpCollisionType collisionTypeA = new cpCollisionType(utypeA); + cpCollisionType collisionTypeB = new cpCollisionType(utypeB); + + cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddCollisionHandler(space, collisionTypeA, collisionTypeB); + return CollisionHandler.GetOrCreate(collisionHandle); + } + + + /// + /// Create or return the existing wildcard collision handler for the specified type. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CollisionHandler GetOrCreateWildcardHandler(int type) + { + cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddWildcardHandler(space, (cpCollisionType)type); + return CollisionHandler.GetOrCreate(collisionHandle); + } + + /// + /// Add a collision shape to the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddShape(Shape shape) + { + NativeMethods.cpSpaceAddShape(space, shape.Handle); + } + + /// + /// Add a rigid body to the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddBody(Body body) + { + NativeMethods.cpSpaceAddBody(space, body.Handle); + } + + /// + /// Add a constraint to the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddConstraint(Constraint constraint) + { + NativeMethods.cpSpaceAddConstraint(space, constraint.Handle); + } + + /// + /// Remove a collision shape from the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveShape(Shape shape) + { + NativeMethods.cpSpaceRemoveShape(space, shape.Handle); + } + + /// + /// Remove a rigid body from the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveBody(Body body) + { + NativeMethods.cpSpaceRemoveBody(space, body.Handle); + } + + /// + /// Remove a constraint from the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveConstraint(Constraint constraint) + { + NativeMethods.cpSpaceRemoveConstraint(space, constraint.Handle); + } + + /// + /// Test if a collision shape has been added to the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Contains(Shape shape) + { + return NativeMethods.cpSpaceContainsShape(space, shape.Handle) != 0; + } + + /// + /// Test if a rigid body has been added to the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Contains(Body body) + { + return NativeMethods.cpSpaceContainsBody(space, body.Handle) != 0; + } + + /// + /// Test if a constraint has been added to the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Contains(Constraint constraint) + { + return NativeMethods.cpSpaceContainsConstraint(space, constraint.Handle) != 0; + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(PostStepFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void PostStepCallBack(cpSpace handleSpace, voidptr_t handleKey, voidptr_t handleData) + { + var space = FromHandle(handleSpace); + var key = NativeInterop.FromIntPtr(handleKey); + var data = NativeInterop.FromIntPtr(handleData); + + Action callback = data.Callback; + + callback(space, key, data.Data); + + NativeInterop.ReleaseHandle(handleKey); + NativeInterop.ReleaseHandle(handleData); + } + + private static PostStepFunction postStepCallBack = PostStepCallBack; + + /// + /// Schedule a post-step callback to be called when finishes. You can + /// only register one callback per unique value for . Returns true + /// only if has never been scheduled before. It's possible to pass + /// null for if you only want to mark as + /// being used. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool AddPostStepCallback(Action callback, object key, object data) + { + var info = new PostStepCallbackInfo(callback, data); + + IntPtr dataHandle = NativeInterop.RegisterHandle(info); + IntPtr keyHandle = NativeInterop.RegisterHandle(key); + + return NativeMethods.cpSpaceAddPostStepCallback(space, postStepCallBack.ToFunctionPointer(), keyHandle, dataHandle) != 0; + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpacePointQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachPointQuery(cpShape shapeHandle, Vect point, double distance, Vect gradient, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + var pointQuery = new PointQueryInfo(shape, point, distance, gradient); + + list.Add(pointQuery); + } + + private static SpacePointQueryFunction eachPointQuery = EachPointQuery; + + /// + /// Get the shapes within a radius of the point location that are part of this space. The + /// filter is applied to the query and follows the same rules as the collision detection. + /// If a maxDistance of 0.0 is used, the point must lie inside a shape. Negative + /// is also allowed meaning that the point must be a under a + /// certain depth within a shape to be considered a match. + /// + /// Where to check for shapes in the space. + /// Match only within this distance. + /// Only pick shapes matching the filter. + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList PointQuery(Vect point, double maxDistance, ShapeFilter filter) + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpacePointQuery(space, point, maxDistance, filter, eachPointQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + + /// + /// Get the nearest shape within a radius of a point that is part of this space. The filter + /// is applied to the query and follows the same rules as the collision detection. If a + /// of 0.0 is used, the point must lie inside a shape. + /// Negative is also allowed, meaning that the point must be + /// under a certain depth within a shape to be considered a match. + /// + /// Where to check for collision in the space. + /// Match only within this distance. + /// Only pick shapes matching the filter. + [EditorBrowsable(EditorBrowsableState.Never)] + public PointQueryInfo PointQueryNearest(Vect point, double maxDistance, ShapeFilter filter) + { + var queryInfo = new cpPointQueryInfo(); + + cpShape shape = NativeMethods.cpSpacePointQueryNearest(space, point, maxDistance, filter, ref queryInfo); + if (shape == IntPtr.Zero) + return null; + + return PointQueryInfo.FromQueryInfo(queryInfo); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceSegmentQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachSegmentQuery(cpShape shapeHandle, Vect point, Vect normal, double alpha, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + var pointQuery = new SegmentQueryInfo(shape, point, normal, alpha); + + list.Add(pointQuery); + } + + private static SpaceSegmentQueryFunction eachSegmentQuery = EachSegmentQuery; + + /// + /// Get the shapes within a capsule-shaped radius of a line segment that is part of this + /// space. The filter is applied to the query and follows the same rules as the collision + /// detection. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList SegmentQuery(Vect start, Vect end, double radius, ShapeFilter filter) + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceSegmentQuery(space, start, end, radius, filter, eachSegmentQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + + /// + /// Get the first shape within a capsule-shaped radius of a line segment that is part of + /// this space. The filter is applied to the query and follows the same rules as the + /// collision detection. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public SegmentQueryInfo SegmentQueryFirst(Vect start, Vect end, double radius, ShapeFilter filter) + { + var queryInfo = new cpSegmentQueryInfo(); + + cpShape shape = NativeMethods.cpSpaceSegmentQueryFirst(space, start, end, radius, filter, ref queryInfo); + if (shape == IntPtr.Zero) + return null; + + return SegmentQueryInfo.FromQueryInfo(queryInfo); + } + + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceBBQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachBBQuery(cpShape shapeHandle, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + + list.Add(shape); + } + + private static SpaceBBQueryFunction eachBBQuery = EachBBQuery; + + + /// + /// Get all shapes within the axis-aligned bounding box that are part of this shape. The + /// filter is applied to the query and follows the same rules as the collision detection. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList BoundBoxQuery(BoundingBox bb, ShapeFilter filter) + { + var list = new List(); + + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceBBQuery(space, bb, filter, eachBBQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + + /// + /// Get all bodies in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Bodies + { + get + { + int count = NativeMethods.cpSpaceGetBodyCount(space); + + if (count == 0) + return Array.Empty(); + + IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + NativeMethods.cpSpaceGetBodiesUserDataArray(space, ptrBodies); + + IntPtr[] userDataArray = new IntPtr[count]; + + Marshal.Copy(ptrBodies, userDataArray, 0, count); + + Marshal.FreeHGlobal(ptrBodies); + + Body[] bodies = new Body[count]; + + for (int i = 0; i < count; i++) + { + Body b = NativeInterop.FromIntPtr(userDataArray[i]); + bodies[i] = b; + } + + return bodies; + } + } + + /// + /// Get dynamic bodies in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList DynamicBodies + { + get + { + int count = NativeMethods.cpSpaceGetDynamicBodyCount(space); + + if (count == 0) + return Array.Empty(); + + IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + NativeMethods.cpSpaceGetDynamicBodiesUserDataArray(space, ptrBodies); + + IntPtr[] userDataArray = new IntPtr[count]; + + Marshal.Copy(ptrBodies, userDataArray, 0, count); + + Marshal.FreeHGlobal(ptrBodies); + + Body[] bodies = new Body[count]; + + for (int i = 0; i < count; i++) + { + Body b = NativeInterop.FromIntPtr(userDataArray[i]); + bodies[i] = b; + } + + return bodies; + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceObjectIteratorFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachShape(cpShape shapeHandle, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + + list.Add(shape); + } + + private static SpaceObjectIteratorFunction eachShape = EachShape; + + /// + /// Get all shapes in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Shapes + { + get + { + var list = new List(); + + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceEachShape(space, eachShape.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + + return list; + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceShapeQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void ShapeQueryCallback(cpShape shape, IntPtr pointsPointer, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var pointSet = NativeInterop.PtrToStructure(pointsPointer); + + list.Add(ContactPointSet.FromContactPointSet(pointSet)); + } + + private static SpaceShapeQueryFunction shapeQueryCallback = ShapeQueryCallback; + + /// + /// Get all shapes in the space that are overlapping the given shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList ShapeQuery(Shape shape) + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceShapeQuery(space, shape.Handle, shapeQueryCallback.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceObjectIteratorFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachConstraint(cpConstraint constraintHandle, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var constraint = Constraint.FromHandle(constraintHandle); + + list.Add(constraint); + } + + private static SpaceObjectIteratorFunction eachConstraint = EachConstraint; + + + /// + /// Get all constraints in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Constraints + { + get + { + var list = new List(); + + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceEachConstraint(space, eachConstraint.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + + return list; + } + } + + /// + /// Update the collision detection info for the static shapes in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ReindexStatic() + { + NativeMethods.cpSpaceReindexStatic(space); + } + + /// + /// Update the collision detection data for a specific shape in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ReindexShape(Shape shape) + { + NativeMethods.cpSpaceReindexShape(space, shape.Handle); + } + + /// + /// Update the collision detection data for all shapes attached to a body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ReindexShapesForBody(Body body) + { + NativeMethods.cpSpaceReindexShapesForBody(space, body.Handle); + } + + /// + /// Switch the space to use a spatial hash as its spatial index. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void UseSpatialHash(double dim, int count) + { + NativeMethods.cpSpaceUseSpatialHash(space, dim, count); + } + + /// + /// Update the space for the given time step. Using a fixed time step is highly recommended. + /// Doing so will increase the efficiency of the contact persistence, requiring an order of + /// magnitude fewer iterations to resolve the collisions in the usual case. It is not the + /// same to call step 10 times with a dt of 0.1, or 100 times with a dt of 0.01 even if the + /// end result is that the simulation moved forward 100 units. Performing multiple calls + /// with a smaller dt creates a more stable and accurate simulation. Therefore, it sometimes + /// makes sense to have a little for loop around the step call. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void Step(double dt) + { + NativeMethods.cpSpaceStep(space, dt); + } + + /// + /// Draw all objects in the space for debugging purposes. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void DebugDraw(IDebugDraw debugDraw) + { + DebugDraw(debugDraw, DebugDrawFlags.All, DebugDrawColors.Default); + } + + /// + /// Draw all objects in the space for debugging purposes using flags. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void DebugDraw(IDebugDraw debugDraw, DebugDrawFlags flags) + { + DebugDraw(debugDraw, flags, DebugDrawColors.Default); + } + + /// + /// Draw all objects in the space for debugging purposes using flags and colors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void DebugDraw(IDebugDraw debugDraw, DebugDrawFlags flags, DebugDrawColors colors) + { + var debugDrawOptions = new cpSpaceDebugDrawOptions(); + IntPtr debugDrawOptionsPointer = debugDrawOptions.AcquireDebugDrawOptions(debugDraw, flags, colors); + + NativeMethods.cpSpaceDebugDraw(space, debugDrawOptionsPointer); + + debugDrawOptions.ReleaseDebugDrawOptions(debugDrawOptionsPointer); + } + + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs new file mode 100644 index 00000000000..b5f92a3afb0 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; + +#pragma warning disable IDE1006 +#pragma warning disable IDE0032 + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Type used for 2x3 affine transforms. See wikipedia for details: + /// http://en.wikipedia.org/wiki/Affine_transformation. The properties map to the matrix in this + /// way: [[a c tx], [b d ty]]. We can't use System.Numerics.Matrix32 since it does't use + /// doubles. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] + public struct Transform : IEquatable + { + private static readonly Transform identity = new Transform(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); + + private double a; + private double b; + private double c; + private double d; + private double tx; + private double ty; + + /// + /// Create a matrix transformation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Transform(double a, double b, double c, double d, double tx, double ty) : this() + { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.tx = tx; + this.ty = ty; + } + + /// + /// Create a transpose matrix. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Transform CreateTranspose(double a, double c, double tx, double b, double d, double ty) + { + return new Transform(a, b, c, d, tx, ty); + } + + /// + /// Create a translation matrix. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Transform CreateTranslation(Vect translate) + { + return CreateTranspose(1.0, 0.0, translate.X, 0.0, 1.0, translate.Y); + } + + /// + /// Create an identity matrix. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Transform Identity => identity; + + /// + /// A + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double A { get => a; set => a = value; } + + /// + /// B + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double B { get => b; set => b = value; } + + /// + /// C + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double C { get => c; set => c = value; } + + /// + /// D + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double D { get => d; set => d = value; } + + /// + /// Tx + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Tx { get => tx; set => tx = value; } + + /// + /// Ty + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Ty { get => ty; set => ty = value; } + + /// + /// Return true if all matrix values are within of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + Transform? transform = obj as Transform?; + + if (transform == null) + return false; + + return Equals(transform.Value); + } + + /// + /// Return true if all matrix values are within of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(Transform other) + { + return Math.Abs(a - other.a) < double.Epsilon && + Math.Abs(b - other.b) < double.Epsilon && + Math.Abs(c - other.c) < double.Epsilon && + Math.Abs(d - other.d) < double.Epsilon && + Math.Abs(tx - other.tx) < double.Epsilon && + Math.Abs(ty - other.ty) < double.Epsilon; + } + + /// + /// Get the hash code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { + var hashCode = -884009331; +#pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()' + hashCode = hashCode * -1521134295 + a.GetHashCode(); + hashCode = hashCode * -1521134295 + b.GetHashCode(); + hashCode = hashCode * -1521134295 + c.GetHashCode(); + hashCode = hashCode * -1521134295 + d.GetHashCode(); + hashCode = hashCode * -1521134295 + tx.GetHashCode(); + hashCode = hashCode * -1521134295 + ty.GetHashCode(); +#pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()' + return hashCode; + } + + /// + /// Return a string formatted like "(a,b|c,d|tx,ty)". + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() + { + return $"({a},{b}|{c},{d}|{tx},{ty})"; + } + + /// + /// Return true if all matrix values are within of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(Transform transform1, Transform transform2) + { + return transform1.Equals(transform2); + } + + /// + /// Return true if all matrix values are not within of each + /// other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(Transform transform1, Transform transform2) + { + return !(transform1 == transform2); + } + } +} + +#pragma warning restore IDE1006 +#pragma warning restore IDE0032 diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/CircleExtensions.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/CircleExtensions.cs new file mode 100644 index 00000000000..ec8f251b2da --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/CircleExtensions.cs @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk.Unsafe +{ + /// + /// Unsafe extension methods for the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static class CircleExtensions + { + /// + /// Change the radius of the circle shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetRadius(this Circle circle, double radius) + { + NativeMethods.cpCircleShapeSetRadius(circle.Handle, radius); + } + + /// + /// Change the offset of the circle shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetOffset(this Circle circle, Vect offset) + { + NativeMethods.cpCircleShapeSetOffset(circle.Handle, offset); + } + + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/PolygonExtensions.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/PolygonExtensions.cs new file mode 100644 index 00000000000..61d737da008 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/PolygonExtensions.cs @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk.Unsafe +{ + /// + /// Unsafe extension methods for the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static class PolygonExtensions + { + /// + /// Set the vertexes of the polygon. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetVertexes(this Polygon polygon, Vect[] vertexes, Transform transform) + { + IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(vertexes); + NativeMethods.cpPolyShapeSetVerts(polygon.Handle, vertexes.Length, ptrVectors, transform); + NativeInterop.FreeStructure(ptrVectors); + } + + /// + /// Set the vertexes of the polygon. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetVertexes(this Polygon polygon, Vect[] vertexes) + { + IntPtr ptrVectors = NativeInterop.StructureArrayToPtr(vertexes); + NativeMethods.cpPolyShapeSetVertsRaw(polygon.Handle, vertexes.Length, ptrVectors); + NativeInterop.FreeStructure(ptrVectors); + } + + /// + /// Set the radius of a poly shape + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetRadius(this Polygon polygon, double radius) + { + NativeMethods.cpPolyShapeSetRadius(polygon.Handle, radius); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/SegmentExtensions.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/SegmentExtensions.cs new file mode 100644 index 00000000000..80357261102 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Unsafe/SegmentExtensions.cs @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System.ComponentModel; + +namespace Tizen.NUI.Physics2D.Chipmunk.Unsafe +{ + /// + /// Unsafe extensions methods for the shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static class SegmentExtensions + { + /// + /// Set the endpoints of a segment shape. This mutates collision shapes. Chipmunk can't get + /// velocity information on changing shapes, so the results will be unrealistic. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetEndpoints(this Segment segment, Vect a, Vect b) + { + NativeMethods.cpSegmentShapeSetEndpoints(segment.Handle, a, b); + } + + /// + /// Set the radius of a segment shape. This mutates collision shapes. Chipmunk can't get + /// velocity information on changing shapes, so the results will be unrealistic. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetRadius(this Segment segment, double radius) + { + NativeMethods.cpSegmentShapeSetRadius(segment.Handle, radius); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Vect.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Vect.cs new file mode 100644 index 00000000000..41049dd76b7 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Vect.cs @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +#pragma warning disable IDE1006 +#pragma warning disable IDE0032 + +// Chipmunk has it own Vector class, +// We can't use System.Numerics.Vector2 since is not blitable with the native Vect from Chipmunk + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// 2D Vector struct + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] + public struct Vect : IEquatable + { + private static readonly Vect zero = new Vect(0, 0); + + private double x; + private double y; + + /// + /// X value + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double X + { + get => x; + set => x = value; + } + + /// + /// Y value + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Y + { + get => y; + set => y = value; + } + + /// + /// Create a vector. + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vect(double x, double y) + { + this.x = x; + this.y = y; + } + + /// + /// Return true if both objects are within of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) + { + Vect? vect = obj as Vect?; + + if (vect == null) + return false; + + return this == vect.Value; + } + + /// + /// Get the hash code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() + { +#pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()' + return (x.GetHashCode() << 16) ^ y.GetHashCode(); +#pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()' + } + + /// + /// Return true if both objects are within of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Equals(Vect other) + { + return this == other; + } + + /// + /// Return a string formatted like "(x,y)". + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() + { + return $"({x},{y})"; + } + + /// + /// Return true if both objects are within of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator ==(Vect a, Vect b) + { + return Math.Abs(b.x - a.x) <= double.Epsilon && + Math.Abs(b.y - a.y) <= double.Epsilon; + } + + /// + /// Return true if both objects are not within of each other. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool operator !=(Vect a, Vect b) + { + return !(a == b); + } + + /// + /// Add two vectors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect operator +(Vect a, Vect b) + { + return new Vect(a.x + b.x, a.y + b.y); + } + + /// + /// Subtract two vectors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect operator -(Vect a, Vect b) + { + return new Vect(a.x - b.x, a.y - b.y); + } + + /// + /// Negate a vector. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect operator -(Vect a) + { + return new Vect(-a.x, -a.y); + } + + /// + /// Scalar multiplication. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect operator *(Vect a, double s) + { + return new Vect(a.x * s, a.y * s); + } + + /// + /// Scalar division. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect operator /(Vect a, double s) + { + return new Vect(a.x / s, a.y / s); + } + + /// + /// Scalar multiplication. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect operator *(double s, Vect a) + { + return new Vect(a.x * s, a.y * s); + } + + /// + /// Scalar division. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect operator /(double s, Vect a) + { + return new Vect(a.x / s, a.y / s); + } + + /// + /// Vector dot product. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double Dot(Vect v2) + { + return x * v2.x + y * v2.y; + } + + /// + /// 2D vector cross product analog. The cross product of 2D vectors results in a 3D vector + /// with only a z component. This function returns the magnitude of the z value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double Cross(Vect v2) + { + return x * v2.y - y * v2.x; + } + + /// + /// Returns a perpendicular vector (-90 degree rotation). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Perpendicurlar => new Vect(-y, x); + + /// + /// Returns the vector projection of v1 onto v2. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vect Project(Vect v2) + { + return v2 * Dot(v2) / v2.Dot(v2); + } + + /// + /// Returns the unit length vector for the given angle (in radians). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vect ForAngle(double angle) + { + return new Vect(Math.Cos(angle), Math.Sin(angle)); + } + + /// + /// Returns the angular direction v is pointing in (in radians). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double ToAngle() + { + return Math.Atan2(y, x); + } + + /// + /// Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a + /// unit vector. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vect Rotate(Vect v2) + { + return new Vect(x * v2.x - y * v2.y, x * v2.y + y * v2.x); + } + + /// + /// Inverse of Rotate(). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vect Unrotate(Vect v2) + { + return new Vect(x * v2.x + y * v2.y, y * v2.x - x * v2.y); + } + + /// + /// Returns the squared length of v. Faster than when you only need to + /// compare lengths. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double LengthSquared() => Dot(this); + + /// + /// Returns the length of v. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double Length() + { + return Math.Sqrt(Dot(this)); + } + + /// + /// Linearly interpolate between this and . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vect Lerp(Vect v2, double t) + { + return this * (1.0 - t) + v2 * t; + } + + /// + /// Returns a normalized copy. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vect Normalize() + { + return this * (1.0 / (Length() + double.Epsilon)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static double Clamp(double value, double min, double max) + { + if (value < min) + { + return min; + } + if (value > max) + { + return max; + } + + return value; + } + + /// + /// Spherical linear interpolation between current position and based + /// on . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect SLerp(Vect v2, double t) + { + double dot = Normalize().Dot(v2.Normalize()); + double omega = Math.Acos(Clamp(dot, -1.0f, 1.0f)); + + if (omega < 1e-3) + { + // If the angle between two vectors is very small, lerp instead to avoid precision issues. + return Lerp(v2, t); + } + + double denom = 1.0 / Math.Sin(omega); + return (this * Math.Sin((1.0f - t) * omega) * denom) + v2 * Math.Sin(t * omega) * denom; + } + + /// + /// Spherical linear interpolation between current position towards by + /// no more than angle radians. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect SLerpConst(Vect v2, double a) + { + double dot = Normalize().Dot(v2.Normalize()); + double omega = Math.Acos(Clamp(dot, -1.0f, 1.0f)); + + return SLerp(v2, Math.Min(a, omega) / omega); + } + + /// + /// Clamp the magnitude to the given length. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Clamp(double length) + { + return Dot(this) > length * length ? Normalize() * length : this; + } + + /// + /// Linearly interpolate between the current position towards by + /// distance . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect LerpConst(Vect v2, double d) + { + return this + (v2 - this).Clamp(d); + } + + /// + /// Return the distance between this and . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [EditorBrowsable(EditorBrowsableState.Never)] + public double Distance(Vect v2) + { + return (this - v2).Length(); + } + + /// + /// Return the squared distance between current position and . Faster + /// than when you only need to compare distances. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [EditorBrowsable(EditorBrowsableState.Never)] + public double DistanceSquare(Vect v2) + { + return (this - v2).LengthSquared(); + } + + /// + /// Return true if the distance between current position and is less + /// than . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Near(Vect v2, double distance) + { + return DistanceSquare(v2) < distance * distance; + } + + /// + /// (0, 0) Vector. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static Vect Zero => zero; + } +} + +#pragma warning restore IDE1006 +#pragma warning restore IDE0032 diff --git a/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs b/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs new file mode 100644 index 00000000000..e790decb13d --- /dev/null +++ b/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2023 Samsung Electronics Co., Ltd. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Text; +using System.Linq; +using Tizen.NUI.Physics2D.Chipmunk; + +// Tests the basic functionality of the Chipmunk2D physics engine without the need of any rendering. +// It sets up a 2D physics simulation with a dynamic circle dropping to the top of two static segments +// representing the ground and bouncing back. The simulation is run for a fixed number of time steps, +// and the position of the circle body is printed at each step to verify the correctness of the physics +// simulation. + +class Physics2DSample +{ + public Physics2DSample() + { + // Create a space for physics simulation + var space = new Space(); + + // Set up gravity along the Y-axis (negative value for downward) + var gravity = new Vect(0, -100); + space.Gravity = gravity; + + // Create two static bodies (static bodies do not move) with shapes (segments) to form the ground + var groundBody1 = new Body(BodyType.Static); + var groundBody2 = new Body(BodyType.Static); + + // Add the body to the space + space.AddBody(groundBody1); + space.AddBody(groundBody2); + + var groundStart = new Vect(-1000, 0); // Start point of the ground + var groundEnd = new Vect(1000, 0); // End point of the ground + + var groundShape1 = new Segment(groundBody1, groundStart, groundEnd, 0); + var groundShape2 = new Segment(groundBody2, groundStart, groundEnd, 0); + + groundShape1.CollisionType = 0; + groundShape2.CollisionType = 1; + + groundShape1.Elasticity = 0.85f; + groundShape2.Elasticity = 0.85f; + + // Add the shapes to the space + space.AddShape(groundShape1); + space.AddShape(groundShape2); + + // Create a dynamic body with a circle shape + var radius = 20.0; + var mass = 1.0; + var moment = Circle.MomentForCircle(mass, 0, radius, Vect.Zero); + + // Set initial position for the circle + var circleBody = new Body(mass, moment); + circleBody.Position = new Vect(0, 50); + + // Add the body to the space + space.AddBody(circleBody); + + // Create a circle shape + var circleShape = new Circle(circleBody, radius, Vect.Zero); + circleShape.CollisionType = 2; + circleShape.Elasticity = 0.85f; + + // Add the circle shape to the space + space.AddShape(circleShape); + + // Detect the collision between the circle and the ground + CollisionHandler handler = space.GetOrCreateCollisionHandler(0, 2); + handler.Data = new StringBuilder(); + + handler.Begin = (arbiterHandle, spaceHandle, userData) => + { + StringBuilder builder = (StringBuilder)userData; + _ = builder.Append("Begin -> "); + + Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); + }; + + handler.PreSolve = (arbiterHandle, spaceHandle, userData) => + { + StringBuilder builder = (StringBuilder)userData; + _ = builder.Append("PreSolve -> "); + + Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); + + return true; + }; + + handler.PostSolve = (arbiterHandle, spaceHandle, userData) => + { + StringBuilder builder = (StringBuilder)userData; + _ = builder.Append("PostSolve -> "); + + Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); + }; + + handler.Separate = (arbiterHandle, spaceHandle, userData) => + { + StringBuilder builder = (StringBuilder)userData; + _ = builder.Append("Separate -> "); + + Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); + }; + + + // Simulate the physics for some time steps + var numSteps = 60; // Number of simulation steps + var timeStep = 1.0 / 60.0; // Time step for each simulation step (60 FPS) + + // Set the velocity of the circle body to make it move to the right + circleBody.Velocity = new Vect(100, 0); // Velocity of (100, 0) along the X-axis + + for (int i = 0; i < numSteps; ++i) + { + space.Step(timeStep); + + // Print the position of the circle body during simulation + var position = circleBody.Position; + Console.WriteLine("Step " + i + " - Circle Position: (" + position.X + ", " + position.Y + ")"); + } + + // Make a point query on a shape + { + circleShape.Filter = new ShapeFilter((UIntPtr)10, 1, 5); + ShapeFilter filter = circleShape.Filter; + Console.WriteLine("ShapeFilter: " + filter.Group + ", " + filter.Categories + ", " + filter.Mask); + + var body = new Body(1, 1.66); + var shape = new Box(body, 2, 2, 0); + + PointQueryInfo point = shape.PointQuery(new Vect(3, 4)); + Console.WriteLine("Shape PointQuery: Distance: " + point.Distance + ", Point: " + point.Point + ", Gradient.X: " + point.Gradient.X + ", Gradient.Y: " + point.Gradient.Y); + + shape.Dispose(); + body.Dispose(); + } + + // Make a point query on a space + { + var mySpace = new Space(); + var body = new Body(1, 1.66); + var shape = new Box(body, 100, 100, 0); + + body.Position = new Vect(0, 0); + + PointQueryInfo[] infos = mySpace.PointQuery(body.Position, 10.0, ShapeFilter.FILTER_ALL).ToArray(); + Console.WriteLine("Space PointQuery: infos.Length: " + infos.Length); + + mySpace.AddBody(body); + mySpace.AddShape(shape); + + infos = mySpace.PointQuery(body.Position, 10.0, ShapeFilter.FILTER_ALL).ToArray(); + Console.WriteLine("Space PointQuery: infos.Length: " + infos.Length); + + if (infos.Length > 0 && shape == infos[0].Shape) + { + Console.WriteLine("Space PointQuery: The shape matches"); + } + + PointQueryInfo info = space.PointQueryNearest(new Vect(0, 0), 100.0, ShapeFilter.FILTER_ALL); + + if (info == null || info.Shape == null) + { + Console.WriteLine("Space PointQueryNearest: No shape is found"); + } + else + { + Console.WriteLine("Shape PointQueryNearest: Distance: " + info.Distance + ", Point: " + info.Point + ", Gradient.X: " + info.Gradient.X + ", Gradient.Y: " + info.Gradient.Y + ", Body position: " + info.Shape.Body.Position); + } + + shape.Dispose(); + body.Dispose(); + mySpace.Dispose(); + } + + // Clean up + groundShape1.Dispose(); + groundShape2.Dispose(); + circleShape.Dispose(); + + groundBody1.Dispose(); + groundBody2.Dispose(); + circleBody.Dispose(); + + space.Dispose(); + } + + /// + /// The main entry point for the application. + /// + [STAThread] // Forces app to use one thread to access NUI + static void Main(string[] args) + { + Physics2DSample example = new Physics2DSample(); + } +} + diff --git a/test/Tizen.NUI.Physics2D.Sample/Tizen.NUI.Physics2D.Sample.csproj b/test/Tizen.NUI.Physics2D.Sample/Tizen.NUI.Physics2D.Sample.csproj new file mode 100644 index 00000000000..b3cedf09f76 --- /dev/null +++ b/test/Tizen.NUI.Physics2D.Sample/Tizen.NUI.Physics2D.Sample.csproj @@ -0,0 +1,22 @@ + + + net6.0 + Exe + Physics2DSample + + + portable + + + None + + + + + + + + + True + + diff --git a/test/Tizen.NUI.Physics2D.Sample/tizen-manifest.xml b/test/Tizen.NUI.Physics2D.Sample/tizen-manifest.xml new file mode 100644 index 00000000000..ce556b8aeb3 --- /dev/null +++ b/test/Tizen.NUI.Physics2D.Sample/tizen-manifest.xml @@ -0,0 +1,13 @@ + + + + + + NUI.png + + + + + + + From fe8dcbd088335717597cb48997fee74dc24533c2 Mon Sep 17 00:00:00 2001 From: David Steele Date: Mon, 11 Sep 2023 21:23:20 +0100 Subject: [PATCH 14/82] [NUI.Physics2D] Adding Dali/Chipmunk interop Adds Tizen.NUI.Physics2D.PhysicsAdaptor, Tizen.NUI.Physics2D.PhysicsActor and Tizen.NUI.Physics2D.ScopedAccessor classes. These wrap the DALi physics classes in dali-toolkit; which run the physics integration thread in the Update thread (using the FrameCallback natively). They offer basic APIs for attaching Views to Chipmunk.Body physics objects, so that they can be rendered. --- .../Tizen.NUI.Physics2D.csproj | 4 +- .../src/internal/interop/Interop.Actor.cs | 70 ++ .../src/internal/interop/Interop.Adaptor.cs | 120 +++ .../src/internal/interop/Interop.Libraries.cs | 30 + .../src/internal/interop/Interop.World.cs | 42 + .../src/public/chipmunk/Body.cs | 8 +- .../src/public/chipmunk/Space.cs | 20 +- .../src/public/chipmunk/SpaceRef.cs | 776 ++++++++++++++++++ .../src/public/wrapper/PhysicsActor.cs | 199 +++++ .../src/public/wrapper/PhysicsAdaptor.cs | 439 ++++++++++ .../public/wrapper/ScopedPhysicsAccessor.cs | 114 +++ .../src/internal/Common/FriendAssembly.cs | 1 + .../Physics2DSample.cs | 260 ++---- .../res/images/blocks-ball.png | Bin 0 -> 5158 bytes 14 files changed, 1902 insertions(+), 181 deletions(-) create mode 100644 src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Actor.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Adaptor.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Libraries.cs create mode 100644 src/Tizen.NUI.Physics2D/src/internal/interop/Interop.World.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsActor.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsAdaptor.cs create mode 100644 src/Tizen.NUI.Physics2D/src/public/wrapper/ScopedPhysicsAccessor.cs create mode 100644 test/Tizen.NUI.Physics2D.Sample/res/images/blocks-ball.png diff --git a/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj index ab51d112c1a..0b35f62fe7f 100755 --- a/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj +++ b/src/Tizen.NUI.Physics2D/Tizen.NUI.Physics2D.csproj @@ -11,7 +11,9 @@ - + + + diff --git a/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Actor.cs b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Actor.cs new file mode 100644 index 00000000000..163c8e46e2f --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Actor.cs @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; +using Tizen.NUI.Physics2D.Chipmunk; + +namespace Tizen.NUI.Physics2D +{ + internal static partial class Interop + { + internal static class Actor + { + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_New")] + internal static extern global::System.IntPtr PhysicsActorNew(HandleRef actor, IntPtr Body, HandleRef adaptor); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_new_PhysicsActor__SWIG_0")] + internal static extern global::System.IntPtr NewPhysicsActor(); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_new_PhysicsActor__SWIG_1")] + internal static extern global::System.IntPtr NewPhysicsActor(HandleRef rhs); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_DownCast")] + internal static extern global::System.IntPtr DownCast(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_delete_PhysicsActor")] + internal static extern void DeletePhysicsActor(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_Assign")] + internal static extern global::System.IntPtr Assign(HandleRef destination, HandleRef source); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_GetId")] + internal static extern uint GetId(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_GetBody")] + internal static extern global::System.IntPtr GetBody(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_AsyncSetPhysicsPosition")] + internal static extern void AsyncSetPhysicsPosition(HandleRef handle, HandleRef position); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_AsyncSetPhysicsRotation")] + internal static extern void AsyncSetPhysicsRotation(HandleRef handle, HandleRef rotation); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_GetPhysicsPosition")] + internal static extern global::System.IntPtr GetPhysicsPosition(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_GetPhysicsRotation")] + internal static extern global::System.IntPtr GetPhysicsRotation(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_GetActorPosition")] + internal static extern global::System.IntPtr GetActorPosition(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsActor_GetActorRotation")] + internal static extern global::System.IntPtr GetActorRotation(HandleRef handle); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Adaptor.cs b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Adaptor.cs new file mode 100644 index 00000000000..b8e1a943c3b --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Adaptor.cs @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; +using Tizen.NUI.Physics2D.Chipmunk; + +namespace Tizen.NUI.Physics2D +{ + internal static partial class Interop + { + internal static class Adaptor + { + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_New")] + internal static extern global::System.IntPtr PhysicsAdaptorNew(HandleRef matrix, HandleRef size); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_new_PhysicsAdaptor__SWIG_0")] + internal static extern global::System.IntPtr NewPhysicsAdaptor(); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_new_PhysicsAdaptor__SWIG_1")] + internal static extern global::System.IntPtr NewPhysicsAdaptor(HandleRef rhs); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_delete_PhysicsAdaptor")] + internal static extern void DeletePhysicsAdaptor(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_DownCast")] + internal static extern global::System.IntPtr DownCast(HandleRef handle); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_Assign")] + internal static extern global::System.IntPtr Assign(HandleRef destination, HandleRef source); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_SetTimestep")] + internal static extern void SetTimestep(HandleRef adaptor, float timestep); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_GetTimestep")] + internal static extern float GetTimestep(HandleRef adaptor); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_CreateDebugLayer")] + internal static extern global::System.IntPtr CreateDebugLayer(HandleRef adaptor, HandleRef window); + // Layer + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_TranslateToPhysicsSpace_1")] + internal static extern global::System.IntPtr TranslatePositionToPhysicsSpace(HandleRef adaptor, HandleRef position); + // Vector3 + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_TranslateToPhysicsSpace_2")] + internal static extern global::System.IntPtr TranslateRotationToPhysicsSpace(HandleRef adaptor, HandleRef rotation); + // Quaternion + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_TranslateFromPhysicsSpace_1")] + internal static extern global::System.IntPtr TranslatePositionFromPhysicsSpace(HandleRef adaptor, HandleRef position); + // Vector3 + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_TranslateFromPhysicsSpace_2")] + internal static extern global::System.IntPtr TranslateRotationFromPhysicsSpace(HandleRef adaptor, HandleRef rotation); + // Quaternion + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_ConvertVectorToPhysicsSpace")] + internal static extern global::System.IntPtr ConvertVectorToPhysicsSpace(HandleRef adaptor, HandleRef vector); + // Vector3 + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_ConvertVectorFromPhysicsSpace")] + internal static extern global::System.IntPtr ConvertVectorFromPhysicsSpace(HandleRef adaptor, HandleRef vector); + // Vector3 + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_SetTransformAndSize")] + internal static extern void SetTransformAndSize(HandleRef adaptor, HandleRef transform, HandleRef size); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_SetIntegrationState")] + internal static extern void SetIntegrationState(HandleRef adaptor, int integrationState); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_GetIntegrationState")] + internal static extern int GetIntegrationState(HandleRef adaptor); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_SetDebugState")] + internal static extern void SetDebugState(HandleRef adaptor, int integrationState); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_GetDebugState")] + internal static extern int GetDebugState(HandleRef adaptor); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_AddActorBody")] + internal static extern global::System.IntPtr AddActorBody(HandleRef adaptor, HandleRef actor, global::System.IntPtr body); + // PhysicsActor + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_RemoveActorBody")] + internal static extern void RemoveActorBody(HandleRef adaptor, HandleRef physicsActor); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_GetPhysicsActor")] + internal static extern global::System.IntPtr GetPhysicsActor(HandleRef adaptor, global::System.IntPtr body); + // PhysicsActor + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_GetRootActor")] + internal static extern global::System.IntPtr GetRootActor(HandleRef adaptor); + // Actor + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_BuildPickingRay")] + internal static extern void BuildPickingRay(HandleRef adaptor, HandleRef origin, HandleRef direction, + HandleRef rayFromWorld, HandleRef rayToWorld); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_ProjectPoint")] + internal static extern global::System.IntPtr ProjectPoint(HandleRef adaptor, HandleRef origin, HandleRef direction, float distance); + // Vector3 + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_CreateSyncPoint")] + internal static extern void CreateSyncPoint(HandleRef adaptor); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsAdaptor_GetPhysicsWorld")] + internal static extern global::System.IntPtr GetPhysicsWorld(HandleRef adaptor); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Libraries.cs b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Libraries.cs new file mode 100644 index 00000000000..b9e984ead31 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.Libraries.cs @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Tizen.NUI.Physics2D +{ + internal static partial class Interop + { + internal static partial class Libraries + { +#if __MACOS__ + public const string Physics2D = "libdali2-csharp-binder-physics-2d.dylib"; +#else + public const string Physics2D = "libdali2-csharp-binder-physics-2d.so"; +#endif + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.World.cs b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.World.cs new file mode 100644 index 00000000000..29aea3bb83b --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/internal/interop/Interop.World.cs @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; +using Tizen.NUI.Physics2D.Chipmunk; + +namespace Tizen.NUI.Physics2D +{ + internal static partial class Interop + { + internal static partial class World + { + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsWorld_Lock")] + internal static extern void Lock(global::System.IntPtr world); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsWorld_Unlock")] + internal static extern void Unlock(global::System.IntPtr world); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsWorld_GetNative")] + internal static extern global::System.IntPtr GetNative(global::System.IntPtr world); + + [DllImport(Libraries.Physics2D, EntryPoint = "CSharp_Dali_PhysicsWorld_HitTest")] + internal static extern global::System.IntPtr HitTest(global::System.IntPtr world, HandleRef rayFromWorld, + HandleRef rayToWorld, Chipmunk.ShapeFilter nativeFilter, + HandleRef localPivot, out float distanceFromCamera); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs index 850b2087d7f..647c0ef5746 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs @@ -7,10 +7,10 @@ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -247,7 +247,7 @@ public BodyType Type /// /// Mass of the rigid body. Mass does not have to be expressed in any particular units, but - /// relative masses should be consistent. + /// relative masses should be consistent. /// [EditorBrowsable(EditorBrowsableState.Never)] public double Mass @@ -259,7 +259,7 @@ public double Mass /// /// Moment of inertia of the body. The mass tells you how hard it is to push an object, /// the MoI tells you how hard it is to spin the object. Don't try to guess the MoI, use the - /// MomentFor*() functions to estimate it, or the physics may behave strangely. + /// MomentFor*() functions to estimate it, or the physics may behave strangely. /// [EditorBrowsable(EditorBrowsableState.Never)] public double Moment diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs index df8c661356b..db27ebd845b 100755 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs @@ -7,10 +7,10 @@ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -77,6 +77,12 @@ protected internal Space(cpSpace handle) RegisterUserData(); } + [EditorBrowsable(EditorBrowsableState.Never)] + internal static Space NativeSpace(cpSpace handle) + { + return new Space(handle); + } + /// /// Destroys and frees. /// @@ -169,7 +175,7 @@ public int Iterations } /// - /// Gravity to pass to rigid bodies when integrating velocity. + /// Gravity to pass to rigid bodies when integrating velocity. /// [EditorBrowsable(EditorBrowsableState.Never)] public Vect Gravity @@ -193,7 +199,7 @@ public double Damping /// /// Speed threshold for a body to be considered idle. The default value of 0 means to let - /// the space guess a good threshold based on gravity. + /// the space guess a good threshold based on gravity. /// [EditorBrowsable(EditorBrowsableState.Never)] public double IdleSpeedThreshold @@ -205,7 +211,7 @@ public double IdleSpeedThreshold /// /// Time a group of bodies must remain idle in order to fall asleep. Enabling sleeping also /// implicitly enables the the contact graph. The default value of infinity disables the - /// sleeping algorithm. + /// sleeping algorithm. /// [EditorBrowsable(EditorBrowsableState.Never)] public double SleepTimeThreshold @@ -218,7 +224,7 @@ public double SleepTimeThreshold /// Amount of encouraged penetration between colliding shapes. This is used to reduce /// oscillating contacts and keep the collision cache warm. Defaults to 0.1. If you have /// poor simulation quality, increase this number as much as possible without allowing - /// visible amounts of overlap. + /// visible amounts of overlap. /// [EditorBrowsable(EditorBrowsableState.Never)] public double CollisionSlop @@ -335,7 +341,7 @@ public void AddShape(Shape shape) } /// - /// Add a rigid body to the simulation. + /// Add a rigid body to the simulation. /// [EditorBrowsable(EditorBrowsableState.Never)] public void AddBody(Body body) diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs new file mode 100644 index 00000000000..9313ff15e2f --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs @@ -0,0 +1,776 @@ +/* + * Copyright (c) 2023 Codefoco (codefoco@codefoco.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.InteropServices; +using cpBody = System.IntPtr; +using cpCollisionHandlerPointer = System.IntPtr; +using cpCollisionType = System.UIntPtr; +using cpConstraint = System.IntPtr; +using cpDataPointer = System.IntPtr; +using cpShape = System.IntPtr; +using cpSpace = System.IntPtr; +using voidptr_t = System.IntPtr; + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +using ObjCRuntime; +#endif + +namespace Tizen.NUI.Physics2D.Chipmunk +{ + /// + /// Weak reference to a Space. + /// Gives access to the Native cpSpace API without enforcing + /// ownership of the space (which may instead be owned by the + /// rendering library) + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class SpaceRef + { +#pragma warning disable IDE0032 + private readonly cpSpace space; +#pragma warning restore IDE0032 + + /// + /// The space reference constructor can only be called from + /// Tizen.NUI.Physics2D.ScopedPhysicsAccessor.GetNative(). + /// It is not intended to be generated by the developer. + /// + /// + internal SpaceRef(cpSpace handle) + { + space = handle; + } + + /// + /// Get a Space object from native cpSpace handle. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private static Space FromHandle(cpSpace space) + { + cpDataPointer handle = NativeMethods.cpSpaceGetUserData(space); + return NativeInterop.FromIntPtr(handle); + } + + + // Properties + + /// + /// Arbitrary user data. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public object Data { get; set; } + + /// + /// Number of iterations to use in the impulse solver to solve contacts and other + /// constraints. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int Iterations + { + get => NativeMethods.cpSpaceGetIterations(space); + set => NativeMethods.cpSpaceSetIterations(space, value); + } + + /// + /// Gravity to pass to rigid bodies when integrating velocity. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vect Gravity + { + get => NativeMethods.cpSpaceGetGravity(space); + set => NativeMethods.cpSpaceSetGravity(space, value); + } + + /// + /// Damping rate expressed as the fraction of velocity that bodies retain each second. A + /// value of 0.9 would mean that each body's velocity will drop 10% per second. The default + /// value is 1.0, meaning no damping is applied. Note: This damping value is different than + /// those of and . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double Damping + { + get => NativeMethods.cpSpaceGetDamping(space); + set => NativeMethods.cpSpaceSetDamping(space, value); + } + + /// + /// Speed threshold for a body to be considered idle. The default value of 0 means to let + /// the space guess a good threshold based on gravity. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double IdleSpeedThreshold + { + get => NativeMethods.cpSpaceGetIdleSpeedThreshold(space); + set => NativeMethods.cpSpaceSetIdleSpeedThreshold(space, value); + } + + /// + /// Time a group of bodies must remain idle in order to fall asleep. Enabling sleeping also + /// implicitly enables the the contact graph. The default value of infinity disables the + /// sleeping algorithm. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double SleepTimeThreshold + { + get => NativeMethods.cpSpaceGetSleepTimeThreshold(space); + set => NativeMethods.cpSpaceSetSleepTimeThreshold(space, value); + } + + /// + /// Amount of encouraged penetration between colliding shapes. This is used to reduce + /// oscillating contacts and keep the collision cache warm. Defaults to 0.1. If you have + /// poor simulation quality, increase this number as much as possible without allowing + /// visible amounts of overlap. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double CollisionSlop + { + get => NativeMethods.cpSpaceGetCollisionSlop(space); + set => NativeMethods.cpSpaceSetCollisionSlop(space, value); + } + + /// + /// Determines how fast overlapping shapes are pushed apart. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double CollisionBias + { + get => NativeMethods.cpSpaceGetCollisionBias(space); + set => NativeMethods.cpSpaceSetCollisionBias(space, value); + } + + /// + /// Number of frames that contact information should persist. Defaults to 3. There is + /// probably never a reason to change this value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public int CollisionPersistence + { + get => (int)NativeMethods.cpSpaceGetCollisionPersistence(space); + set => NativeMethods.cpSpaceSetCollisionPersistence(space, (uint)value); + } + + /// + /// The Space provided static body for a given . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Body StaticBody + { + get + { + cpBody bodyHandle = NativeMethods.cpSpaceGetStaticBody(space); + cpDataPointer gcHandle = NativeMethods.cpBodyGetUserData(bodyHandle); + + if (gcHandle != IntPtr.Zero) + { + return NativeInterop.FromIntPtr(gcHandle); + } + + return new Body(bodyHandle); + } + } + + /// + /// Returns the current (or most recent) time step used with the given space. + /// Useful from callbacks if your time step is not a compile-time global. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public double CurrentTimeStep => NativeMethods.cpSpaceGetCurrentTimeStep(space); + + /// + /// Returns true from inside a callback when objects cannot be added/removed. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsLocked => NativeMethods.cpSpaceIsLocked(space) != 0; + + + // Collision Handlers + + /// + /// Create or return the existing collision handler that is called for all collisions that are + /// not handled by a more specific collision handler. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CollisionHandler GetOrCreateDefaultCollisionHandler() + { + cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddDefaultCollisionHandler(space); + return CollisionHandler.GetOrCreate(collisionHandle); + } + + /// + /// Create or return the existing collision handler for the specified pair of collision + /// types. If wildcard handlers are used with either of the collision types, it's the + /// responsibility of the custom handler to invoke the wildcard handlers. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CollisionHandler GetOrCreateCollisionHandler(int typeA, int typeB) + { + uint utypeA = unchecked((uint)typeA); + uint utypeB = unchecked((uint)typeB); + + cpCollisionType collisionTypeA = new cpCollisionType(utypeA); + cpCollisionType collisionTypeB = new cpCollisionType(utypeB); + + cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddCollisionHandler(space, collisionTypeA, collisionTypeB); + return CollisionHandler.GetOrCreate(collisionHandle); + } + + + /// + /// Create or return the existing wildcard collision handler for the specified type. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CollisionHandler GetOrCreateWildcardHandler(int type) + { + cpCollisionHandlerPointer collisionHandle = NativeMethods.cpSpaceAddWildcardHandler(space, (cpCollisionType)type); + return CollisionHandler.GetOrCreate(collisionHandle); + } + + /// + /// Add a collision shape to the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddShape(Shape shape) + { + NativeMethods.cpSpaceAddShape(space, shape.Handle); + } + + /// + /// Add a rigid body to the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddBody(Body body) + { + NativeMethods.cpSpaceAddBody(space, body.Handle); + } + + /// + /// Add a constraint to the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddConstraint(Constraint constraint) + { + NativeMethods.cpSpaceAddConstraint(space, constraint.Handle); + } + + /// + /// Remove a collision shape from the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveShape(Shape shape) + { + NativeMethods.cpSpaceRemoveShape(space, shape.Handle); + } + + /// + /// Remove a rigid body from the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveBody(Body body) + { + NativeMethods.cpSpaceRemoveBody(space, body.Handle); + } + + /// + /// Remove a constraint from the simulation. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveConstraint(Constraint constraint) + { + NativeMethods.cpSpaceRemoveConstraint(space, constraint.Handle); + } + + /// + /// Test if a collision shape has been added to the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Contains(Shape shape) + { + return NativeMethods.cpSpaceContainsShape(space, shape.Handle) != 0; + } + + /// + /// Test if a rigid body has been added to the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Contains(Body body) + { + return NativeMethods.cpSpaceContainsBody(space, body.Handle) != 0; + } + + /// + /// Test if a constraint has been added to the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Contains(Constraint constraint) + { + return NativeMethods.cpSpaceContainsConstraint(space, constraint.Handle) != 0; + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(PostStepFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void PostStepCallBack(cpSpace handleSpace, voidptr_t handleKey, voidptr_t handleData) + { + var space = FromHandle(handleSpace); + var key = NativeInterop.FromIntPtr(handleKey); + var data = NativeInterop.FromIntPtr(handleData); + + Action callback = data.Callback; + + callback(space, key, data.Data); + + NativeInterop.ReleaseHandle(handleKey); + NativeInterop.ReleaseHandle(handleData); + } + + private static PostStepFunction postStepCallBack = PostStepCallBack; + + /// + /// Schedule a post-step callback to be called when finishes. You can + /// only register one callback per unique value for . Returns true + /// only if has never been scheduled before. It's possible to pass + /// null for if you only want to mark as + /// being used. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool AddPostStepCallback(Action callback, object key, object data) + { + var info = new PostStepCallbackInfo(callback, data); + + IntPtr dataHandle = NativeInterop.RegisterHandle(info); + IntPtr keyHandle = NativeInterop.RegisterHandle(key); + + return NativeMethods.cpSpaceAddPostStepCallback(space, postStepCallBack.ToFunctionPointer(), keyHandle, dataHandle) != 0; + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpacePointQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachPointQuery(cpShape shapeHandle, Vect point, double distance, Vect gradient, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + var pointQuery = new PointQueryInfo(shape, point, distance, gradient); + + list.Add(pointQuery); + } + + private static SpacePointQueryFunction eachPointQuery = EachPointQuery; + + /// + /// Get the shapes within a radius of the point location that are part of this space. The + /// filter is applied to the query and follows the same rules as the collision detection. + /// If a maxDistance of 0.0 is used, the point must lie inside a shape. Negative + /// is also allowed meaning that the point must be a under a + /// certain depth within a shape to be considered a match. + /// + /// Where to check for shapes in the space. + /// Match only within this distance. + /// Only pick shapes matching the filter. + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList PointQuery(Vect point, double maxDistance, ShapeFilter filter) + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpacePointQuery(space, point, maxDistance, filter, eachPointQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + + /// + /// Get the nearest shape within a radius of a point that is part of this space. The filter + /// is applied to the query and follows the same rules as the collision detection. If a + /// of 0.0 is used, the point must lie inside a shape. + /// Negative is also allowed, meaning that the point must be + /// under a certain depth within a shape to be considered a match. + /// + /// Where to check for collision in the space. + /// Match only within this distance. + /// Only pick shapes matching the filter. + [EditorBrowsable(EditorBrowsableState.Never)] + public PointQueryInfo PointQueryNearest(Vect point, double maxDistance, ShapeFilter filter) + { + var queryInfo = new cpPointQueryInfo(); + + cpShape shape = NativeMethods.cpSpacePointQueryNearest(space, point, maxDistance, filter, ref queryInfo); + if (shape == IntPtr.Zero) + return null; + + return PointQueryInfo.FromQueryInfo(queryInfo); + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceSegmentQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachSegmentQuery(cpShape shapeHandle, Vect point, Vect normal, double alpha, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + var pointQuery = new SegmentQueryInfo(shape, point, normal, alpha); + + list.Add(pointQuery); + } + + private static SpaceSegmentQueryFunction eachSegmentQuery = EachSegmentQuery; + + /// + /// Get the shapes within a capsule-shaped radius of a line segment that is part of this + /// space. The filter is applied to the query and follows the same rules as the collision + /// detection. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList SegmentQuery(Vect start, Vect end, double radius, ShapeFilter filter) + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceSegmentQuery(space, start, end, radius, filter, eachSegmentQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + + /// + /// Get the first shape within a capsule-shaped radius of a line segment that is part of + /// this space. The filter is applied to the query and follows the same rules as the + /// collision detection. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public SegmentQueryInfo SegmentQueryFirst(Vect start, Vect end, double radius, ShapeFilter filter) + { + var queryInfo = new cpSegmentQueryInfo(); + + cpShape shape = NativeMethods.cpSpaceSegmentQueryFirst(space, start, end, radius, filter, ref queryInfo); + if (shape == IntPtr.Zero) + return null; + + return SegmentQueryInfo.FromQueryInfo(queryInfo); + } + + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceBBQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachBBQuery(cpShape shapeHandle, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + + list.Add(shape); + } + + private static SpaceBBQueryFunction eachBBQuery = EachBBQuery; + + + /// + /// Get all shapes within the axis-aligned bounding box that are part of this shape. The + /// filter is applied to the query and follows the same rules as the collision detection. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList BoundBoxQuery(BoundingBox bb, ShapeFilter filter) + { + var list = new List(); + + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceBBQuery(space, bb, filter, eachBBQuery.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + + /// + /// Get all bodies in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Bodies + { + get + { + int count = NativeMethods.cpSpaceGetBodyCount(space); + + if (count == 0) + return Array.Empty(); + + IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + NativeMethods.cpSpaceGetBodiesUserDataArray(space, ptrBodies); + + IntPtr[] userDataArray = new IntPtr[count]; + + Marshal.Copy(ptrBodies, userDataArray, 0, count); + + Marshal.FreeHGlobal(ptrBodies); + + Body[] bodies = new Body[count]; + + for (int i = 0; i < count; i++) + { + Body b = NativeInterop.FromIntPtr(userDataArray[i]); + bodies[i] = b; + } + + return bodies; + } + } + + /// + /// Get dynamic bodies in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList DynamicBodies + { + get + { + int count = NativeMethods.cpSpaceGetDynamicBodyCount(space); + + if (count == 0) + return Array.Empty(); + + IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + NativeMethods.cpSpaceGetDynamicBodiesUserDataArray(space, ptrBodies); + + IntPtr[] userDataArray = new IntPtr[count]; + + Marshal.Copy(ptrBodies, userDataArray, 0, count); + + Marshal.FreeHGlobal(ptrBodies); + + Body[] bodies = new Body[count]; + + for (int i = 0; i < count; i++) + { + Body b = NativeInterop.FromIntPtr(userDataArray[i]); + bodies[i] = b; + } + + return bodies; + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceObjectIteratorFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachShape(cpShape shapeHandle, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var shape = Shape.FromHandle(shapeHandle); + + list.Add(shape); + } + + private static SpaceObjectIteratorFunction eachShape = EachShape; + + /// + /// Get all shapes in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Shapes + { + get + { + var list = new List(); + + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceEachShape(space, eachShape.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + + return list; + } + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceShapeQueryFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void ShapeQueryCallback(cpShape shape, IntPtr pointsPointer, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var pointSet = NativeInterop.PtrToStructure(pointsPointer); + + list.Add(ContactPointSet.FromContactPointSet(pointSet)); + } + + private static SpaceShapeQueryFunction shapeQueryCallback = ShapeQueryCallback; + + /// + /// Get all shapes in the space that are overlapping the given shape. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList ShapeQuery(Shape shape) + { + var list = new List(); + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceShapeQuery(space, shape.Handle, shapeQueryCallback.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + return list; + } + +#if __IOS__ || __TVOS__ || __WATCHOS__ || __MACCATALYST__ +#pragma warning disable CA1416 // Validate platform compatibility + [MonoPInvokeCallback(typeof(SpaceObjectIteratorFunction))] +#pragma warning restore CA1416 // Validate platform compatibility +#endif + private static void EachConstraint(cpConstraint constraintHandle, voidptr_t data) + { + var list = (List)GCHandle.FromIntPtr(data).Target; + + var constraint = Constraint.FromHandle(constraintHandle); + + list.Add(constraint); + } + + private static SpaceObjectIteratorFunction eachConstraint = EachConstraint; + + + /// + /// Get all constraints in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList Constraints + { + get + { + var list = new List(); + + var gcHandle = GCHandle.Alloc(list); + + NativeMethods.cpSpaceEachConstraint(space, eachConstraint.ToFunctionPointer(), GCHandle.ToIntPtr(gcHandle)); + + gcHandle.Free(); + + return list; + } + } + + /// + /// Update the collision detection info for the static shapes in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ReindexStatic() + { + NativeMethods.cpSpaceReindexStatic(space); + } + + /// + /// Update the collision detection data for a specific shape in the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ReindexShape(Shape shape) + { + NativeMethods.cpSpaceReindexShape(space, shape.Handle); + } + + /// + /// Update the collision detection data for all shapes attached to a body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ReindexShapesForBody(Body body) + { + NativeMethods.cpSpaceReindexShapesForBody(space, body.Handle); + } + + /// + /// Switch the space to use a spatial hash as its spatial index. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void UseSpatialHash(double dim, int count) + { + NativeMethods.cpSpaceUseSpatialHash(space, dim, count); + } + + /// + /// Update the space for the given time step. Using a fixed time step is highly recommended. + /// Doing so will increase the efficiency of the contact persistence, requiring an order of + /// magnitude fewer iterations to resolve the collisions in the usual case. It is not the + /// same to call step 10 times with a dt of 0.1, or 100 times with a dt of 0.01 even if the + /// end result is that the simulation moved forward 100 units. Performing multiple calls + /// with a smaller dt creates a more stable and accurate simulation. Therefore, it sometimes + /// makes sense to have a little for loop around the step call. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void Step(double dt) + { + NativeMethods.cpSpaceStep(space, dt); + } + + /// + /// Draw all objects in the space for debugging purposes. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void DebugDraw(IDebugDraw debugDraw) + { + DebugDraw(debugDraw, DebugDrawFlags.All, DebugDrawColors.Default); + } + + /// + /// Draw all objects in the space for debugging purposes using flags. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void DebugDraw(IDebugDraw debugDraw, DebugDrawFlags flags) + { + DebugDraw(debugDraw, flags, DebugDrawColors.Default); + } + + /// + /// Draw all objects in the space for debugging purposes using flags and colors. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void DebugDraw(IDebugDraw debugDraw, DebugDrawFlags flags, DebugDrawColors colors) + { + var debugDrawOptions = new cpSpaceDebugDrawOptions(); + IntPtr debugDrawOptionsPointer = debugDrawOptions.AcquireDebugDrawOptions(debugDraw, flags, colors); + + NativeMethods.cpSpaceDebugDraw(space, debugDrawOptionsPointer); + + debugDrawOptions.ReleaseDebugDrawOptions(debugDrawOptionsPointer); + } + + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsActor.cs b/src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsActor.cs new file mode 100644 index 00000000000..2c2684b77c8 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsActor.cs @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using Tizen.NUI.BaseComponents; + +namespace Tizen.NUI.Physics2D +{ + /// + /// Class to associate a physics body (such as btRigidBody*) with a View + /// for rendering. + /// + /// This object offers methods to modify basic physics properties + /// asynchronously, that is, on the Update thread. + /// + /// Currently, using the Physics API directly should be done after + /// blocking the physics integration step, by getting a ScopedAccessor from + /// the PhysicsAdaptor. Once the ScopedAccessor is disposed, then the + /// physics integration will run again. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class PhysicsActor : BaseHandle + { +#pragma warning disable IDE0032 + private readonly View _view; +#pragma warning restore IDE0032 + + /// + /// View is the view used for rendering the associated physics body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public NUI.BaseComponents.View View => _view; + + /// + /// Binds the actor to the given body. This should be a body that has + /// been added to the physics world, and has physical postion and + /// rotation in that space. The Actor is used to render that object in + /// DALi space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PhysicsActor(View view, Chipmunk.Body body, PhysicsAdaptor adaptor) + : this(Interop.Actor.PhysicsActorNew(View.getCPtr(view), body.Handle, PhysicsAdaptor.getCPtr(adaptor)), true) + { + this._view = view; + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Copy Constructor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PhysicsActor(PhysicsActor adaptor) : this( Interop.Actor.NewPhysicsActor(PhysicsActor.getCPtr(adaptor)), true) + { + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Assignment "operator" + /// + internal PhysicsActor Assign(PhysicsActor rhs) + { + PhysicsActor adaptor = new PhysicsActor(Interop.Actor.Assign(SwigCPtr, PhysicsActor.getCPtr(rhs)), false); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return adaptor; + } + + internal PhysicsActor(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + { + } + + /// + /// Dispose the physics actor + /// This will release the View, but it's up to the caller to release the Body. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void Dispose(DisposeTypes type) + { + if(disposed) + { + return; + } + if(type == DisposeTypes.Explicit) + { + // Called by user + // Release managed resources + } + // Release unmanaged resources + + base.Dispose(type); + } + + /** + */ + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr) + { + Interop.Actor.DeletePhysicsActor(swigCPtr); + } + + /// + /// Get the physics body associated with this physics actor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Chipmunk.Body GetBody() + { + IntPtr cPtr = Interop.Actor.GetBody(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Chipmunk.Body(cPtr); + } + + /// + /// Queue a method to set the position on the associated physics body + /// in the update thread before the next integration. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AsyncSetPhysicsPosition(Vector3 position) + { + Interop.Actor.AsyncSetPhysicsPosition(SwigCPtr, Vector3.getCPtr(position)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Queue a method to set the rotation of the associated physics body + /// in the update thread before the next integration. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AsyncSetPhysicsRotation(Rotation position) + { + Interop.Actor.AsyncSetPhysicsRotation(SwigCPtr, Rotation.getCPtr(position)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Get the current position of the physics body in Physics space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 GetPhysicsPosition() + { + IntPtr cPtr = Interop.Actor.GetPhysicsPosition(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Vector3(cPtr, true); + } + + /// + /// Get the current rotation of the physics body in Physics space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Rotation GetPhysicsRotation() + { + IntPtr cPtr = Interop.Actor.GetPhysicsRotation(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Rotation(cPtr, true); + } + + /// + /// Get the current position of the View in world space + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 GetActorPosition() + { + IntPtr cPtr = Interop.Actor.GetActorPosition(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Vector3(cPtr, true); + } + + /// + /// Get the current rotation of the View in world space + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Rotation GetActorRotation() + { + IntPtr cPtr = Interop.Actor.GetActorRotation(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Rotation(cPtr, true); + } + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsAdaptor.cs b/src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsAdaptor.cs new file mode 100644 index 00000000000..3dd72f2d709 --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/wrapper/PhysicsAdaptor.cs @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System.ComponentModel; +using System.Runtime.InteropServices; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Binding; +using Tizen.NUI; + +namespace Tizen.NUI.Physics2D +{ + /// + /// Enumeration to turn the integration step on or off. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public enum IntegrationState + { + /// + ///Integration state is turned off - physics stops running + /// + Off, + + /// + ///Integration state is turned on - physics runs in Update thread + /// + On + }; + + /// + /// Enumeration to turn the debug layer on or off. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public enum DebugState + { + /// + ///Debug state is turned off - no debug is drawn + /// + Off, + + /// + ///Debug state is turned on - if there is a Debug layer, then + ///the physics debug is drawn over the top of the root layer + /// + On + }; + + /// + /// Adaptor to manage access to the physics world and pairing actors and physics + /// bodies, plus some translation methods to/from the physics space and dali space. + /// + /// Also manages a debug renderer that may utilize the physics engine debug. + /// It is up to the developer to retrieve the root actor and parent it into the scene. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class PhysicsAdaptor : NUI.BaseHandle + { + /// + /// Initialize the physics system. + /// Transformation matrix from NUI space to the Physics Space + /// Size of the root layer that the adaptor creates + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PhysicsAdaptor(NUI.Matrix transform, NUI.Vector2 size) + : this(Interop.Adaptor.PhysicsAdaptorNew(NUI.Matrix.getCPtr(transform), NUI.Vector2.getCPtr(size)), true) + { + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Copy Constructor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PhysicsAdaptor(PhysicsAdaptor adaptor) : this( Interop.Adaptor.NewPhysicsAdaptor(PhysicsAdaptor.getCPtr(adaptor)), true) + { + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + internal PhysicsAdaptor Assign(PhysicsAdaptor rhs) + { + PhysicsAdaptor adaptor = new PhysicsAdaptor(Interop.Adaptor.Assign(SwigCPtr, PhysicsAdaptor.getCPtr(rhs)), false); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return adaptor; + } + + internal PhysicsAdaptor(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + { + } + + /// + /// Dispose the PhysicsAdaptor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void Dispose(DisposeTypes type) + { + if(disposed) + { + return; + } + if(type == DisposeTypes.Explicit) + { + // Called by user + // Release managed resources + } + // Release unmanaged resources + + base.Dispose(type); + } + + /// This will not be publicly opened + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr) + { + Interop.Adaptor.DeletePhysicsAdaptor(swigCPtr); + } + + /// + /// The time that the integration step notionally takes. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float Timestep + { + get + { + return GetTimestep(); + } + set + { + SetTimestep(value); + } + } + + internal float GetTimestep() + { + float timestep = Interop.Adaptor.GetTimestep(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return timestep; + } + internal void SetTimestep(float timestep) + { + Interop.Adaptor.SetTimestep(SwigCPtr, timestep); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Property to handle the IntegrationState of the adaptor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public IntegrationState IntegrationState + { + get + { + return GetIntegrationState(); + } + set + { + SetIntegrationState(value); + } + } + internal IntegrationState GetIntegrationState() + { + int state = Interop.Adaptor.GetIntegrationState(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return (IntegrationState)state; + } + internal void SetIntegrationState(IntegrationState state) + { + Interop.Adaptor.SetIntegrationState(SwigCPtr, (int)state); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Property to handle the debug state of the adaptor + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Physics2D.DebugState DebugState + { + get + { + return GetDebugState(); + } + set + { + SetDebugState(value); + } + } + internal DebugState GetDebugState() + { + int state = Interop.Adaptor.GetDebugState(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return (DebugState)state; + } + internal void SetDebugState(DebugState state) + { + Interop.Adaptor.SetDebugState(SwigCPtr, (int)state); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + + /// + /// Change the transform matrix or the size of the root view + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetTransformAndSize(Matrix transform, Vector2 size) + { + Interop.Adaptor.SetTransformAndSize(SwigCPtr, Matrix.getCPtr(transform), Vector2.getCPtr(size)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Return an accessor to the physics world. + /// Internally, this locks a mutex to prevent the integration step from running, + /// this will also block the Update thread. It is important that this accessor + /// is disposed of when not needed to restart the update thread. (Suggest use of + /// "using" block). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ScopedPhysicsAccessor GetAccessor() + { + global::System.IntPtr worldCPtr = Interop.Adaptor.GetPhysicsWorld(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new ScopedPhysicsAccessor(worldCPtr); + } + + /// + /// Add a view to the body. The view will be used to render the body. It is parented onto the root layer. + /// The physics body should be added to the physics space by the user. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PhysicsActor AddViewToBody(View view, Chipmunk.Body body) + { + // @todo Converting a View to an Actor internally _should_ be OK?! + global::System.IntPtr cPtr = Interop.Adaptor.AddActorBody(SwigCPtr, View.getCPtr(view), body.Handle); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new PhysicsActor(cPtr, false); + } + + /// + /// This will unparent the View from the root layer, and dis-associate it + /// from the physics body. It is the responsibility of the user to remove + /// the physics body from the world. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveViewFromBody(PhysicsActor actor) + { + Interop.Adaptor.RemoveActorBody(SwigCPtr, PhysicsActor.getCPtr(actor)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Retrieve a PhysicsActor given a physics body. + /// If there is no associated PhysicsActor, this will return null. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public PhysicsActor GetPhysicsActor(Chipmunk.Body body) + { + global::System.IntPtr cPtr = Interop.Adaptor.GetPhysicsActor(SwigCPtr, body.Handle); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + // @todo This creates a new PhysicsActor on native side, but it's + // not registered with native or c# registries. Do we need to add functionality? + if(cPtr != global::System.IntPtr.Zero) + { + return new PhysicsActor(cPtr, false); + } + else + { + return null; + } + } + + /// + /// + /// + //public Layer GetRootLayer()... it's needed for 2 things - touch and finding actors. + // Provide a PhysisActor api to get View back + [EditorBrowsable(EditorBrowsableState.Never)] + public Layer GetRootLayer() + { + global::System.IntPtr cPtr = Interop.Adaptor.GetRootActor(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + // @todo Test against registry? + Layer layer = new Layer(cPtr, false); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return layer; + } + + /// + /// Convert a touch point into a picking ray in the Physics space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void BuildPickingRay(Vector3 origin, Vector3 direction, /*out*/ Vector3 rayFromWorld, /*out*/ Vector3 rayToWorld) + { + Interop.Adaptor.BuildPickingRay(SwigCPtr, Vector3.getCPtr(origin), Vector3.getCPtr(direction), + Vector3.getCPtr(rayFromWorld), Vector3.getCPtr(rayToWorld)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Project a point from the origin (in NUI space) a distance along the direction + /// vector (in NUI space) and returns the projected point in physics space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 ProjectPoint(Vector3 origin, Vector3 direction, float distance) + { + global::System.IntPtr cPtr = Interop.Adaptor.ProjectPoint(SwigCPtr, Vector3.getCPtr(origin), Vector3.getCPtr(direction), distance); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Vector3(cPtr, true); + } + + /// + /// Transforms a position from NUI space to physics space + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 TransformPositionToPhysicsSpace(Vector3 position) + { + global::System.IntPtr cPtr = Interop.Adaptor.TranslatePositionToPhysicsSpace(SwigCPtr, Vector3.getCPtr(position)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Vector3(cPtr, true); + } + + /// + /// Transform a rotation from NUI to physics space + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Rotation TransformRotationToPhysicsSpace(Rotation rotation) + { + global::System.IntPtr cPtr = Interop.Adaptor.TranslateRotationToPhysicsSpace(SwigCPtr, Rotation.getCPtr(rotation)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Rotation(cPtr, true); + } + + /// + /// Transform a position in Physics space to NUI space + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 TransformPositionFromPhysicsSpace(Vector3 position) + { + global::System.IntPtr cPtr = Interop.Adaptor.TranslatePositionFromPhysicsSpace(SwigCPtr, Vector3.getCPtr(position)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Vector3(cPtr, true); + } + + /// + /// Convert a rotation in physics space into NUI space + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Rotation TransformRotationFromPhysicsSpace(Rotation rotation) + { + global::System.IntPtr cPtr = Interop.Adaptor.TranslateRotationFromPhysicsSpace(SwigCPtr, Rotation.getCPtr(rotation)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Rotation(cPtr, true); + } + + /// + /// Converts a vector (not a point) in NUI space to Physics space + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 ConvertVectorToPhysicsSpace(Vector3 vector) + { + global::System.IntPtr cPtr = Interop.Adaptor.ConvertVectorToPhysicsSpace(SwigCPtr, Vector3.getCPtr(vector)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Vector3(cPtr, true); + } + + /// + /// Converts a vector (not a point) in physics space to NUI space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Vector3 ConvertVectorFromPhysicsSpace(Vector3 vector) + { + global::System.IntPtr cPtr = Interop.Adaptor.ConvertVectorFromPhysicsSpace(SwigCPtr, Vector3.getCPtr(vector)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Vector3(cPtr, true); + } + + /// + /// The debug layer uses a drawable actor and the debug features of the native physics engine + /// to render any debug graphics for the physics bodies. + /// This layer needs to be created before setting the DebugState has any effect. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Layer CreateDebugLayer(Window window) + { + global::System.IntPtr cPtr = Interop.Adaptor.CreateDebugLayer(SwigCPtr, Window.getCPtr(window)); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Layer(cPtr, false); + } + + /// + /// A sync point is necessary to synchronize Async calls in the update thread. + /// Any use of the PhysicsActor.AsyncNNN calls will require this API to be called. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void CreateSyncPoint() + { + Interop.Adaptor.CreateSyncPoint(SwigCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + // @todo Define interface for Queue that can accept cdecls. + } +} diff --git a/src/Tizen.NUI.Physics2D/src/public/wrapper/ScopedPhysicsAccessor.cs b/src/Tizen.NUI.Physics2D/src/public/wrapper/ScopedPhysicsAccessor.cs new file mode 100644 index 00000000000..2af0dc3214f --- /dev/null +++ b/src/Tizen.NUI.Physics2D/src/public/wrapper/ScopedPhysicsAccessor.cs @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using Tizen.NUI; +using Tizen.NUI.BaseComponents; + +namespace Tizen.NUI.Physics2D +{ + /// + /// Scoped accessor to the physics world. + /// + /// Automatically locks the physics world with a mutex to prevent the + /// integration step from running whilst the developer is accessing + /// the world, e.g. to add/remove bodies or constraints, or to + /// perform hit-test. + /// + /// When it is disposed, the mutex is unlocked, and the integration step + /// can resume. + /// + /// Suggest that this is created with a "using" block: + /// + /// using(accessor=physicsAdaptor.GetAccessor()) + /// { + /// var space = accessor.GetNative(); + /// // Perform operations on space or bodies. + /// } // automatically disposed. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class ScopedPhysicsAccessor : IDisposable + { + private IntPtr worldCPtr; + + // Can only be constructed by PhysicsAdaptor + internal ScopedPhysicsAccessor(IntPtr worldCPtr) + { + this.worldCPtr = worldCPtr; + Interop.World.Lock(worldCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Get a weak handle to the native physics space. Disposing of + /// this handle does not destroy the space. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Chipmunk.SpaceRef GetNative() + { + IntPtr spaceCPtr = Interop.World.GetNative(worldCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return new Chipmunk.SpaceRef(spaceCPtr); + } + + /// + /// Perform a hit test on the given physics world ray, with a possible filter. + /// The ray can be created with PhysicsAdaptor.BuildPickingRay(). + /// Returns a body if hit, along with the local pivot coordinates and the distance from the ray origin (usually camera) + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Chipmunk.Body HitTest( NUI.Vector3 rayFromWorld, NUI.Vector3 rayToWorld, Chipmunk.ShapeFilter filter, /*out*/ NUI.Vector3 localPivot, out float distanceFromCamera) + { + IntPtr cPtr = Interop.World.HitTest(worldCPtr, NUI.Vector3.getCPtr(rayFromWorld), NUI.Vector3.getCPtr(rayToWorld), filter, NUI.Vector3.getCPtr(localPivot), out distanceFromCamera); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + if(cPtr != global::System.IntPtr.Zero) + { + return new Chipmunk.Body(cPtr); + } + return null; + } + + /// + /// Dispose of this object. + /// This ensures that the integration step is resumed + /// + protected virtual void Dispose(bool disposing) + { + Interop.World.Unlock(worldCPtr); + if(NDalicPINVOKE.SWIGPendingException.Pending) + throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Disposes the Space object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + } + +} diff --git a/src/Tizen.NUI/src/internal/Common/FriendAssembly.cs b/src/Tizen.NUI/src/internal/Common/FriendAssembly.cs index e53710f52cb..54301f4b80a 100755 --- a/src/Tizen.NUI/src/internal/Common/FriendAssembly.cs +++ b/src/Tizen.NUI/src/internal/Common/FriendAssembly.cs @@ -27,6 +27,7 @@ [assembly: InternalsVisibleTo("Tizen.NUI.Components, " + Tizen.NUI.PublicKey.TizenFX)] [assembly: InternalsVisibleTo("Tizen.NUI.Extension, " + Tizen.NUI.PublicKey.TizenFX)] [assembly: InternalsVisibleTo("Tizen.NUI.Scene3D, " + Tizen.NUI.PublicKey.TizenFX)] +[assembly: InternalsVisibleTo("Tizen.NUI.Physics2D, " + Tizen.NUI.PublicKey.TizenFX)] [assembly: InternalsVisibleTo("Tizen.TV.NUI, " + Tizen.NUI.PublicKey.TizenTV)] [assembly: InternalsVisibleTo("Tizen.TV.NUI.Component, " + Tizen.NUI.PublicKey.TizenTV)] diff --git a/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs b/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs index e790decb13d..93b6b70aa2a 100644 --- a/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs +++ b/test/Tizen.NUI.Physics2D.Sample/Physics2DSample.cs @@ -20,190 +20,112 @@ using System.Runtime.CompilerServices; using System.Text; using System.Linq; +using Tizen.NUI; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Constants; +using Tizen.NUI.Physics2D; using Tizen.NUI.Physics2D.Chipmunk; + + // Tests the basic functionality of the Chipmunk2D physics engine without the need of any rendering. // It sets up a 2D physics simulation with a dynamic circle dropping to the top of two static segments // representing the ground and bouncing back. The simulation is run for a fixed number of time steps, // and the position of the circle body is printed at each step to verify the correctness of the physics // simulation. -class Physics2DSample +class Physics2DSample : NUIApplication { - public Physics2DSample() + static string IMAGE_DIR = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "images/"; + + Window mWindow; + Vector2 mWindowSize; + Matrix mTransform; + PhysicsAdaptor mPhysicsAdaptor; + + protected override void OnCreate() { + // Up call to the Base class first + base.OnCreate(); + + mWindow = Window.Instance; + mWindow.BackgroundColor = Color.DarkOrchid; + mWindowSize = mWindow.WindowSize; + + mTransform = new Matrix(); + mTransform.SetIdentityAndScale(new Vector3(1.0f, -1.0f, 1.0f)); + mTransform.SetTranslation(new Vector3(mWindowSize.Width * 0.5f, mWindowSize.Height * 0.5f, 0.0f)); + // Create a space for physics simulation - var space = new Space(); - - // Set up gravity along the Y-axis (negative value for downward) - var gravity = new Vect(0, -100); - space.Gravity = gravity; - - // Create two static bodies (static bodies do not move) with shapes (segments) to form the ground - var groundBody1 = new Body(BodyType.Static); - var groundBody2 = new Body(BodyType.Static); - - // Add the body to the space - space.AddBody(groundBody1); - space.AddBody(groundBody2); - - var groundStart = new Vect(-1000, 0); // Start point of the ground - var groundEnd = new Vect(1000, 0); // End point of the ground - - var groundShape1 = new Segment(groundBody1, groundStart, groundEnd, 0); - var groundShape2 = new Segment(groundBody2, groundStart, groundEnd, 0); - - groundShape1.CollisionType = 0; - groundShape2.CollisionType = 1; - - groundShape1.Elasticity = 0.85f; - groundShape2.Elasticity = 0.85f; - - // Add the shapes to the space - space.AddShape(groundShape1); - space.AddShape(groundShape2); - - // Create a dynamic body with a circle shape - var radius = 20.0; - var mass = 1.0; - var moment = Circle.MomentForCircle(mass, 0, radius, Vect.Zero); - - // Set initial position for the circle - var circleBody = new Body(mass, moment); - circleBody.Position = new Vect(0, 50); - - // Add the body to the space - space.AddBody(circleBody); - - // Create a circle shape - var circleShape = new Circle(circleBody, radius, Vect.Zero); - circleShape.CollisionType = 2; - circleShape.Elasticity = 0.85f; - - // Add the circle shape to the space - space.AddShape(circleShape); - - // Detect the collision between the circle and the ground - CollisionHandler handler = space.GetOrCreateCollisionHandler(0, 2); - handler.Data = new StringBuilder(); - - handler.Begin = (arbiterHandle, spaceHandle, userData) => - { - StringBuilder builder = (StringBuilder)userData; - _ = builder.Append("Begin -> "); - - Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); - }; - - handler.PreSolve = (arbiterHandle, spaceHandle, userData) => - { - StringBuilder builder = (StringBuilder)userData; - _ = builder.Append("PreSolve -> "); - - Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); - - return true; - }; - - handler.PostSolve = (arbiterHandle, spaceHandle, userData) => - { - StringBuilder builder = (StringBuilder)userData; - _ = builder.Append("PostSolve -> "); - - Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); - }; - - handler.Separate = (arbiterHandle, spaceHandle, userData) => - { - StringBuilder builder = (StringBuilder)userData; - _ = builder.Append("Separate -> "); - - Console.WriteLine("CollisionHandler::" + handler.Data.ToString()); - }; - - - // Simulate the physics for some time steps - var numSteps = 60; // Number of simulation steps - var timeStep = 1.0 / 60.0; // Time step for each simulation step (60 FPS) - - // Set the velocity of the circle body to make it move to the right - circleBody.Velocity = new Vect(100, 0); // Velocity of (100, 0) along the X-axis - - for (int i = 0; i < numSteps; ++i) - { - space.Step(timeStep); - - // Print the position of the circle body during simulation - var position = circleBody.Position; - Console.WriteLine("Step " + i + " - Circle Position: (" + position.X + ", " + position.Y + ")"); - } + mPhysicsAdaptor = new PhysicsAdaptor(mTransform, mWindowSize); + mWindow.AddLayer(mPhysicsAdaptor.GetRootLayer()); - // Make a point query on a shape + using (var accessor = mPhysicsAdaptor.GetAccessor()) { - circleShape.Filter = new ShapeFilter((UIntPtr)10, 1, 5); - ShapeFilter filter = circleShape.Filter; - Console.WriteLine("ShapeFilter: " + filter.Group + ", " + filter.Categories + ", " + filter.Mask); - - var body = new Body(1, 1.66); - var shape = new Box(body, 2, 2, 0); - - PointQueryInfo point = shape.PointQuery(new Vect(3, 4)); - Console.WriteLine("Shape PointQuery: Distance: " + point.Distance + ", Point: " + point.Point + ", Gradient.X: " + point.Gradient.X + ", Gradient.Y: " + point.Gradient.Y); - - shape.Dispose(); - body.Dispose(); - } - - // Make a point query on a space - { - var mySpace = new Space(); - var body = new Body(1, 1.66); - var shape = new Box(body, 100, 100, 0); - - body.Position = new Vect(0, 0); - - PointQueryInfo[] infos = mySpace.PointQuery(body.Position, 10.0, ShapeFilter.FILTER_ALL).ToArray(); - Console.WriteLine("Space PointQuery: infos.Length: " + infos.Length); - - mySpace.AddBody(body); - mySpace.AddShape(shape); - - infos = mySpace.PointQuery(body.Position, 10.0, ShapeFilter.FILTER_ALL).ToArray(); - Console.WriteLine("Space PointQuery: infos.Length: " + infos.Length); - - if (infos.Length > 0 && shape == infos[0].Shape) - { - Console.WriteLine("Space PointQuery: The shape matches"); - } - - PointQueryInfo info = space.PointQueryNearest(new Vect(0, 0), 100.0, ShapeFilter.FILTER_ALL); - - if (info == null || info.Shape == null) - { - Console.WriteLine("Space PointQueryNearest: No shape is found"); - } - else + var space = accessor.GetNative(); + + // Set up gravity along the Y-axis (negative value for downward) + var gravity = new Vect(0, -100); + space.Gravity = gravity; + + // Create two static bodies (static bodies do not move) with shapes (segments) to form the ground + var groundBody1 = new Body(BodyType.Static); + var groundBody2 = new Body(BodyType.Static); + + // Add the body to the space + space.AddBody(groundBody1); + space.AddBody(groundBody2); + + var groundStart = new Vect(-1000.0f, 0.0f); // Start point of the ground + var groundEnd = new Vect(1000.0f, 0.0f); // End point of the ground + + var groundShape1 = new Segment(groundBody1, groundStart, groundEnd, 0); + var groundShape2 = new Segment(groundBody2, groundStart, groundEnd, 0); + + groundShape1.CollisionType = 0; + groundShape2.CollisionType = 1; + + groundShape1.Elasticity = 0.85f; + groundShape2.Elasticity = 0.85f; + + // Add the shapes to the space + space.AddShape(groundShape1); + space.AddShape(groundShape2); + + // Create a dynamic body with a circle shape + var radius = 13.0; + var mass = 1.0; + var moment = Circle.MomentForCircle(mass, 0, radius, Vect.Zero); + + // Set initial position for the circle + var circleBody = new Body(mass, moment); + circleBody.Position = new Vect(0, 50); + + // Add the body to the space + space.AddBody(circleBody); + + // Create a circle shape + var circleShape = new Circle(circleBody, radius, Vect.Zero); + circleShape.CollisionType = 2; + circleShape.Elasticity = 0.85f; + + // Add the circle shape to the space + space.AddShape(circleShape); + + View ball; + ball = new ImageView(IMAGE_DIR + "blocks-ball.png") { - Console.WriteLine("Shape PointQueryNearest: Distance: " + info.Distance + ", Point: " + info.Point + ", Gradient.X: " + info.Gradient.X + ", Gradient.Y: " + info.Gradient.Y + ", Body position: " + info.Shape.Body.Position); - } - - shape.Dispose(); - body.Dispose(); - mySpace.Dispose(); + Name = "ball", + Size = new Size(26, 26) + }; + + var physicsBall = mPhysicsAdaptor.AddViewToBody(ball, circleBody); + physicsBall.AsyncSetPhysicsPosition(new Vector3(0.0f, 100.0f, 0.0f)); + // Auto dispose of accessor } - - // Clean up - groundShape1.Dispose(); - groundShape2.Dispose(); - circleShape.Dispose(); - - groundBody1.Dispose(); - groundBody2.Dispose(); - circleBody.Dispose(); - - space.Dispose(); + mPhysicsAdaptor.CreateSyncPoint(); } - + /// /// The main entry point for the application. /// @@ -211,6 +133,6 @@ public Physics2DSample() static void Main(string[] args) { Physics2DSample example = new Physics2DSample(); + example.Run(args); } } - diff --git a/test/Tizen.NUI.Physics2D.Sample/res/images/blocks-ball.png b/test/Tizen.NUI.Physics2D.Sample/res/images/blocks-ball.png new file mode 100644 index 0000000000000000000000000000000000000000..81e97d63287c4d9ef3562d5c8b5fe562b48ae5cc GIT binary patch literal 5158 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 Date: Wed, 13 Sep 2023 12:04:35 +0900 Subject: [PATCH 15/82] [NUI] Fix ImageColor alpha not applied issue Visual look at same value, Visual.MixColor's alpha and Visual.Opacity, we need to synchronize both values. Since we don't open Visual.Opacity property for View side let we control this value inside of View. Signed-off-by: Eunki, Hong --- src/Tizen.NUI/src/public/BaseComponents/ImageView.cs | 1 + .../src/public/BaseComponents/ImageViewBindableProperty.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs b/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs index 7bdc3c1738a..dd9f625486e 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs @@ -67,6 +67,7 @@ private static string ConvertResourceUrl(ref string value) ImageVisualProperty.WrapModeV, ImageVisualProperty.SynchronousLoading, Visual.Property.MixColor, + Visual.Property.Opacity, Visual.Property.PremultipliedAlpha, ImageVisualProperty.OrientationCorrection, ImageVisualProperty.FastTrackUploading, diff --git a/src/Tizen.NUI/src/public/BaseComponents/ImageViewBindableProperty.cs b/src/Tizen.NUI/src/public/BaseComponents/ImageViewBindableProperty.cs index 5ea4767eb17..f8b861331ac 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ImageViewBindableProperty.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ImageViewBindableProperty.cs @@ -589,6 +589,7 @@ public partial class ImageView var imageView = (ImageView)bindable; if (newValue != null) { + imageView.UpdateImage(Visual.Property.Opacity, new PropertyValue(((Color)newValue).A), false); imageView.UpdateImage(Visual.Property.MixColor, new PropertyValue((Color)newValue)); } }, From f019f9fced0f246eccfb1b0c60d6460802c58525 Mon Sep 17 00:00:00 2001 From: Yunhee Seo Date: Thu, 7 Sep 2023 11:49:21 +0900 Subject: [PATCH 16/82] [System.Feedback] Add new feedback_pattern for "da" profile To support using new feedback_pattern for da profile, new pattern string and id value is added to Pattern dictionary. Signed-off-by: Yunhee Seo --- .../Feedback/Feedback.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Tizen.System.Feedback/Feedback/Feedback.cs b/src/Tizen.System.Feedback/Feedback/Feedback.cs index c9b253103f9..7346798e909 100755 --- a/src/Tizen.System.Feedback/Feedback/Feedback.cs +++ b/src/Tizen.System.Feedback/Feedback/Feedback.cs @@ -122,6 +122,38 @@ public class Feedback {"ListReorder", 62}, {"ListSlider", 63}, {"VolumeKeyPressed", 64}, + {"Basic", 40001}, + {"ToggleOn", 40002}, + {"ToggleOff", 40003}, + {"LongPressOn", 40004}, + {"LongPressOff", 40005}, + {"Invalid", 40006}, + {"Confirm", 40007}, + {"PopUp", 40008}, + {"PreheatEnding", 40009}, + {"TaskEnding", 40010}, + {"Scroll", 40011}, + {"PageTurn", 40012}, + {"OpStart", 40013}, + {"OpPause", 40014}, + {"OpStop", 40015}, + {"Default", 40016}, + {"DefaultLeve1", 40017}, + {"Level1", 40018}, + {"Level2", 40019}, + {"Level3", 40020}, + {"Level4", 40021}, + {"Level5", 40022}, + {"Level6", 40023}, + {"Level7", 40024}, + {"Level8", 40025}, + {"Level9", 40026}, + {"Level10", 40027}, + {"TimerEnding", 40028}, + {"BurnerDetected", 40029}, + {"BurnerMoved", 40030}, + {"Connected", 40031}, + {"Disconnected", 40032}, }; /// From 32ce2253b62b1561793ad56f1850ce5a9f348f55 Mon Sep 17 00:00:00 2001 From: Yunhee Seo Date: Fri, 15 Sep 2023 10:47:50 +0900 Subject: [PATCH 17/82] [System.Feedback] Add internal API to support feedback stop by feedback type Allows feedback stop according to feedback type. This is newly added to System.Feedback. - public void StopTypeInternal(FeedbackType type) -> It stops current feedback playing according to feedback type. Signed-off-by: Yunhee Seo --- .../Feedback/Feedback.cs | 47 +++++++++++++++++++ .../Interop/Interop.Feedback.cs | 3 ++ 2 files changed, 50 insertions(+) diff --git a/src/Tizen.System.Feedback/Feedback/Feedback.cs b/src/Tizen.System.Feedback/Feedback/Feedback.cs index 7346798e909..4888ed5471e 100755 --- a/src/Tizen.System.Feedback/Feedback/Feedback.cs +++ b/src/Tizen.System.Feedback/Feedback/Feedback.cs @@ -496,5 +496,52 @@ public void SetThemeIndexInternal(FeedbackType type, uint indexOfTheme) } } } + + /// + /// Stops the current feedback playing by feedback type + /// + /// + /// To stop vibration, the application should have http://tizen.org/privilege/haptic privilege. + /// + /// 10 + /// The feedback type. + /// Thrown when failed because the feedback is not initialized. + /// Thrown when failed because of an invalid argument + /// Thrown when failed because the device (haptic, sound) or a specific pattern is not supported. + /// Thrown when failed because the access is not granted (No privilege). + /// Thrown when failed because of a system error. + /// + /// + /// Feedback Feedback = new Feedback(); + /// feedback.StopTypeInternal(FeedbackType.Sound); + /// feedback.StopTypeInternal(FeedbackType.Vibration); + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void StopTypeInternal(FeedbackType type) + { + Interop.Feedback.FeedbackError res; + + res = (Interop.Feedback.FeedbackError)Interop.Feedback.StopTypeInternal((Interop.Feedback.FeedbackType)type); + + if (res != Interop.Feedback.FeedbackError.None) + { + Log.Warn(LogTag, string.Format("Failed to Stop feedback by feedback type internal. err = {0}", res)); + switch (res) + { + case Interop.Feedback.FeedbackError.NotInitialized: + throw new Exception("Not initialized"); + case Interop.Feedback.FeedbackError.InvalidParameter: + throw new ArgumentException("Invalid Arguments"); + case Interop.Feedback.FeedbackError.NotSupported: + throw new NotSupportedException("Not supported"); + case Interop.Feedback.FeedbackError.PermissionDenied: + throw new UnauthorizedAccessException("Access is not granted"); + case Interop.Feedback.FeedbackError.OperationFailed: + default: + throw new InvalidOperationException("Failed to stop pattern by feedback type"); + } + } + } } } diff --git a/src/Tizen.System.Feedback/Interop/Interop.Feedback.cs b/src/Tizen.System.Feedback/Interop/Interop.Feedback.cs index 359f9b296c2..4cc34fd52b1 100644 --- a/src/Tizen.System.Feedback/Interop/Interop.Feedback.cs +++ b/src/Tizen.System.Feedback/Interop/Interop.Feedback.cs @@ -64,5 +64,8 @@ internal enum FeedbackType [DllImport(Libraries.Feedback, EntryPoint = "feedback_set_theme_index_internal")] internal static extern int SetThemeIndexInternal(FeedbackType type, uint indexOfTheme); + + [DllImport(Libraries.Feedback, EntryPoint = "feedback_stop_type_internal")] + internal static extern int StopTypeInternal(FeedbackType type); } } From 21b2c1e6b35839c6b3f17fa813c85e61acb07512 Mon Sep 17 00:00:00 2001 From: Yunhee Seo Date: Thu, 14 Sep 2023 17:07:49 +0900 Subject: [PATCH 18/82] [System.Feedback] Add new feedback_pattern to support general feedback patterns To support general feedback patterns, newly patterns are added. With these string pattern, it is possible to use mapped feedback patterns from libfeedback. Signed-off-by: Yunhee Seo --- .../Feedback/Feedback.cs | 185 +++++++++++++++++- 1 file changed, 184 insertions(+), 1 deletion(-) diff --git a/src/Tizen.System.Feedback/Feedback/Feedback.cs b/src/Tizen.System.Feedback/Feedback/Feedback.cs index 4888ed5471e..306a80dea8a 100755 --- a/src/Tizen.System.Feedback/Feedback/Feedback.cs +++ b/src/Tizen.System.Feedback/Feedback/Feedback.cs @@ -85,6 +85,10 @@ public class Feedback { {"Tap", 0}, {"SoftInputPanel", 1}, + {"SipBackspace", 2}, + {"SipFunction", 3}, + {"SipFjkey", 4}, + {"MaxCharacter", 5}, {"Key0", 6}, {"Key1", 7}, {"Key2", 8}, @@ -99,29 +103,208 @@ public class Feedback {"KeySharp", 17}, {"KeyBack", 18}, {"Hold", 19}, + {"MultiTap", 20}, {"HardwareKeyPressed", 21}, {"HardwareKeyHold", 22}, {"Message", 23}, + {"MessageOnCall", 24}, {"Email", 25}, + {"EmailOnCall", 26}, {"WakeUp", 27}, + {"WakeUpOnCall", 28}, {"Schedule", 29}, + {"ScheduleOnCall", 30}, {"Timer", 31}, + {"TimerOnCall", 32}, {"General", 33}, + {"GeneralOnCall", 34}, + {"SmartAlert", 35}, {"PowerOn", 36}, {"PowerOff", 37}, {"ChargerConnected", 38}, + {"ChargerconnOnCall", 39}, {"ChargingError", 40}, + {"ChargingErrorOnCall", 41}, {"FullyCharged", 42}, + {"FullchargedOnCall", 43}, {"LowBattery", 44}, + {"LowBattOnCall", 45}, {"Lock", 46}, {"UnLock", 47}, + {"GeometricLock", 50}, + {"Callconnect", 51}, + {"Discallconnect", 52}, + {"OutgoingCall", 53}, + {"Minuteminder", 54}, {"VibrationModeAbled", 55}, {"SilentModeDisabled", 56}, {"BluetoothDeviceConnected", 57}, {"BluetoothDeviceDisconnected", 58}, + {"BtPairing", 59}, + {"BtWaiting", 60}, + {"ScreenCapture", 61}, {"ListReorder", 62}, {"ListSlider", 63}, {"VolumeKeyPressed", 64}, + {"UvProcessing", 95}, + {"ShealthStart", 96}, + {"ShealthPause", 97}, + {"ShealthStop", 98}, + {"3rdApplication", 99}, + {"Tick", 100}, + {"TransitionCircular", 101}, + {"TransitionPop", 102}, + {"Process", 103}, + {"MoveList", 104}, + {"Dismiss", 105}, + {"ClockSecondHand", 106}, + {"SystemShort", 107}, + {"SystemError", 108}, + {"SpiralDown", 109}, + {"MoveList2", 110}, + {"SpiralUp", 111}, + {"SystemLong", 112}, + {"SystemMid", 113}, + {"Silence", 114}, + {"InactiveTension", 115}, + {"InactiveFine", 116}, + {"EndEffect", 117}, + {"ShealthNotice", 118}, + {"ShealthGentleAlert", 119}, + {"EndEffectFine", 120}, + {"ClickValue", 121}, + {"ClickFineTrain1", 122}, + {"ClickFine", 123}, + {"ClickSlider", 124}, + {"ClickMedium", 125}, + {"ClickStrong", 126}, + {"TurnRight", 127}, + {"TurnLeft", 128}, + {"Function", 129}, + {"VoiceStart", 130}, + {"VoiceStop", 131}, + {"Communication", 132}, + {"MessageStrongBuzz", 133}, + {"EmailStrongBuzz", 134}, + {"GeneralStrongBuzz", 135}, + {"CommunicationStrongBuzz", 136}, + {"ScheduleStrongBuzz", 137}, + {"WakeupStrongBuzz", 138}, + {"TimerStrongBuzz", 139}, + {"RingerStrongBuzz", 140}, + {"Heartbeat", 141}, + {"HeartbeatFast", 142}, + {"SettingOn", 143}, + {"SettingOff", 144}, + {"Connect", 145}, + {"Disconnect", 146}, + {"FindMyGear", 147}, + {"Notification1", 148}, + {"Notification1StrongBuzz", 149}, + {"Notification2", 150}, + {"Notification2StrongBuzz", 151}, + {"Notification3", 152}, + {"Notification3StrongBuzz", 153}, + {"Notification4", 154}, + {"Notification4StrongBuzz", 155}, + {"Notification5", 156}, + {"Notification5StrongBuzz", 157}, + {"Notification6", 158}, + {"Notification6StrongBuzz", 159}, + {"Notification7", 160}, + {"Notification7StrongBuzz", 161}, + {"Notification8", 162}, + {"Notification8StrongBuzz", 163}, + {"Notification9", 164}, + {"Notification9StrongBuzz", 165}, + {"Notification10", 166}, + {"Notification10StrongBuzz", 167}, + {"Ring1", 168}, + {"Ring1StrongBuzz", 169}, + {"Ring2", 170}, + {"Ring2StrongBuzz", 171}, + {"Ring3", 172}, + {"Ring3StrongBuzz", 173}, + {"Ring4", 174}, + {"Ring4StrongBuzz", 175}, + {"Ring5", 176}, + {"Ring5StrongBuzz", 177}, + {"Ring6", 178}, + {"Ring6StrongBuzz", 179}, + {"Ring7", 180}, + {"Ring7StrongBuzz", 181}, + {"Ring8", 182}, + {"Ring8StrongBuzz", 183}, + {"Ring9", 184}, + {"Ring9StrongBuzz", 185}, + {"Ring10", 186}, + {"Ring10StrongBuzz", 187}, + {"Alarm1", 188}, + {"Alarm1StrongBuzz", 189}, + {"Alarm2", 190}, + {"Alarm2StrongBuzz", 191}, + {"Alarm3", 192}, + {"Alarm3StrongBuzz", 193}, + {"Alarm4", 194}, + {"Alarm4StrongBuzz", 195}, + {"Alarm5", 196}, + {"Alarm5StrongBuzz", 197}, + {"Alarm6", 198}, + {"Alarm6StrongBuzz", 199}, + {"Alarm7", 200}, + {"Alarm7StrongBuzz", 201}, + {"Alarm8", 202}, + {"Alarm8StrongBuzz", 203}, + {"Alarm9", 204}, + {"Alarm9StrongBuzz", 205}, + {"Alarm10", 206}, + {"Alarm10StrongBuzz", 207}, + {"Picker", 208}, + {"PickerFinish", 209}, + {"OnOffSwitch", 210}, + {"Reorder", 211}, + {"CursorMove", 212}, + {"Mms", 10000}, + {"HourlyAlert", 10001}, + {"SafetyAlert", 10002}, + {"AccidentDetect", 10003}, + {"SendSosMessage", 10004}, + {"EndSosMessage", 10005}, + {"EmergencyBuzzer", 10006}, + {"SafetyLowPower", 10007}, + {"Cmas", 10008}, + {"Ringer", 10009}, + {"Notification", 10010}, + {"Info", 10011}, + {"Warning", 10012}, + {"Error", 10013}, + {"Emergency", 10014}, + {"InternalWakeup", 10015}, + {"InternalTimer", 10016}, + {"TemperatureWarning", 10017}, + {"CooldownWarning1", 10018}, + {"CooldownWarning2", 10019}, + {"SpeedUp", 10020}, + {"SlowDown", 10021}, + {"KeepThisPace", 10022}, + {"GoalAchieved", 10023}, + {"ExerciseCount", 10024}, + {"StartCue", 10025}, + {"HealthPace", 10026}, + {"InactiveTime", 10027}, + {"CmasCa", 10028}, + {"NfcSuccess", 10029}, + {"MeasuringSuccess", 10030}, + {"MeasuringFailure", 10031}, + {"Meditation", 10032}, + {"MeditationInternal", 10033}, + {"FallDetection1", 10034}, + {"FallDetection2", 10035}, + {"SmartGesture", 10036}, + {"BreathingExhale", 12000}, + {"Bos", 12001}, + {"Eos", 12002}, + {"Uds", 12003}, {"Basic", 40001}, {"ToggleOn", 40002}, {"ToggleOff", 40003}, @@ -138,7 +321,7 @@ public class Feedback {"OpPause", 40014}, {"OpStop", 40015}, {"Default", 40016}, - {"DefaultLeve1", 40017}, + {"DefaultLevel1", 40017}, {"Level1", 40018}, {"Level2", 40019}, {"Level3", 40020}, From 8d79376153aed45a26351b5e004df8da335111e8 Mon Sep 17 00:00:00 2001 From: Taehyub Kim Date: Fri, 15 Sep 2023 13:25:05 +0900 Subject: [PATCH 19/82] [NUI] DragAndDrop : Add APIs for Window --- .../internal/Interop/Interop.DragAndDrop.cs | 12 ++- .../src/public/DragAndDrop/DragAndDrop.cs | 80 ++++++++++++++++++- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs b/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs index 4d498b084e6..1acf55699be 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2022 Samsung Electronics Co., Ltd. + * Copyright(c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,11 +36,21 @@ internal enum DragType public static extern bool StartDragAndDrop(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef sourceView, global::System.Runtime.InteropServices.HandleRef shadow, string mimeType, string data, global::System.Runtime.InteropServices.HandleRef callback); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_AddListener")] + [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] public static extern bool AddListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetView, global::System.Runtime.InteropServices.HandleRef callback); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_RemoveListener")] + [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] public static extern bool RemoveListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetView, global::System.Runtime.InteropServices.HandleRef callback); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_Window_AddListener")] + [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] + public static extern bool WindowAddListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetWindow, global::System.Runtime.InteropServices.HandleRef callback); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_Window_RemoveListener")] + [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] + public static extern bool WindowRemoveListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetWindow, global::System.Runtime.InteropServices.HandleRef callback); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragEvent_GetAction")] public static extern int GetAction(global::System.IntPtr dragAndDrop); diff --git a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs index 0a2601cd34b..c60558ef278 100755 --- a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs +++ b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2022 Samsung Electronics Co., Ltd. + * Copyright(c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,9 +33,11 @@ public class DragAndDrop : BaseHandle public delegate void SourceEventHandler(DragSourceEventType sourceEventType); private delegate void InternalSourceEventHandler(int sourceEventType); public delegate void DragAndDropEventHandler(View targetView, DragEvent dragEvent); + public delegate void DragAndDropWindowEventHandler(Window targetWindow, DragEvent dragEvent); private delegate void InternalDragAndDropEventHandler(global::System.IntPtr dragEvent); private InternalSourceEventHandler sourceEventCb; private Dictionary targetEventDictionary = new Dictionary(); + private Dictionary targetWindowEventDictionary = new Dictionary(); private View mShadowView; private Window mDragWindow; private int shadowWidth; @@ -215,7 +217,7 @@ public void AddListener(View targetView, DragAndDropEventHandler callback) if (!Interop.DragAndDrop.AddListener(SwigCPtr, View.getCPtr(targetView), new global::System.Runtime.InteropServices.HandleRef(this, Marshal.GetFunctionPointerForDelegate(cb)))) { - throw new InvalidOperationException("Fail to AddListener"); + throw new InvalidOperationException("Fail to AddListener for View"); } } @@ -229,7 +231,7 @@ public void RemoveListener(View targetView, DragAndDropEventHandler callback) { if (!targetEventDictionary.ContainsKey(targetView)) { - throw new InvalidOperationException("Fail to RemoveListener"); + throw new InvalidOperationException("Fail to RemoveListener for View"); } InternalDragAndDropEventHandler cb = targetEventDictionary[targetView]; @@ -237,7 +239,77 @@ public void RemoveListener(View targetView, DragAndDropEventHandler callback) if (!Interop.DragAndDrop.RemoveListener(SwigCPtr, View.getCPtr(targetView), new global::System.Runtime.InteropServices.HandleRef(this, Marshal.GetFunctionPointerForDelegate(cb)))) { - throw new InvalidOperationException("Fail to RemoveListener"); + throw new InvalidOperationException("Fail to RemoveListener for View"); + } + } + + /// + /// Adds listener for drop targets + /// + /// The target Window + /// The callback function to get drag event when the drag source enters, moves, leaves and drops on the drop target + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddListener(Window targetWindow, DragAndDropWindowEventHandler callback) + { + InternalDragAndDropEventHandler cb = (dragEvent) => + { + DragType type = (DragType)Interop.DragAndDrop.GetAction(dragEvent); + DragEvent ev = new DragEvent(); + global::System.IntPtr cPtr = Interop.DragAndDrop.GetPosition(dragEvent); + ev.Position = (cPtr == global::System.IntPtr.Zero) ? null : new Position(cPtr, false); + + if (type == DragType.Enter) + { + ev.DragType = type; + callback(targetWindow, ev); + } + else if (type == DragType.Leave) + { + ev.DragType = type; + callback(targetWindow, ev); + } + else if (type == DragType.Move) + { + ev.DragType = type; + callback(targetWindow, ev); + } + else if (type == DragType.Drop) + { + ev.DragType = type; + ev.MimeType = Interop.DragAndDrop.GetMimeType(dragEvent); + ev.Data = Interop.DragAndDrop.GetData(dragEvent); + callback(targetWindow, ev); + } + }; + + targetWindowEventDictionary.Add(targetWindow, cb); + + if (!Interop.DragAndDrop.WindowAddListener(SwigCPtr, Window.getCPtr(targetWindow), + new global::System.Runtime.InteropServices.HandleRef(this, Marshal.GetFunctionPointerForDelegate(cb)))) + { + throw new InvalidOperationException("Fail to AddListener for Window"); + } + } + + /// + /// Removes listener for drop targets + /// + /// The target window + /// The callback function to remove + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveListener(Window targetWindow, DragAndDropWindowEventHandler callback) + { + if (!targetWindowEventDictionary.ContainsKey(targetWindow)) + { + throw new InvalidOperationException("Fail to RemoveListener for Window"); + } + + InternalDragAndDropEventHandler cb = targetWindowEventDictionary[targetWindow]; + targetWindowEventDictionary.Remove(targetWindow); + if (!Interop.DragAndDrop.WindowRemoveListener(SwigCPtr, Window.getCPtr(targetWindow), + new global::System.Runtime.InteropServices.HandleRef(this, Marshal.GetFunctionPointerForDelegate(cb)))) + { + throw new InvalidOperationException("Fail to RemoveListener for Window"); } } } From ad6202777a8d41f0d81dd146ab460dcc0665ff91 Mon Sep 17 00:00:00 2001 From: Seoyeon Kim Date: Mon, 18 Sep 2023 17:41:18 +0900 Subject: [PATCH 20/82] [NUI] Version Update (22244) Signed-off-by: Seoyeon Kim --- packaging/csapi-tizenfx.spec | 2 +- packaging/version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/csapi-tizenfx.spec b/packaging/csapi-tizenfx.spec index 4843a3974b4..500bb1bdafa 100644 --- a/packaging/csapi-tizenfx.spec +++ b/packaging/csapi-tizenfx.spec @@ -1,7 +1,7 @@ # Auto-generated from csapi-tizenfx.spec.in by makespec.sh %define TIZEN_NET_API_VERSION 11 -%define TIZEN_NET_RPM_VERSION 11.0.0.999+nui22243 +%define TIZEN_NET_RPM_VERSION 11.0.0.999+nui22244 %define TIZEN_NET_NUGET_VERSION 11.0.0.99999 %define DOTNET_ASSEMBLY_PATH /usr/share/dotnet.tizen/framework diff --git a/packaging/version.txt b/packaging/version.txt index fb2e7134ab2..f96232e7875 100755 --- a/packaging/version.txt +++ b/packaging/version.txt @@ -6,4 +6,4 @@ RPM_VERSION=11.0.0.999 NUGET_VERSION=11.0.0.99999 # RPM Version Suffix -RPM_VERSION_SUFFIX=nui22243 +RPM_VERSION_SUFFIX=nui22244 From a89de98397425ec13d883b673902e58c90b525ab Mon Sep 17 00:00:00 2001 From: Taehyub Kim Date: Mon, 18 Sep 2023 19:10:28 +0900 Subject: [PATCH 21/82] DragAndDrop : hide window event handler --- src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs index c60558ef278..0e77eb85f8c 100755 --- a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs +++ b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs @@ -33,6 +33,7 @@ public class DragAndDrop : BaseHandle public delegate void SourceEventHandler(DragSourceEventType sourceEventType); private delegate void InternalSourceEventHandler(int sourceEventType); public delegate void DragAndDropEventHandler(View targetView, DragEvent dragEvent); + [EditorBrowsable(EditorBrowsableState.Never)] public delegate void DragAndDropWindowEventHandler(Window targetWindow, DragEvent dragEvent); private delegate void InternalDragAndDropEventHandler(global::System.IntPtr dragEvent); private InternalSourceEventHandler sourceEventCb; From 19de26951d9e06468335a17c7520258a2a5497f9 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 19 Sep 2023 22:43:45 +0900 Subject: [PATCH 22/82] [NUI.Scene3D] Fix MotionData TCT error Fix unmatched function binding Signed-off-by: Eunki, Hong --- .../src/internal/Interop/Interop.MotionIndex.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.MotionIndex.cs b/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.MotionIndex.cs index b0ae286f9e2..78086c3b2e6 100755 --- a/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.MotionIndex.cs +++ b/src/Tizen.NUI.Scene3D/src/internal/Interop/Interop.MotionIndex.cs @@ -95,13 +95,13 @@ internal static partial class MotionIndex [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionPropertyIndex_Assign")] public static extern global::System.IntPtr MotionPropertyIndexAssign(global::System.Runtime.InteropServices.HandleRef motionPropertyIndex, global::System.Runtime.InteropServices.HandleRef sourceMotionPropertyIndex); - [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionTransformIndex_DownCast")] + [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionPropertyIndex_DownCast")] public static extern global::System.IntPtr MotionPropertyIndexDownCast(global::System.Runtime.InteropServices.HandleRef motionPropertyIndex); - [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionTransformIndex_SetTransformType")] + [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionPropertyIndex_SetPropertyId")] public static extern void SetPropertyId(global::System.Runtime.InteropServices.HandleRef motionPropertyIndex, global::System.Runtime.InteropServices.HandleRef propertyKey); - [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionTransformIndex_GetTransformType")] + [global::System.Runtime.InteropServices.DllImport(Libraries.Scene3D, EntryPoint = "CSharp_Dali_MotionPropertyIndex_GetPropertyId")] public static extern global::System.IntPtr GetPropertyId(global::System.Runtime.InteropServices.HandleRef motionPropertyIndex); #endregion From b8a355039daa43057d000733a8793bcafb81d068 Mon Sep 17 00:00:00 2001 From: Junseok Kim Date: Thu, 14 Sep 2023 14:07:47 +0900 Subject: [PATCH 23/82] [NUI.WindowSystem] Introduce the new InputGenerate feature --- .../Interop/Interop.InputGenerator.cs | 89 ++++++ .../src/public/InputGenerator.cs | 290 ++++++++++++++++++ .../Tizen.NUI.WindowSystem.InputGenerator.cs | 98 ++++++ ...zen.NUI.WindowSystem.InputGenerator.csproj | 27 ++ .../Tizen.NUI.WindowSystem.InputGenerator.png | Bin 0 -> 10097 bytes .../tizen-manifest.xml | 16 + .../tizen_dotnet_project.yaml | 9 + 7 files changed, 529 insertions(+) create mode 100644 src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGenerator.cs create mode 100644 src/Tizen.NUI.WindowSystem/src/public/InputGenerator.cs create mode 100644 test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.cs create mode 100644 test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.csproj create mode 100644 test/Tizen.NUI.WindowSystem.InputGenerator/shared/res/Tizen.NUI.WindowSystem.InputGenerator.png create mode 100644 test/Tizen.NUI.WindowSystem.InputGenerator/tizen-manifest.xml create mode 100644 test/Tizen.NUI.WindowSystem.InputGenerator/tizen_dotnet_project.yaml diff --git a/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGenerator.cs b/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGenerator.cs new file mode 100644 index 00000000000..d9bbd03c0fa --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.InputGenerator.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tizen.NUI.WindowSystem +{ + internal static partial class Interop + { + internal static partial class InputGenerator + { + const string lib = "libcapi-ui-efl-util.so.0"; + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_initialize_generator")] + internal static extern IntPtr Init(int devType); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_initialize_generator_with_name")] + internal static extern IntPtr InitWithName(int devType, string devName); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_initialize_generator_with_sync")] + internal static extern IntPtr SyncInit(int devType, string devName); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_deinitialize_generator")] + internal static extern ErrorCode Deinit(IntPtr inputGenHandler); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_generate_key")] + internal static extern ErrorCode GenerateKey(IntPtr inputGenHandler, string keyName, int pressed); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_generate_pointer")] + internal static extern ErrorCode GeneratePointer(IntPtr inputGenHandler, int buttons, int pointerType, int x, int y); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_generate_wheel")] + internal static extern ErrorCode GenerateWheel(IntPtr inputGenHandler, int wheelType, int value); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_generate_touch")] + internal static extern ErrorCode GenerateTouch(IntPtr inputGenHandler, int idx, int touchType, int x, int y); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "efl_util_input_generate_touch_axis")] + internal static extern ErrorCode GenerateTouchAxis(IntPtr inputGenHandler, int idx, int touchType, int x, int y, double radius_x, double radius_y, double pressure, double angle, double palm); + + // Enumeration of input device types. + // The device type may be used overlapped. + internal enum DeviceType + { + None = 0x0, + Touchscreen = (1 << 0), + Keyboard = (1 << 1), + Pointer = (1 << 2), + All = Touchscreen | Keyboard, // Keyboard and Touchscreen + } + + // Enumeration of touch event types + internal enum TouchType + { + None, + Begin, + Update, + End, + } + + // Enumeration of pointer event types + internal enum PointerType + { + Down, + Up, + Move, + } + + // Enumeration of pointer wheel event types + internal enum PointerWheelType + { + Vertical, + Horizontal, + } + + private const int ErrorTzsh = -0x02860000; + + internal enum ErrorCode + { + None = Tizen.Internals.Errors.ErrorCode.None, // Successful + OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, // Out of memory + InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, // Invalid parameter + InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation, // Invalid operation + PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied, // Permission denied + NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported, // NOT supported + NoService = ErrorTzsh | 0x01, // Service does not exist + } + } + } +} diff --git a/src/Tizen.NUI.WindowSystem/src/public/InputGenerator.cs b/src/Tizen.NUI.WindowSystem/src/public/InputGenerator.cs new file mode 100644 index 00000000000..a9ccf0afa24 --- /dev/null +++ b/src/Tizen.NUI.WindowSystem/src/public/InputGenerator.cs @@ -0,0 +1,290 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.ComponentModel; + +namespace Tizen.NUI.WindowSystem +{ + /// + /// Class for the Tizen Input Generator. + /// + /// + /// http://tizen.org/privilege/inputgenerator + /// + /// This class is need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public class InputGenerator : IDisposable + { + private IntPtr _handler; + private bool disposed = false; + private bool isDisposeQueued = false; + + /// + /// Enumeration of input device types. + /// + public enum DeviceType + { + /// + /// None. + /// + None = Interop.InputGenerator.DeviceType.None, + + /// + /// Touchscreen device. + /// + Touchscreen = Interop.InputGenerator.DeviceType.Touchscreen, + + /// + /// Keyboard device. + /// + Keyboard = Interop.InputGenerator.DeviceType.Keyboard, + + /// + /// Pointer device. + /// + Pointer = Interop.InputGenerator.DeviceType.Pointer, + + /// + /// Keyboard and Touchscreen device. + /// + All = Interop.InputGenerator.DeviceType.All, + } + + /// + /// Enumeration of touch event types. + /// + public enum TouchType + { + /// + /// None. + /// + None = Interop.InputGenerator.TouchType.None, + + /// + /// Touch begin. + /// + Begin = Interop.InputGenerator.TouchType.Begin, + + /// + /// Touch move. + /// + Update = Interop.InputGenerator.TouchType.Update, + + /// + /// Touch end. + /// + End = Interop.InputGenerator.TouchType.End, + } + + /// + /// Enumeration of pointer event types. + /// + public enum PointerType + { + /// + /// Pointer down. + /// + Down = Interop.InputGenerator.PointerType.Down, + + /// + /// Pointer up. + /// + Up = Interop.InputGenerator.PointerType.Up, + + /// + /// Pointer move. + /// + Move = Interop.InputGenerator.PointerType.Move, + } + + /// + /// Enumeration of pointer wheel event types. + /// + public enum PointerWheelType + { + /// + /// Vertical wheel. + /// + Vertical = Interop.InputGenerator.PointerWheelType.Vertical, + + /// + /// Horizontal wheel. + /// + Horizontal = Interop.InputGenerator.PointerWheelType.Horizontal, + } + + internal void ErrorCodeThrow(Interop.InputGenerator.ErrorCode error) + { + switch (error) + { + case Interop.InputGenerator.ErrorCode.None : + return; + case Interop.InputGenerator.ErrorCode.OutOfMemory : + throw new Tizen.Applications.Exceptions.OutOfMemoryException("Out of Memory"); + case Interop.InputGenerator.ErrorCode.InvalidParameter : + throw new ArgumentException("Invalid Parameter"); + case Interop.InputGenerator.ErrorCode.PermissionDenied : + throw new Tizen.Applications.Exceptions.PermissionDeniedException("Permission denied"); + case Interop.InputGenerator.ErrorCode.NotSupported : + throw new NotSupportedException("Not Supported"); + case Interop.InputGenerator.ErrorCode.NoService : + throw new InvalidOperationException("No Service"); + default : + throw new InvalidOperationException("Unknown Error"); + } + } + + /// + /// Creates a new InputGenerator. + /// + /// The Device type of the new input generator. + /// Thrown when failed of invalid argument. + /// Thrown when a argument is null. + public InputGenerator(DeviceType devType) + { + if (devType == DeviceType.None) + { + throw new ArgumentException("Invalid device type"); + } + + _handler = Interop.InputGenerator.Init((int)devType); + } + + public InputGenerator(DeviceType devType, string name, bool sync = false) + { + if (devType == DeviceType.None) + { + throw new ArgumentException("Invalid device type"); + } + + if (sync) + _handler = Interop.InputGenerator.SyncInit((int)devType, name); + else + _handler = Interop.InputGenerator.InitWithName((int)devType, name); + } + + /// + /// Destructor. + /// + ~InputGenerator() + { + if (!isDisposeQueued) + { + isDisposeQueued = true; + DisposeQueue.Instance.Add(this); + } + } + + /// + /// Dispose. + /// + public void Dispose() + { + if (isDisposeQueued) + { + Dispose(DisposeTypes.Implicit); + } + else + { + Dispose(DisposeTypes.Explicit); + GC.SuppressFinalize(this); + } + } + + /// + protected virtual void Dispose(DisposeTypes type) + { + if (!disposed) + { + if (_handler != IntPtr.Zero) + { + Interop.InputGenerator.ErrorCode res = Interop.InputGenerator.Deinit(_handler); + ErrorCodeThrow(res); + _handler = IntPtr.Zero; + } + disposed = true; + } + } + + /// + /// Generate given key. + /// + /// The key name to generate. + /// Set the key is pressed or released. + public void GenerateKey(string keyName, int pressed) + { + Interop.InputGenerator.ErrorCode res = Interop.InputGenerator.GenerateKey(_handler, keyName, pressed); + ErrorCodeThrow(res); + } + + /// + /// Generate given pointer. + /// + /// The pointer button to generate. + /// The type of the pointer. + /// X coordinate of the pointer. + /// Y coordinate of the pointer. + public void GeneratePointer(int buttons, PointerType pointerType, int x, int y) + { + Interop.InputGenerator.ErrorCode res = Interop.InputGenerator.GeneratePointer(_handler, buttons, (int)pointerType, x, y); + ErrorCodeThrow(res); + } + + /// + /// Generate given wheel. + /// + /// The wheel type to generate. + /// The value of the wheel. + public void GenerateWheel(PointerWheelType wheelType, int value) + { + Interop.InputGenerator.ErrorCode res = Interop.InputGenerator.GenerateWheel(_handler, (int)wheelType, value); + ErrorCodeThrow(res); + } + + /// + /// Generate given touch. + /// + /// The touch index to generate. + /// The touch type to generate. + /// X coordinate of the touch. + /// Y coordinate of the touch. + public void GenerateTouch(int idx, TouchType touchType, int x, int y) + { + Interop.InputGenerator.ErrorCode res = Interop.InputGenerator.GenerateTouch(_handler, idx, (int) touchType, x, y); + ErrorCodeThrow(res); + } + + /// + /// Generate given touch with axis. + /// + /// The touch index to generate. + /// The touch type to generate. + /// X coordinate of the touch. + /// Y coordinate of the touch. + /// radius_x of the touch. + /// radius_y of the touch. + /// pressure of the touch. + /// angle of the touch. + /// palm of the touch. + public void GenerateTouchAxis(int idx, TouchType touchType, int x, int y, double radius_x, double radius_y, double pressure, double angle, double palm) + { + Interop.InputGenerator.ErrorCode res = Interop.InputGenerator.GenerateTouchAxis(_handler, idx, (int) touchType, x, y, radius_x, radius_y, pressure, angle, palm); + ErrorCodeThrow(res); + } + } +} diff --git a/test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.cs b/test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.cs new file mode 100644 index 00000000000..e61ac3af2bb --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.cs @@ -0,0 +1,98 @@ +/* + * Copyright(c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using Tizen; +using Tizen.NUI; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.WindowSystem; +using System.Collections.Generic; + +namespace Tizen.NUI.WindowSystem +{ + class Program : NUIApplication + { + protected override void OnCreate() + { + base.OnCreate(); + Initialize(); + } + + void Initialize() + { + Window win = Window.Instance; + inputGen = new InputGenerator(InputGenerator.DeviceType.All, null); + + win.WindowSize = new Size2D(500, 500); + win.KeyEvent += OnKeyEvent; + win.BackgroundColor = Color.White; + + View windowView = new View(); + windowView.Size2D = new Size2D(500, 500); + windowView.BackgroundColor = Color.White; + windowView.TouchEvent += OnTouchEvent; + win.Add(windowView); + + centerLabel = new TextLabel("InputGenerator Sample, Click to generate Return Key."); + centerLabel.HorizontalAlignment = HorizontalAlignment.Center; + centerLabel.VerticalAlignment = VerticalAlignment.Center; + centerLabel.TextColor = Color.Black; + centerLabel.PointSize = 12.0f; + centerLabel.HeightResizePolicy = ResizePolicyType.FillToParent; + centerLabel.WidthResizePolicy = ResizePolicyType.FillToParent; + windowView.Add(centerLabel); + + repeatCounter = 0; + } + + private void OnKeyEvent(object sender, Window.KeyEventArgs e) + { + if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "XF86Back" || e.Key.KeyPressedName == "Escape")) + { + Exit(); + } + if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "Return") + { + repeatCounter++; + centerLabel.Text = "Return Key Pressed, counter: " + repeatCounter.ToString(); + } + } + + private bool OnTouchEvent(object sender, View.TouchEventArgs e) + { + if (e.Touch.GetState(0) == PointStateType.Down) + { + inputGen.GenerateKey("Return", 1); + inputGen.GenerateKey("Return", 0); + + return true; + } + + return false; + } + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } + + private InputGenerator inputGen; + private TextLabel centerLabel; + int repeatCounter = 0; + } +} diff --git a/test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.csproj b/test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.csproj new file mode 100644 index 00000000000..b0bb521cc41 --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGenerator/Tizen.NUI.WindowSystem.InputGenerator.csproj @@ -0,0 +1,27 @@ + + + + Exe + net6.0 + + + + portable + + + None + + + + + + + + + + + + True + + + diff --git a/test/Tizen.NUI.WindowSystem.InputGenerator/shared/res/Tizen.NUI.WindowSystem.InputGenerator.png b/test/Tizen.NUI.WindowSystem.InputGenerator/shared/res/Tizen.NUI.WindowSystem.InputGenerator.png new file mode 100644 index 0000000000000000000000000000000000000000..9f3cb98608134e7b9eb4beb7394fec9f03e40f63 GIT binary patch literal 10097 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 TJbOA100000NkvXXu0mjf?x(Kf literal 0 HcmV?d00001 diff --git a/test/Tizen.NUI.WindowSystem.InputGenerator/tizen-manifest.xml b/test/Tizen.NUI.WindowSystem.InputGenerator/tizen-manifest.xml new file mode 100644 index 00000000000..b9b9b08bed8 --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGenerator/tizen-manifest.xml @@ -0,0 +1,16 @@ + + + + + + Tizen.NUI.WindowSystem.InputGenerator.png + + + diff --git a/test/Tizen.NUI.WindowSystem.InputGenerator/tizen_dotnet_project.yaml b/test/Tizen.NUI.WindowSystem.InputGenerator/tizen_dotnet_project.yaml new file mode 100644 index 00000000000..01c7a15174b --- /dev/null +++ b/test/Tizen.NUI.WindowSystem.InputGenerator/tizen_dotnet_project.yaml @@ -0,0 +1,9 @@ +# csproj file path +csproj_file: Tizen.NUI.WindowSystem.InputGenerator.csproj + +# files monitored for dirty/modified status +files: + - Tizen.NUI.WindowSystem.InputGenerator.csproj + - Tizen.NUI.WindowSystem.InputGenerator.cs + - tizen-manifest.xml + - shared/res/Tizen.NUI.WindowSystem.InputGenerator.png \ No newline at end of file From 7807a093bfe6feeb02ce05c354c97ba7e90b2c0d Mon Sep 17 00:00:00 2001 From: Junseok Kim Date: Wed, 30 Aug 2023 16:23:02 +0900 Subject: [PATCH 24/82] [NUI.WindowSystem] Add new request of KVM Service Add new request of KVM Service as below: - ReceiveDragData: Request to get current drag data. - CancelDrag: Request to cancel current drag. --- .../internal/Interop/Interop.KVMService.cs | 6 ++++++ .../src/public/KVMService.cs | 21 +++++++++++++++++++ test/NUIWindowKVMSample/NUIWindowKVMSample.cs | 18 ++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.KVMService.cs b/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.KVMService.cs index 52ee625b431..4fc52fdd9c4 100644 --- a/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.KVMService.cs +++ b/src/Tizen.NUI.WindowSystem/src/internal/Interop/Interop.KVMService.cs @@ -19,6 +19,12 @@ internal static partial class KVMService [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "tzsh_kvm_service_perform_drop")] internal static extern int PerformDrop(IntPtr kvmService); + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "tzsh_kvm_service_cancel_drag")] + internal static extern int CancelDrag(IntPtr kvmService); + + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "tzsh_kvm_service_receive_drag_data")] + internal static extern int ReceiveDragData(IntPtr kvmService, string mimeType); + [global::System.Runtime.InteropServices.DllImport(lib, EntryPoint = "tzsh_kvm_service_secondary_selection_set")] internal static extern int SetSecondarySelection(IntPtr kvmService); diff --git a/src/Tizen.NUI.WindowSystem/src/public/KVMService.cs b/src/Tizen.NUI.WindowSystem/src/public/KVMService.cs index febc47350e9..78f8ac4bca2 100644 --- a/src/Tizen.NUI.WindowSystem/src/public/KVMService.cs +++ b/src/Tizen.NUI.WindowSystem/src/public/KVMService.cs @@ -187,6 +187,27 @@ public void PerformDrop() _tzsh.ErrorCodeThrow(res); } + /// + /// Requests to cancel current drag. + /// + /// Thrown when failed of invalid argument. + public void CancelDrag() + { + int res = Interop.KVMService.CancelDrag(_kvmService); + _tzsh.ErrorCodeThrow(res); + } + + /// + /// Requests to receive the current drag data. + /// the drag data will be received by the DragEvent of the window. + /// + /// Thrown when failed of invalid argument. + public void ReceiveDragData(string mimeType) + { + int res = Interop.KVMService.ReceiveDragData(_kvmService, mimeType); + _tzsh.ErrorCodeThrow(res); + } + /// /// Requests to set KVM window as secondary selection window. /// diff --git a/test/NUIWindowKVMSample/NUIWindowKVMSample.cs b/test/NUIWindowKVMSample/NUIWindowKVMSample.cs index 3fcc072f94c..0c266d39d7e 100644 --- a/test/NUIWindowKVMSample/NUIWindowKVMSample.cs +++ b/test/NUIWindowKVMSample/NUIWindowKVMSample.cs @@ -112,7 +112,9 @@ public KVMServiceWindow(Rectangle winGeometry) : windowView.BackgroundColor = Color.Yellow; this.Add(windowView); - dnd.AddListener(windowView, OnDnDEvent); + // The First argument of listener should be window, not view. + // The listener of view couldn't catch receive data from ReceiveDragData of KVMService + dnd.AddListener(this, OnDnDEvent); tzShell = new Tizen.NUI.WindowSystem.Shell.TizenShell(); kvmService = new Tizen.NUI.WindowSystem.Shell.KVMService(tzShell, this); @@ -126,7 +128,15 @@ private void OnDnDEvent(object sender, DragEvent e) if (e.DragType == DragType.Enter) { Log.Debug("KVMSample", "Target(KVM) App DRagEvnetType: Enter"); - kvmService.PerformDrop(); + // PerformDrop is drop into the KVM window and finish the current drag. + // If you want to get the current drag data without end the drag, + // use ReceiveDragData(mimetype) instead of PerformDrop(). + //kvmService.PerformDrop(); + + // The drag data will be received by ReceiveDragData of OnDragStarted callback and DragEvent of the OnDnDEvent callback. + // and the drag will be ended by enter the KVM window as UX of the app. + // If you want to end the drag without receive drag data, use CancelDrag(). + kvmService.CancelDrag(); } if (e.DragType == DragType.Drop) { @@ -137,6 +147,10 @@ private void OnDnDEvent(object sender, DragEvent e) private void OnDragStarted(object sender, EventArgs e) { Log.Debug("KVMSample", "Tizen KVM: Drag started"); + + // Request the drag data to the Display server. + // The drag data can get at DnD Listener (OnDnDEvent function) + kvmService.ReceiveDragData("text/plain"); } private void OnDragEnded(object sender, EventArgs e) From b0c2ef1d772086da2e037f921bc48954978dca21 Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Wed, 20 Sep 2023 17:10:21 +0900 Subject: [PATCH 25/82] [NUI] bug fixed about windowPointerConstraintsEventCallback --- src/Tizen.NUI/src/public/Window/WindowEvent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tizen.NUI/src/public/Window/WindowEvent.cs b/src/Tizen.NUI/src/public/Window/WindowEvent.cs index b278409e347..9036e535102 100755 --- a/src/Tizen.NUI/src/public/Window/WindowEvent.cs +++ b/src/Tizen.NUI/src/public/Window/WindowEvent.cs @@ -630,7 +630,7 @@ public event EventHandler PointerConstraintsEvent if (windowPointerConstraintsEventHandler == null && windowPointerConstraintsEventCallback != null) { using WindowPointerConstraintsSignal signal = new WindowPointerConstraintsSignal(Interop.WindowPointerConstraintsSignal.GetSignal(SwigCPtr), false); - signal?.Disconnect(windowMouseRelativeEventCallback); + signal?.Disconnect(windowPointerConstraintsEventCallback); windowPointerConstraintsEventCallback = null; } } From 65aa1eddd9787d8a3566acea0c5e02cf97256152 Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Mon, 28 Aug 2023 15:10:16 +0900 Subject: [PATCH 26/82] [NUI] Add HoverEvent in Window Window window = NUIApplication.GetDefaultWindow(); window.HoverEvent += OnHover; private void OnHover(object source, Window.HoverEventArgs e) { // e.Hover.GetState(0); // PointStateType.Motion; } --- .../src/public/Window/WindowEvent.cs | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/Tizen.NUI/src/public/Window/WindowEvent.cs b/src/Tizen.NUI/src/public/Window/WindowEvent.cs index 9036e535102..72d091ff2a1 100755 --- a/src/Tizen.NUI/src/public/Window/WindowEvent.cs +++ b/src/Tizen.NUI/src/public/Window/WindowEvent.cs @@ -57,6 +57,7 @@ public partial class Window private ResizeCompletedEventCallbackType resizeCompletedEventCallback; private InsetsChangedEventCallbackType insetsChangedEventCallback; private WindowPointerConstraintsEventCallback windowPointerConstraintsEventCallback; + private RootLayerHoverDataCallbackType rootLayerHoverDataCallback; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void WindowFocusChangedEventCallbackType(IntPtr window, bool focusGained); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] @@ -91,6 +92,8 @@ public partial class Window private delegate void InsetsChangedEventCallbackType(int partType, int partState, IntPtr extents); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void WindowPointerConstraintsEventCallback(IntPtr window, IntPtr constraintsEvent); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate bool RootLayerHoverDataCallbackType(IntPtr view, IntPtr hoverData); /// @@ -152,6 +155,7 @@ public event EventHandler TouchEvent } } + /// /// An event for the touched signal which can be used to subscribe or unsubscribe the event handler provided by the user.
/// The touched signal is emitted when the touch input is received.
@@ -344,6 +348,35 @@ public event EventHandler Resized } } + /// + /// An event for the hovered signal which can be used to subscribe or unsubscribe the event handler provided by the user.
+ /// The hovered signal is emitted when the hover input is received.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler HoverEvent + { + add + { + if (rootLayerHoverDataEventHandler == null) + { + rootLayerHoverDataCallback = OnWindowHover; + Interop.ActorSignal.HoveredConnect(Layer.getCPtr(GetRootLayer()), rootLayerHoverDataCallback.ToHandleRef(this)); + NDalicPINVOKE.ThrowExceptionIfExists(); + } + rootLayerHoverDataEventHandler += value; + } + remove + { + rootLayerHoverDataEventHandler -= value; + if (rootLayerHoverDataEventHandler == null && rootLayerHoverDataCallback != null) + { + Interop.ActorSignal.HoveredDisconnect(Layer.getCPtr(GetRootLayer()), rootLayerHoverDataCallback.ToHandleRef(this)); + NDalicPINVOKE.ThrowExceptionIfExists(); + rootLayerHoverDataCallback = null; + } + } + } + /// /// Do not use this, that will be deprecated. Use 'FocusChanged' event instead. /// @@ -657,6 +690,7 @@ public event EventHandler PointerConstraintsEvent private event EventHandler resizeCompletedHandler; private event EventHandler insetsChangedEventHandler; private event EventHandler windowPointerConstraintsEventHandler; + private event EventHandler rootLayerHoverDataEventHandler; internal event EventHandler EventProcessingFinished @@ -955,6 +989,13 @@ internal void DisconnectNativeSignals() signal?.Disconnect(windowPointerConstraintsEventCallback); windowPointerConstraintsEventCallback = null; } + + if (rootLayerHoverDataCallback != null) + { + Interop.ActorSignal.HoveredDisconnect(Layer.getCPtr(GetRootLayer()), rootLayerHoverDataCallback.ToHandleRef(this)); + NDalicPINVOKE.ThrowExceptionIfExists(); + rootLayerHoverDataCallback = null; + } } private void OnWindowFocusedChanged(IntPtr window, bool focusGained) @@ -1265,6 +1306,23 @@ private void OnWindowPointerConstraintsEvent(IntPtr view, IntPtr constraintsEven } } + private bool OnWindowHover(IntPtr view, IntPtr hoverData) + { + if (hoverData == global::System.IntPtr.Zero) + { + NUILog.Error("hoverData should not be null!"); + return false; + } + + if (rootLayerHoverDataEventHandler != null) + { + HoverEventArgs e = new HoverEventArgs(); + e.Hover = Tizen.NUI.Hover.GetHoverFromPtr(hoverData); + rootLayerHoverDataEventHandler(this, e); + } + return false; + } + /// /// The focus changed event argument. /// @@ -1459,6 +1517,31 @@ public PointerConstraints PointerConstraints } } + /// + /// Event arguments that passed via the hover signal. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public class HoverEventArgs : EventArgs + { + private Hover hover; + + /// + /// Hover - contains touch points that represent the points that are currently being hovered or the points where a hover has stopped. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Hover Hover + { + get + { + return hover; + } + set + { + hover = value; + } + } + } + /// /// Do not use this, that will be deprecated. /// From 7c25a740f0256551436f6878bc626cb682d990c1 Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Thu, 21 Sep 2023 15:25:39 +0900 Subject: [PATCH 27/82] [NUI] Binding DispatchTouchMotion and DispatchHoverMotion These determine whether to send touch and hover motion events or not. This is used when the user does not want to receive motion events. --- .../internal/Interop/Interop.ActorProperty.cs | 6 +++ .../BaseComponents/ViewBindableProperty.cs | 36 +++++++++++++ .../src/public/BaseComponents/ViewEnum.cs | 2 + .../src/public/BaseComponents/ViewEvent.cs | 54 ++++++++++--------- .../src/public/Window/WindowEvent.cs | 36 +++++++++++++ 5 files changed, 109 insertions(+), 25 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ActorProperty.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ActorProperty.cs index 96b89c203e2..1491d1a9169 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.ActorProperty.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ActorProperty.cs @@ -221,6 +221,12 @@ internal static partial class ActorProperty [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Actor_Property_UPDATE_AREA_HINT_get")] public static extern int UpdateAreaHintGet(); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Actor_Property_DISPATCH_TOUCH_MOTION_get")] + public static extern int DispatchTouchMotionGet(); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Actor_Property_DISPATCH_HOVER_MOTION_get")] + public static extern int DispatchHoverMotionGet(); } } } diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs index 708ae8e6750..6afade18e13 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs @@ -2582,6 +2582,42 @@ public partial class View return instance.InternalTouchAreaOffset; }); + /// + /// DispatchTouchMotionProperty + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly BindableProperty DispatchTouchMotionProperty = BindableProperty.Create(nameof(DispatchTouchMotion), typeof(bool), typeof(View), false, propertyChanged: (bindable, oldValue, newValue) => + { + var instance = (Tizen.NUI.BaseComponents.View)bindable; + if (newValue != null) + { + instance.InternalDispatchTouchMotion = (bool)newValue; + } + }, + defaultValueCreator: (bindable) => + { + var instance = (Tizen.NUI.BaseComponents.View)bindable; + return instance.InternalDispatchTouchMotion; + }); + + /// + /// DispatchHoverMotionProperty + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly BindableProperty DispatchHoverMotionProperty = BindableProperty.Create(nameof(DispatchHoverMotion), typeof(bool), typeof(View), false, propertyChanged: (bindable, oldValue, newValue) => + { + var instance = (Tizen.NUI.BaseComponents.View)bindable; + if (newValue != null) + { + instance.InternalDispatchHoverMotion = (bool)newValue; + } + }, + defaultValueCreator: (bindable) => + { + var instance = (Tizen.NUI.BaseComponents.View)bindable; + return instance.InternalDispatchHoverMotion; + }); + /// /// Gets View's Size2D set by user. /// diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs index 639bd542523..c7bc20d6663 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewEnum.cs @@ -264,6 +264,8 @@ internal class Property internal static readonly int AccessibilityHidden = Interop.ViewProperty.AccessibilityHiddenGet(); internal static readonly int AutomationId = Interop.ViewProperty.AutomationIdGet(); internal static readonly int UpdateAreaHint = Interop.ActorProperty.UpdateAreaHintGet(); + internal static readonly int DispatchTouchMotion = Interop.ActorProperty.DispatchTouchMotionGet(); + internal static readonly int DispatchHoverMotion = Interop.ActorProperty.DispatchHoverMotionGet(); } } } diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewEvent.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewEvent.cs index f7951915372..702e81d7ea9 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewEvent.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewEvent.cs @@ -104,8 +104,6 @@ public partial class View private bool dispatchParentHoverEvents = true; private bool dispatchGestureEvents = true; private bool dispatchParentGestureEvents = true; - private bool dispatchTouchMotion = true; - private bool dispatchHoverMotion = true; /// @@ -842,12 +840,6 @@ private bool OnInterceptTouch(IntPtr view, IntPtr touchData) TouchEventArgs e = new TouchEventArgs(); e.Touch = Tizen.NUI.Touch.GetTouchFromPtr(touchData); - // If DispatchTouchMotion is false, Motion event is not dispatched. - if (DispatchTouchMotion == false && e.Touch.GetState(0) == PointStateType.Motion) - { - return true; - } - bool consumed = false; if (interceptTouchDataEventHandler != null) @@ -876,13 +868,6 @@ private bool OnTouch(IntPtr view, IntPtr touchData) TouchEventArgs e = new TouchEventArgs(); e.Touch = Tizen.NUI.Touch.GetTouchFromPtr(touchData); - // If DispatchTouchMotion is false, Motion event is not dispatched. - if (DispatchTouchMotion == false && e.Touch.GetState(0) == PointStateType.Motion) - { - return true; - } - - bool consumed = false; if (touchDataEventHandler != null) @@ -922,12 +907,6 @@ private bool OnHoverEvent(IntPtr view, IntPtr hoverEvent) HoverEventArgs e = new HoverEventArgs(); e.Hover = Tizen.NUI.Hover.GetHoverFromPtr(hoverEvent); - // If DispatchHoverMotion is false, Motion event is not dispatched. - if (DispatchHoverMotion == false && e.Hover.GetState(0) == PointStateType.Motion) - { - return true; - } - bool consumed = false; if (hoverEventHandler != null) @@ -1677,11 +1656,24 @@ public bool DispatchTouchMotion { get { - return dispatchTouchMotion; + return (bool)GetValue(DispatchTouchMotionProperty); + } + set + { + SetValue(DispatchTouchMotionProperty, value); + } + } + + private bool InternalDispatchTouchMotion + { + get + { + return Object.InternalGetPropertyBool(SwigCPtr, View.Property.DispatchTouchMotion); } set { - dispatchTouchMotion = value; + Object.InternalSetPropertyBool(SwigCPtr, View.Property.DispatchTouchMotion, value); + NotifyPropertyChanged(); } } @@ -1694,13 +1686,25 @@ public bool DispatchHoverMotion { get { - return dispatchHoverMotion; + return (bool)GetValue(DispatchHoverMotionProperty); } set { - dispatchHoverMotion = value; + SetValue(DispatchHoverMotionProperty, value); } } + private bool InternalDispatchHoverMotion + { + get + { + return Object.InternalGetPropertyBool(SwigCPtr, View.Property.DispatchHoverMotion); + } + set + { + Object.InternalSetPropertyBool(SwigCPtr, View.Property.DispatchHoverMotion, value); + NotifyPropertyChanged(); + } + } } } diff --git a/src/Tizen.NUI/src/public/Window/WindowEvent.cs b/src/Tizen.NUI/src/public/Window/WindowEvent.cs index 72d091ff2a1..36e7b8427f0 100755 --- a/src/Tizen.NUI/src/public/Window/WindowEvent.cs +++ b/src/Tizen.NUI/src/public/Window/WindowEvent.cs @@ -669,6 +669,42 @@ public event EventHandler PointerConstraintsEvent } } + /// + /// Gets or sets the status of whether motion event of Touch can be dispatched. + /// If a Window's DispatchTouchMotion is set to false, then it's can not will receive motion event of TouchEvent. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool DispatchTouchMotion + { + get + { + return Object.InternalGetPropertyBool(Layer.getCPtr(GetRootLayer()), View.Property.DispatchTouchMotion); + } + set + { + Object.InternalSetPropertyBool(Layer.getCPtr(GetRootLayer()), View.Property.DispatchTouchMotion, value); + NotifyPropertyChanged(); + } + } + + /// + /// Gets or sets the status of whether motion event of Hover can be dispatched. + /// If a Window's DispatchHoverMotion is set to false, then it's can not will receive motion event of HoverEvent. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool DispatchHoverMotion + { + get + { + return Object.InternalGetPropertyBool(Layer.getCPtr(GetRootLayer()), View.Property.DispatchHoverMotion); + } + set + { + Object.InternalSetPropertyBool(Layer.getCPtr(GetRootLayer()), View.Property.DispatchHoverMotion, value); + NotifyPropertyChanged(); + } + } + private event EventHandler windowFocusChangedEventHandler; private event EventHandler rootLayerTouchDataEventHandler; private ReturnTypeEventHandler rootLayerInterceptTouchDataEventHandler; From fa38f30d7f66e85c54d9a019f51057a51c8f3e45 Mon Sep 17 00:00:00 2001 From: sunghyun kim Date: Mon, 25 Sep 2023 13:38:06 +0900 Subject: [PATCH 28/82] [NUI] Add widget list for keeping widget instance widget need to keep it's instance --- src/Tizen.NUI/src/public/Widget/Widget.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tizen.NUI/src/public/Widget/Widget.cs b/src/Tizen.NUI/src/public/Widget/Widget.cs index a10d2387d34..ce65cb5cf79 100755 --- a/src/Tizen.NUI/src/public/Widget/Widget.cs +++ b/src/Tizen.NUI/src/public/Widget/Widget.cs @@ -46,6 +46,8 @@ internal Widget(WidgetImpl widgetImpl, bool swigCMemOwn) : this(Interop.Widget.N widgetImpl.WidgetInstanceResumed += OnWidgetInstanceResumed; widgetImpl.WidgetInstanceResized += OnWidgetInstanceResized; widgetImpl.WidgetInstanceUpdated += OnWidgetInstanceUpdated; + + (WidgetApplication.Instance as WidgetApplication)?.AddWidgetInstance(this); } internal Widget(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) From dcfbbf07e02ef5b75c45e544ffbeeb156101ad26 Mon Sep 17 00:00:00 2001 From: seungho baek Date: Mon, 25 Sep 2023 12:16:45 +0900 Subject: [PATCH 29/82] Add VisualFactory.UsePrecompiledShader() Signed-off-by: seungho baek --- .../internal/Interop/Interop.VisualFactory.cs | 3 +++ .../src/public/Visuals/VisualFactory.cs | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.VisualFactory.cs b/src/Tizen.NUI/src/internal/Interop/Interop.VisualFactory.cs index b7262adba84..a9a3a08b019 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.VisualFactory.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.VisualFactory.cs @@ -44,6 +44,9 @@ internal static partial class VisualFactory [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_VisualFactory_CreateVisual__SWIG_2")] public static extern global::System.IntPtr CreateVisual(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, global::System.Runtime.InteropServices.HandleRef jarg3); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_VisualFactory_UsePreCompiledShader")] + public static extern void UsePreCompiledShader(global::System.Runtime.InteropServices.HandleRef jarg1); } } } diff --git a/src/Tizen.NUI/src/public/Visuals/VisualFactory.cs b/src/Tizen.NUI/src/public/Visuals/VisualFactory.cs index 73bbfcece04..ab2a33a102e 100755 --- a/src/Tizen.NUI/src/public/Visuals/VisualFactory.cs +++ b/src/Tizen.NUI/src/public/Visuals/VisualFactory.cs @@ -84,5 +84,22 @@ public VisualBase CreateVisual(PropertyMap propertyMap) if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } + + /// + /// Compile the visual shader in advance. Afterwards, + /// when a visual using a new shader is requested, the pre-compiled shader is used. + /// + /// It is recommended that this method be called at the top of the application code. + /// + /// Using precompiled shaders is helpful when the application is complex and uses + /// many different styles of visual options. On the other hand,if most visuals are the same + /// and the application is simple, it may use memory unnecessarily or slow down the application launching speed. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void UsePreCompiledShader() + { + Interop.VisualFactory.UsePreCompiledShader(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } } } From 0bbde0720920df7959750731dcd827f3f7e3cfe8 Mon Sep 17 00:00:00 2001 From: Jiyun Yang Date: Mon, 25 Sep 2023 15:21:14 +0900 Subject: [PATCH 30/82] [NUI] Version Update (22245) Signed-off-by: Jiyun Yang --- packaging/csapi-tizenfx.spec | 2 +- packaging/version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/csapi-tizenfx.spec b/packaging/csapi-tizenfx.spec index 500bb1bdafa..0cf3614f20d 100644 --- a/packaging/csapi-tizenfx.spec +++ b/packaging/csapi-tizenfx.spec @@ -1,7 +1,7 @@ # Auto-generated from csapi-tizenfx.spec.in by makespec.sh %define TIZEN_NET_API_VERSION 11 -%define TIZEN_NET_RPM_VERSION 11.0.0.999+nui22244 +%define TIZEN_NET_RPM_VERSION 11.0.0.999+nui22245 %define TIZEN_NET_NUGET_VERSION 11.0.0.99999 %define DOTNET_ASSEMBLY_PATH /usr/share/dotnet.tizen/framework diff --git a/packaging/version.txt b/packaging/version.txt index f96232e7875..ab5d5f86eee 100755 --- a/packaging/version.txt +++ b/packaging/version.txt @@ -6,4 +6,4 @@ RPM_VERSION=11.0.0.999 NUGET_VERSION=11.0.0.99999 # RPM Version Suffix -RPM_VERSION_SUFFIX=nui22244 +RPM_VERSION_SUFFIX=nui22245 From 7ebb2120854a98aee9c6bc1ea3c830e0796c977f Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Mon, 25 Sep 2023 14:38:22 +0900 Subject: [PATCH 31/82] [NUI] Do not registry last event items who get retrieved Since we change BaseObject internally when we use Interop.Window.InternalRetrievingLast~~~Event(~~) function. This behaviour might occure some error cases when we use Registry system. Signed-off-by: Eunki, Hong --- src/Tizen.NUI/src/public/Events/Touch.cs | 2 +- src/Tizen.NUI/src/public/Window/Window.cs | 27 ++++++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Tizen.NUI/src/public/Events/Touch.cs b/src/Tizen.NUI/src/public/Events/Touch.cs index cc0111eac40..7fb042090dd 100755 --- a/src/Tizen.NUI/src/public/Events/Touch.cs +++ b/src/Tizen.NUI/src/public/Events/Touch.cs @@ -42,7 +42,7 @@ internal Touch(Touch other) : this(Interop.Touch.NewTouch(Touch.getCPtr(other)), if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Touch(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Touch.Upcast(cPtr), cMemoryOwn) + internal Touch(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) { } diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index 4d14e0ea145..c35c464371c 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -2108,13 +2108,18 @@ public bool IsWindowRotating() /// /// Gets the last key event the window gets. /// + /// + /// We will use weak reference of last key events. + /// Return value will be invalidated if last key event changed internally. + /// /// The last key event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Key GetLastKeyEvent() { - if(internalLastKeyEvent == null) + if (internalLastKeyEvent == null || !internalLastKeyEvent.HasBody()) { - internalLastKeyEvent = new Key(); + // Create empty event handle without register. + internalLastKeyEvent = new Key(Interop.Key.New("", "", 0, 0, 0u, 0), false); } Interop.Window.InternalRetrievingLastKeyEvent(SwigCPtr, internalLastKeyEvent.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -2124,13 +2129,18 @@ public Key GetLastKeyEvent() /// /// Gets the last touch event the window gets. /// + /// + /// We will use weak reference of last touch events. + /// Return value will be invalidated if last touch event changed internally. + /// /// The last touch event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Touch GetLastTouchEvent() { - if(internalLastTouchEvent == null) + if (internalLastTouchEvent == null || !internalLastTouchEvent.HasBody()) { - internalLastTouchEvent = new Touch(); + // Create empty event handle without register. + internalLastTouchEvent = new Touch(Interop.Touch.NewTouch(), false); } Interop.Window.InternalRetrievingLastTouchEvent(SwigCPtr, internalLastTouchEvent.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -2140,13 +2150,18 @@ public Touch GetLastTouchEvent() /// /// Gets the last hover event the window gets. /// + /// + /// We will use weak reference of last hover events. + /// Return value will be invalidated if last hover event changed internally. + /// /// The last hover event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Hover GetLastHoverEvent() { - if(internalLastHoverEvent == null) + if (internalLastHoverEvent == null || !internalLastHoverEvent.HasBody()) { - internalLastHoverEvent = new Hover(); + // Create empty event handle without register. + internalLastHoverEvent = new Hover(Interop.Hover.New(0u), false); } Interop.Window.InternalRetrievingLastHoverEvent(SwigCPtr, internalLastHoverEvent.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); From 9a325ae8685423b8f015e885cb804dd6813a8bea Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Tue, 26 Sep 2023 01:22:41 +0900 Subject: [PATCH 32/82] [NUI] Implement defaut key construct Let we use default key creation API if we only need to use empty key handle. Signed-off-by: Eunki Hong --- src/Tizen.NUI/src/internal/Interop/Interop.Key.cs | 3 +++ src/Tizen.NUI/src/public/Input/Key.cs | 2 +- src/Tizen.NUI/src/public/Window/Window.cs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.Key.cs b/src/Tizen.NUI/src/internal/Interop/Interop.Key.cs index fdce0aa2fea..18a7e6a1c9c 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.Key.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.Key.cs @@ -33,6 +33,9 @@ internal static partial class Key [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Key_New")] public static extern global::System.IntPtr New(string jarg1, string jarg2, int jarg3, int jarg4, uint jarg5, int jarg6); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Key_New__SWIG_1")] + public static extern global::System.IntPtr New(); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Key")] public static extern void DeleteKey(global::System.Runtime.InteropServices.HandleRef jarg1); diff --git a/src/Tizen.NUI/src/public/Input/Key.cs b/src/Tizen.NUI/src/public/Input/Key.cs index c17c2995056..2ce31b9056e 100755 --- a/src/Tizen.NUI/src/public/Input/Key.cs +++ b/src/Tizen.NUI/src/public/Input/Key.cs @@ -30,7 +30,7 @@ public class Key : BaseHandle /// The default constructor. /// /// 3 - public Key() : this(Interop.Key.New("", "", 0, 0, 0u, 0), true) + public Key() : this(Interop.Key.New(), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index c35c464371c..e9e208144f0 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -2119,7 +2119,7 @@ public Key GetLastKeyEvent() if (internalLastKeyEvent == null || !internalLastKeyEvent.HasBody()) { // Create empty event handle without register. - internalLastKeyEvent = new Key(Interop.Key.New("", "", 0, 0, 0u, 0), false); + internalLastKeyEvent = new Key(Interop.Key.New(), false); } Interop.Window.InternalRetrievingLastKeyEvent(SwigCPtr, internalLastKeyEvent.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); From 1316251af41e89d73fd04aafd6e4221d9fb413e0 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 26 Sep 2023 11:51:06 +0900 Subject: [PATCH 33/82] [NUI] Let we don't dispose cached LastEvents Signed-off-by: Eunki, Hong --- src/Tizen.NUI/src/public/Window/Window.cs | 48 +++++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index e9e208144f0..e25d45e8a6b 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -1269,7 +1269,7 @@ internal void FeedHover(TouchPoint touchPoint = null) { if (touchPoint == null) { - using Hover hover = GetLastHoverEvent(); + Hover hover = GetLastHoverEvent(); if (hover == null || hover.GetPointCount() < 1) { return; @@ -2112,12 +2112,20 @@ public bool IsWindowRotating() /// We will use weak reference of last key events. /// Return value will be invalidated if last key event changed internally. /// + /// + /// Do not Dispose this value. + /// /// The last key event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Key GetLastKeyEvent() { - if (internalLastKeyEvent == null || !internalLastKeyEvent.HasBody()) + if (internalLastKeyEvent == null) { + // TODO : We need to make automatically release memory of these cached events in future. + if (!(internalLastKeyEvent?.IsNativeHandleInvalid() ?? true)) + { + Interop.Key.DeleteKey(internalLastKeyEvent.SwigCPtr); + } // Create empty event handle without register. internalLastKeyEvent = new Key(Interop.Key.New(), false); } @@ -2133,12 +2141,20 @@ public Key GetLastKeyEvent() /// We will use weak reference of last touch events. /// Return value will be invalidated if last touch event changed internally. /// + /// + /// Do not Dispose this value. + /// /// The last touch event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Touch GetLastTouchEvent() { - if (internalLastTouchEvent == null || !internalLastTouchEvent.HasBody()) + if (internalLastTouchEvent == null) { + // TODO : We need to make automatically release memory of these cached events in future. + if (!(internalLastTouchEvent?.IsNativeHandleInvalid() ?? true)) + { + Interop.Touch.DeleteTouch(internalLastTouchEvent.SwigCPtr); + } // Create empty event handle without register. internalLastTouchEvent = new Touch(Interop.Touch.NewTouch(), false); } @@ -2154,12 +2170,20 @@ public Touch GetLastTouchEvent() /// We will use weak reference of last hover events. /// Return value will be invalidated if last hover event changed internally. /// + /// + /// Do not Dispose this value. + /// /// The last hover event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Hover GetLastHoverEvent() { - if (internalLastHoverEvent == null || !internalLastHoverEvent.HasBody()) + if (internalLastHoverEvent == null) { + // TODO : We need to make automatically release memory of these cached events in future. + if (!(internalLastHoverEvent?.IsNativeHandleInvalid() ?? true)) + { + Interop.Hover.DeleteHover(internalLastHoverEvent.SwigCPtr); + } // Create empty event handle without register. internalLastHoverEvent = new Hover(Interop.Hover.New(0u), false); } @@ -2250,10 +2274,26 @@ protected override void Dispose(DisposeTypes type) localController?.Dispose(); + // TODO : We need to make automatically release memory of these cached events in future. + if (!(internalLastKeyEvent?.IsNativeHandleInvalid() ?? true)) + { + Interop.Key.DeleteKey(internalLastKeyEvent.SwigCPtr); + } + if (!(internalLastTouchEvent?.IsNativeHandleInvalid() ?? true)) + { + Interop.Touch.DeleteTouch(internalLastTouchEvent.SwigCPtr); + } + if (!(internalLastHoverEvent?.IsNativeHandleInvalid() ?? true)) + { + Interop.Hover.DeleteHover(internalLastHoverEvent.SwigCPtr); + } + internalLastKeyEvent?.Dispose(); internalLastKeyEvent = null; internalLastTouchEvent?.Dispose(); internalLastTouchEvent = null; + internalLastHoverEvent?.Dispose(); + internalLastHoverEvent = null; internalHoverTimer?.Stop(); internalHoverTimer?.Dispose(); From 30b593ae6366044eb65d39e404da74c5733ffa75 Mon Sep 17 00:00:00 2001 From: "dongsug.song" Date: Tue, 26 Sep 2023 18:39:21 +0900 Subject: [PATCH 34/82] [NUI] fix IME window crash issue --- .../src/internal/Application/Application.cs | 23 +++++++++++++++---- .../internal/Application/NUICoreBackend.cs | 2 +- .../internal/Interop/Interop.Application.cs | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Application/Application.cs b/src/Tizen.NUI/src/internal/Application/Application.cs index ec28235ef6b..d66cd5320d3 100755 --- a/src/Tizen.NUI/src/internal/Application/Application.cs +++ b/src/Tizen.NUI/src/internal/Application/Application.cs @@ -1553,13 +1553,13 @@ public static Application NewApplication(string[] args, string stylesheet, NUIAp return instance; } - public static Application NewApplication(string stylesheet, NUIApplication.WindowMode windowMode, WindowType type) + public static Application NewApplication(string[] args, string stylesheet, NUIApplication.WindowMode windowMode, WindowType type) { if (instance != null) { return instance; } - Application ret = New(1, stylesheet, windowMode, type); + Application ret = New(args, stylesheet, windowMode, type); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); instance = ret; @@ -1700,12 +1700,27 @@ public static Application New(string[] args, string stylesheet, NUIApplication.W return ret; } - public static Application New(int argc, string stylesheet, NUIApplication.WindowMode windowMode, WindowType type) + public static Application New(string[] args, string stylesheet, NUIApplication.WindowMode windowMode, WindowType type) { + int argc = 0; + string argvStr = ""; + try + { + argc = args.Length; + argvStr = string.Join(" ", args); + } + catch (Exception exception) + { + Tizen.Log.Fatal("NUI", "[Error] got exception during Application New(), this should not occur, message : " + exception.Message); + Tizen.Log.Fatal("NUI", "[Error] error line number : " + new StackTrace(exception, true).GetFrame(0).GetFileLineNumber()); + Tizen.Log.Fatal("NUI", "[Error] Stack Trace : " + exception.StackTrace); + throw; + } + // It will be removed until dali APIs are prepared. Rectangle initRectangle = new Rectangle(0, 0, 0, 0); - Application ret = new Application(Interop.Application.New(argc, stylesheet, (int)windowMode, Rectangle.getCPtr(initRectangle), (int)type), true); + Application ret = new Application(Interop.Application.New(argc, argvStr, stylesheet, (int)windowMode, Rectangle.getCPtr(initRectangle), (int)type), true); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } diff --git a/src/Tizen.NUI/src/internal/Application/NUICoreBackend.cs b/src/Tizen.NUI/src/internal/Application/NUICoreBackend.cs index f3472315018..37696d40e25 100755 --- a/src/Tizen.NUI/src/internal/Application/NUICoreBackend.cs +++ b/src/Tizen.NUI/src/internal/Application/NUICoreBackend.cs @@ -186,7 +186,7 @@ public void Run(string[] args) } else if (defaultWindowType != WindowType.Normal) { - application = Application.NewApplication(stylesheet, windowMode, defaultWindowType); + application = Application.NewApplication(args, stylesheet, windowMode, defaultWindowType); } else { diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.Application.cs b/src/Tizen.NUI/src/internal/Interop/Interop.Application.cs index d453dba39ac..b17b6dda3ac 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.Application.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.Application.cs @@ -90,7 +90,7 @@ internal static partial class Application public static extern global::System.IntPtr New(int jarg1, string jarg3, int jarg4, global::System.Runtime.InteropServices.HandleRef jarg5); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Application_New__SWIG_5")] - public static extern global::System.IntPtr New(int jarg1, string jarg3, int jarg4, global::System.Runtime.InteropServices.HandleRef jarg5, int jarg6); + public static extern global::System.IntPtr New(int argc, string argv, string styleSheet, int windowMode, global::System.Runtime.InteropServices.HandleRef initRectangle, int windowType); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Application_New__SWIG_6")] public static extern global::System.IntPtr New(int argc, string argv, string jarg3, int jarg4, global::System.Runtime.InteropServices.HandleRef jarg5, bool jarg7); From 1859e09100317d06e3e6e09e69aebdb5dacd6a94 Mon Sep 17 00:00:00 2001 From: Jay Cho Date: Thu, 5 Oct 2023 13:32:50 +0900 Subject: [PATCH 35/82] Add API12 --- .github/branch-metadata.yml | 8 +++++++- .github/workflows/nightly-release.yml | 2 +- README.md | 13 +++++++------ pkg/Tizen.NET/Tizen.NET.nuspec | 6 +++++- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/branch-metadata.yml b/.github/branch-metadata.yml index 2d5ea3c5f09..1752567a98c 100644 --- a/.github/branch-metadata.yml +++ b/.github/branch-metadata.yml @@ -1,7 +1,13 @@ master: + api-level: API12 + labels: [ API12 ] + tizen-branch: tizen + version-prefix: 12.0.0 + +API11: api-level: API11 labels: [ API11 ] - tizen-branch: tizen + tizen-branch: tizen_8.0 version-prefix: 11.0.0 API10: diff --git a/.github/workflows/nightly-release.yml b/.github/workflows/nightly-release.yml index ce309c0b7f3..2bad9f9baac 100644 --- a/.github/workflows/nightly-release.yml +++ b/.github/workflows/nightly-release.yml @@ -7,7 +7,7 @@ on: workflow_dispatch: env: - TARGET_BRANCHES: 'master API10 API9' + TARGET_BRANCHES: 'master API11 API10' jobs: nightly: diff --git a/README.md b/README.md index cabe17afd2a..f419cffc99a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ TizenFX API, which allows you to access platform-specific features not covered b | Branch | API Level | Target Framework | API Reference | Platform | myget.org | nuget.org | |--------|:---------:|------------------|---------------|-------------------|-----------|------------| -|master | 11 | net6.0-tizen8.0 | [Link](https://samsung.github.io/TizenFX/master/) | Tizen 8.0 | [![api11_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API11.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | | +|master | 12 | net6.0-tizen9.0 | [Link](https://samsung.github.io/TizenFX/master/) | Tizen vNext | [![api12_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API12.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | | +|API11 | 11 | net6.0-tizen8.0 | [Link](https://samsung.github.io/TizenFX/master/) | Tizen 8.0 | [![api11_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API11.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | | |API10 | 10 | tizen10.0 | [Link](https://samsung.github.io/TizenFX/API10/) | Tizen 7.0 | [![api10_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API10.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | [![api10_nuget](https://img.shields.io/nuget/v/Tizen.NET.API10.svg)](https://www.nuget.org/packages/Tizen.NET/) | |API9 | 9 | tizen90 | [Link](https://samsung.github.io/TizenFX/API9/) | Tizen 6.5 | [![api9_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API9.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | [![api9_nuget](https://img.shields.io/nuget/v/Tizen.NET.API9.svg)](https://www.nuget.org/packages/Tizen.NET/) | |API8 | 8 | tizen80 | [Link](https://samsung.github.io/TizenFX/API8/) | Tizen 6.0 | [![api8_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API8.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | [![api8_nuget](https://img.shields.io/nuget/v/Tizen.NET.API8.svg)](https://www.nuget.org/packages/Tizen.NET/) | @@ -19,7 +20,7 @@ TizenFX API, which allows you to access platform-specific features not covered b |API4 | 4 | tizen40 | [Link](https://samsung.github.io/TizenFX/API4/) | Tizen 4.0 | [![api4_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API4.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | [![api4_nuget](https://img.shields.io/nuget/v/Tizen.NET.API4.svg)](https://www.nuget.org/packages/Tizen.NET/) | ### master -The __master__ branch is the main development branch for the Tizen .NET __API Level 11__. +The __master__ branch is the main development branch for the Tizen .NET __API Level 12__. The following NuGet packages will be published to [Tizen MyGet Gallery](https://tizen.myget.org/gallery/dotnet) and [Github Packages Registry](https://github.com/orgs/Samsung/packages?tab=packages&q=Tizen.NET) every day if there are any changes. (Nightly Build) @@ -27,13 +28,13 @@ The following NuGet packages will be published to [Tizen MyGet Gallery](https:// > - GitHub Packages Feed : ```https://nuget.pkg.github.com/Samsung/index.json``` > - GitHub Packages only supports authentication using a personal access token (classic). For more information, see [Working with the NuGet registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry) and [Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) -* Tizen.NET 11.0.0.##### -* Tizen.NET.API11 11.0.0.##### -* Tizen.NET.Internals 11.0.0.##### +* Tizen.NET 12.0.0.##### +* Tizen.NET.API12 12.0.0.##### +* Tizen.NET.Internals 12.0.0.##### And, This branch is pushed to the [tizen branch](https://git.tizen.org/cgit/platform/core/csapi/tizenfx/?h=tizen) in the tizen gerrit and submitted for the next Tizen platform. -### API4 ~ API10 branches +### API4 ~ API11 branches The __API#__ branches are the release branch for Tizen .NET __API Level #__. These release branches were __FROZEN__. No new public APIs can be added to these branches, only bug fixes and internal APIs can be added. diff --git a/pkg/Tizen.NET/Tizen.NET.nuspec b/pkg/Tizen.NET/Tizen.NET.nuspec index 08687b19366..d4f6274cb33 100644 --- a/pkg/Tizen.NET/Tizen.NET.nuspec +++ b/pkg/Tizen.NET/Tizen.NET.nuspec @@ -49,7 +49,11 @@ - + + + + + From 0e3969305768e037d2e6c6a5aa78f253f280d471 Mon Sep 17 00:00:00 2001 From: Jay Cho Date: Fri, 6 Oct 2023 18:38:09 +0900 Subject: [PATCH 36/82] Add API12 Update pkg --- README.md | 3 ++- packaging/500.tizenfx_upgrade.sh | 6 +++--- packaging/csapi-tizenfx.spec | 10 +++++----- packaging/version.txt | 6 +++--- .../xamlbuild/Tizen.NUI.XamlBuild.dll | Bin 515072 -> 0 bytes .../Tizen.NET.API12.nuspec} | 10 +++++----- .../build/net6.0/Tizen.NET.API12.props} | 0 .../build/net6.0/Tizen.NET.API12.targets} | 0 .../LICENSE.Microsoft.NETCore.App.Ref.txt | 0 .../build/tizen11.0/PlatformManifest.txt | 0 .../build/tizen11.0/Tizen.NET.API12.props} | 0 .../build/tizen11.0/Tizen.NET.API12.targets} | 0 .../build/tizen11.0/ref/Microsoft.CSharp.dll | Bin .../build/tizen11.0/ref/Microsoft.CSharp.xml | 0 .../ref/Microsoft.VisualBasic.Core.dll | Bin .../ref/Microsoft.VisualBasic.Core.xml | 0 .../tizen11.0/ref/Microsoft.VisualBasic.dll | Bin .../ref/Microsoft.Win32.Primitives.dll | Bin .../ref/Microsoft.Win32.Primitives.xml | 0 .../tizen11.0/ref/Microsoft.Win32.Registry.dll | Bin .../tizen11.0/ref/Microsoft.Win32.Registry.xml | 0 .../build/tizen11.0/ref/System.AppContext.dll | Bin .../build/tizen11.0/ref/System.Buffers.dll | Bin .../ref/System.Collections.Concurrent.dll | Bin .../ref/System.Collections.Concurrent.xml | 0 .../ref/System.Collections.Immutable.dll | Bin .../ref/System.Collections.Immutable.xml | 0 .../ref/System.Collections.NonGeneric.dll | Bin .../ref/System.Collections.NonGeneric.xml | 0 .../ref/System.Collections.Specialized.dll | Bin .../ref/System.Collections.Specialized.xml | 0 .../build/tizen11.0/ref/System.Collections.dll | Bin .../build/tizen11.0/ref/System.Collections.xml | 0 .../ref/System.ComponentModel.Annotations.dll | Bin .../ref/System.ComponentModel.Annotations.xml | 0 .../System.ComponentModel.DataAnnotations.dll | Bin .../System.ComponentModel.EventBasedAsync.dll | Bin .../System.ComponentModel.EventBasedAsync.xml | 0 .../ref/System.ComponentModel.Primitives.dll | Bin .../ref/System.ComponentModel.Primitives.xml | 0 .../System.ComponentModel.TypeConverter.dll | Bin .../System.ComponentModel.TypeConverter.xml | 0 .../tizen11.0/ref/System.ComponentModel.dll | Bin .../tizen11.0/ref/System.ComponentModel.xml | 0 .../tizen11.0/ref/System.Configuration.dll | Bin .../build/tizen11.0/ref/System.Console.dll | Bin .../build/tizen11.0/ref/System.Console.xml | 0 .../build/tizen11.0/ref/System.Core.dll | Bin .../build/tizen11.0/ref/System.Data.Common.dll | Bin .../build/tizen11.0/ref/System.Data.Common.xml | 0 .../ref/System.Data.DataSetExtensions.dll | Bin .../build/tizen11.0/ref/System.Data.dll | Bin .../ref/System.Diagnostics.Contracts.dll | Bin .../ref/System.Diagnostics.Contracts.xml | 0 .../tizen11.0/ref/System.Diagnostics.Debug.dll | Bin .../System.Diagnostics.DiagnosticSource.dll | Bin .../System.Diagnostics.DiagnosticSource.xml | 0 .../ref/System.Diagnostics.FileVersionInfo.dll | Bin .../ref/System.Diagnostics.FileVersionInfo.xml | 0 .../ref/System.Diagnostics.Process.dll | Bin .../ref/System.Diagnostics.Process.xml | 0 .../ref/System.Diagnostics.StackTrace.dll | Bin .../ref/System.Diagnostics.StackTrace.xml | 0 ...tem.Diagnostics.TextWriterTraceListener.dll | Bin ...tem.Diagnostics.TextWriterTraceListener.xml | 0 .../tizen11.0/ref/System.Diagnostics.Tools.dll | Bin .../ref/System.Diagnostics.TraceSource.dll | Bin .../ref/System.Diagnostics.TraceSource.xml | 0 .../ref/System.Diagnostics.Tracing.dll | Bin .../ref/System.Diagnostics.Tracing.xml | 0 .../ref/System.Drawing.Primitives.dll | Bin .../ref/System.Drawing.Primitives.xml | 0 .../build/tizen11.0/ref/System.Drawing.dll | Bin .../tizen11.0/ref/System.Dynamic.Runtime.dll | Bin .../tizen11.0/ref/System.Formats.Asn1.dll | Bin .../tizen11.0/ref/System.Formats.Asn1.xml | 0 .../ref/System.Globalization.Calendars.dll | Bin .../ref/System.Globalization.Extensions.dll | Bin .../tizen11.0/ref/System.Globalization.dll | Bin .../ref/System.IO.Compression.Brotli.dll | Bin .../ref/System.IO.Compression.FileSystem.dll | Bin .../ref/System.IO.Compression.ZipFile.dll | Bin .../ref/System.IO.Compression.ZipFile.xml | 0 .../tizen11.0/ref/System.IO.Compression.dll | Bin .../tizen11.0/ref/System.IO.Compression.xml | 0 .../ref/System.IO.FileSystem.AccessControl.dll | Bin .../ref/System.IO.FileSystem.AccessControl.xml | 0 .../ref/System.IO.FileSystem.DriveInfo.dll | Bin .../ref/System.IO.FileSystem.DriveInfo.xml | 0 .../ref/System.IO.FileSystem.Primitives.dll | Bin .../ref/System.IO.FileSystem.Watcher.dll | Bin .../ref/System.IO.FileSystem.Watcher.xml | 0 .../tizen11.0/ref/System.IO.FileSystem.dll | Bin .../ref/System.IO.IsolatedStorage.dll | Bin .../ref/System.IO.IsolatedStorage.xml | 0 .../ref/System.IO.MemoryMappedFiles.dll | Bin .../ref/System.IO.MemoryMappedFiles.xml | 0 .../ref/System.IO.Pipes.AccessControl.dll | Bin .../ref/System.IO.Pipes.AccessControl.xml | 0 .../build/tizen11.0/ref/System.IO.Pipes.dll | Bin .../build/tizen11.0/ref/System.IO.Pipes.xml | 0 .../ref/System.IO.UnmanagedMemoryStream.dll | Bin .../build/tizen11.0/ref/System.IO.dll | Bin .../tizen11.0/ref/System.Linq.Expressions.dll | Bin .../tizen11.0/ref/System.Linq.Expressions.xml | 0 .../tizen11.0/ref/System.Linq.Parallel.dll | Bin .../tizen11.0/ref/System.Linq.Parallel.xml | 0 .../tizen11.0/ref/System.Linq.Queryable.dll | Bin .../tizen11.0/ref/System.Linq.Queryable.xml | 0 .../build/tizen11.0/ref/System.Linq.dll | Bin .../build/tizen11.0/ref/System.Linq.xml | 0 .../build/tizen11.0/ref/System.Memory.dll | Bin .../build/tizen11.0/ref/System.Memory.xml | 0 .../tizen11.0/ref/System.Net.Http.Json.dll | Bin .../tizen11.0/ref/System.Net.Http.Json.xml | 0 .../build/tizen11.0/ref/System.Net.Http.dll | Bin .../build/tizen11.0/ref/System.Net.Http.xml | 0 .../tizen11.0/ref/System.Net.HttpListener.dll | Bin .../tizen11.0/ref/System.Net.HttpListener.xml | 0 .../build/tizen11.0/ref/System.Net.Mail.dll | Bin .../build/tizen11.0/ref/System.Net.Mail.xml | 0 .../ref/System.Net.NameResolution.dll | Bin .../ref/System.Net.NameResolution.xml | 0 .../ref/System.Net.NetworkInformation.dll | Bin .../ref/System.Net.NetworkInformation.xml | 0 .../build/tizen11.0/ref/System.Net.Ping.dll | Bin .../build/tizen11.0/ref/System.Net.Ping.xml | 0 .../tizen11.0/ref/System.Net.Primitives.dll | Bin .../tizen11.0/ref/System.Net.Primitives.xml | 0 .../tizen11.0/ref/System.Net.Requests.dll | Bin .../tizen11.0/ref/System.Net.Requests.xml | 0 .../tizen11.0/ref/System.Net.Security.dll | Bin .../tizen11.0/ref/System.Net.Security.xml | 0 .../tizen11.0/ref/System.Net.ServicePoint.dll | Bin .../tizen11.0/ref/System.Net.ServicePoint.xml | 0 .../build/tizen11.0/ref/System.Net.Sockets.dll | Bin .../build/tizen11.0/ref/System.Net.Sockets.xml | 0 .../tizen11.0/ref/System.Net.WebClient.dll | Bin .../tizen11.0/ref/System.Net.WebClient.xml | 0 .../ref/System.Net.WebHeaderCollection.dll | Bin .../ref/System.Net.WebHeaderCollection.xml | 0 .../tizen11.0/ref/System.Net.WebProxy.dll | Bin .../tizen11.0/ref/System.Net.WebProxy.xml | 0 .../ref/System.Net.WebSockets.Client.dll | Bin .../ref/System.Net.WebSockets.Client.xml | 0 .../tizen11.0/ref/System.Net.WebSockets.dll | Bin .../tizen11.0/ref/System.Net.WebSockets.xml | 0 .../build/tizen11.0/ref/System.Net.dll | Bin .../tizen11.0/ref/System.Numerics.Vectors.dll | Bin .../build/tizen11.0/ref/System.Numerics.dll | Bin .../build/tizen11.0/ref/System.ObjectModel.dll | Bin .../build/tizen11.0/ref/System.ObjectModel.xml | 0 .../ref/System.Reflection.DispatchProxy.dll | Bin .../ref/System.Reflection.DispatchProxy.xml | 0 .../System.Reflection.Emit.ILGeneration.dll | Bin .../System.Reflection.Emit.ILGeneration.xml | 0 .../ref/System.Reflection.Emit.Lightweight.dll | Bin .../ref/System.Reflection.Emit.Lightweight.xml | 0 .../tizen11.0/ref/System.Reflection.Emit.dll | Bin .../tizen11.0/ref/System.Reflection.Emit.xml | 0 .../ref/System.Reflection.Extensions.dll | Bin .../ref/System.Reflection.Metadata.dll | Bin .../ref/System.Reflection.Metadata.xml | 0 .../ref/System.Reflection.Primitives.dll | Bin .../ref/System.Reflection.Primitives.xml | 0 .../ref/System.Reflection.TypeExtensions.dll | Bin .../ref/System.Reflection.TypeExtensions.xml | 0 .../build/tizen11.0/ref/System.Reflection.dll | Bin .../tizen11.0/ref/System.Resources.Reader.dll | Bin .../ref/System.Resources.ResourceManager.dll | Bin .../tizen11.0/ref/System.Resources.Writer.dll | Bin .../tizen11.0/ref/System.Resources.Writer.xml | 0 .../System.Runtime.CompilerServices.Unsafe.dll | Bin .../System.Runtime.CompilerServices.Unsafe.xml | 0 ...System.Runtime.CompilerServices.VisualC.dll | Bin ...System.Runtime.CompilerServices.VisualC.xml | 0 .../ref/System.Runtime.Extensions.dll | Bin .../tizen11.0/ref/System.Runtime.Handles.dll | Bin ...time.InteropServices.RuntimeInformation.dll | Bin ...time.InteropServices.RuntimeInformation.xml | 0 .../ref/System.Runtime.InteropServices.dll | Bin .../ref/System.Runtime.InteropServices.xml | 0 .../ref/System.Runtime.Intrinsics.dll | Bin .../ref/System.Runtime.Intrinsics.xml | 0 .../tizen11.0/ref/System.Runtime.Loader.dll | Bin .../tizen11.0/ref/System.Runtime.Loader.xml | 0 .../tizen11.0/ref/System.Runtime.Numerics.dll | Bin .../tizen11.0/ref/System.Runtime.Numerics.xml | 0 ...System.Runtime.Serialization.Formatters.dll | Bin ...System.Runtime.Serialization.Formatters.xml | 0 .../ref/System.Runtime.Serialization.Json.dll | Bin .../ref/System.Runtime.Serialization.Json.xml | 0 ...System.Runtime.Serialization.Primitives.dll | Bin ...System.Runtime.Serialization.Primitives.xml | 0 .../ref/System.Runtime.Serialization.Xml.dll | Bin .../ref/System.Runtime.Serialization.Xml.xml | 0 .../ref/System.Runtime.Serialization.dll | Bin .../build/tizen11.0/ref/System.Runtime.dll | Bin .../build/tizen11.0/ref/System.Runtime.xml | 0 .../ref/System.Security.AccessControl.dll | Bin .../ref/System.Security.AccessControl.xml | 0 .../tizen11.0/ref/System.Security.Claims.dll | Bin .../tizen11.0/ref/System.Security.Claims.xml | 0 ...System.Security.Cryptography.Algorithms.dll | Bin ...System.Security.Cryptography.Algorithms.xml | 0 .../ref/System.Security.Cryptography.Cng.dll | Bin .../ref/System.Security.Cryptography.Cng.xml | 0 .../ref/System.Security.Cryptography.Csp.dll | Bin .../ref/System.Security.Cryptography.Csp.xml | 0 .../System.Security.Cryptography.Encoding.dll | Bin .../System.Security.Cryptography.Encoding.xml | 0 .../System.Security.Cryptography.OpenSsl.dll | Bin .../System.Security.Cryptography.OpenSsl.xml | 0 ...System.Security.Cryptography.Primitives.dll | Bin ...System.Security.Cryptography.Primitives.xml | 0 ....Security.Cryptography.X509Certificates.dll | Bin ....Security.Cryptography.X509Certificates.xml | 0 .../ref/System.Security.Principal.Windows.dll | Bin .../ref/System.Security.Principal.Windows.xml | 0 .../ref/System.Security.Principal.dll | Bin .../ref/System.Security.SecureString.dll | Bin .../build/tizen11.0/ref/System.Security.dll | Bin .../tizen11.0/ref/System.ServiceModel.Web.dll | Bin .../tizen11.0/ref/System.ServiceProcess.dll | Bin .../ref/System.Text.Encoding.CodePages.dll | Bin .../ref/System.Text.Encoding.CodePages.xml | 0 .../ref/System.Text.Encoding.Extensions.dll | Bin .../ref/System.Text.Encoding.Extensions.xml | 0 .../tizen11.0/ref/System.Text.Encoding.dll | Bin .../ref/System.Text.Encodings.Web.dll | Bin .../ref/System.Text.Encodings.Web.xml | 0 .../build/tizen11.0/ref/System.Text.Json.dll | Bin .../build/tizen11.0/ref/System.Text.Json.xml | 0 .../ref/System.Text.RegularExpressions.dll | Bin .../ref/System.Text.RegularExpressions.xml | 0 .../ref/System.Threading.Channels.dll | Bin .../ref/System.Threading.Channels.xml | 0 .../ref/System.Threading.Overlapped.dll | Bin .../ref/System.Threading.Overlapped.xml | 0 .../ref/System.Threading.Tasks.Dataflow.dll | Bin .../ref/System.Threading.Tasks.Dataflow.xml | 0 .../ref/System.Threading.Tasks.Extensions.dll | Bin .../ref/System.Threading.Tasks.Parallel.dll | Bin .../ref/System.Threading.Tasks.Parallel.xml | 0 .../tizen11.0/ref/System.Threading.Tasks.dll | Bin .../tizen11.0/ref/System.Threading.Thread.dll | Bin .../tizen11.0/ref/System.Threading.Thread.xml | 0 .../ref/System.Threading.ThreadPool.dll | Bin .../ref/System.Threading.ThreadPool.xml | 0 .../tizen11.0/ref/System.Threading.Timer.dll | Bin .../build/tizen11.0/ref/System.Threading.dll | Bin .../build/tizen11.0/ref/System.Threading.xml | 0 .../ref/System.Transactions.Local.dll | Bin .../ref/System.Transactions.Local.xml | 0 .../tizen11.0/ref/System.Transactions.dll | Bin .../build/tizen11.0/ref/System.ValueTuple.dll | Bin .../tizen11.0/ref/System.Web.HttpUtility.dll | Bin .../tizen11.0/ref/System.Web.HttpUtility.xml | 0 .../build/tizen11.0/ref/System.Web.dll | Bin .../build/tizen11.0/ref/System.Windows.dll | Bin .../build/tizen11.0/ref/System.Xml.Linq.dll | Bin .../tizen11.0/ref/System.Xml.ReaderWriter.dll | Bin .../tizen11.0/ref/System.Xml.ReaderWriter.xml | 0 .../tizen11.0/ref/System.Xml.Serialization.dll | Bin .../tizen11.0/ref/System.Xml.XDocument.dll | Bin .../tizen11.0/ref/System.Xml.XDocument.xml | 0 .../ref/System.Xml.XPath.XDocument.dll | Bin .../ref/System.Xml.XPath.XDocument.xml | 0 .../build/tizen11.0/ref/System.Xml.XPath.dll | Bin .../build/tizen11.0/ref/System.Xml.XPath.xml | 0 .../tizen11.0/ref/System.Xml.XmlDocument.dll | Bin .../tizen11.0/ref/System.Xml.XmlSerializer.dll | Bin .../tizen11.0/ref/System.Xml.XmlSerializer.xml | 0 .../build/tizen11.0/ref/System.Xml.dll | Bin .../build/tizen11.0/ref/System.dll | Bin .../build/tizen11.0/ref/WindowsBase.dll | Bin .../build/tizen11.0/ref/mscorlib.dll | Bin .../build/tizen11.0/ref/netstandard.dll | Bin .../build/tizen11.0/ref/netstandard.xml | 0 .../design/Tizen.NUI.Components.Design.dll | Bin .../design/Tizen.NUI.Design.dll | Bin .../xamlbuild/Mono.Cecil.Mdb.dll | Bin .../xamlbuild/Mono.Cecil.Pdb.dll | Bin .../xamlbuild/Mono.Cecil.Rocks.dll | Bin .../xamlbuild/Mono.Cecil.dll | Bin .../xamlbuild/System.CodeDom.dll | Bin .../xamlbuild/Tizen.NUI.XamlBuild.dll | Bin .../xamlbuild/Tizen.NUI.XamlBuild.props | 0 .../xamlbuild/Tizen.NUI.XamlBuild.targets | 0 test/NUITizenGallery/NUITizenGallery.csproj | 2 +- 290 files changed, 19 insertions(+), 18 deletions(-) delete mode 100644 pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.dll rename pkg/{Tizen.NET.API11/Tizen.NET.API11.nuspec => Tizen.NET.API12/Tizen.NET.API12.nuspec} (75%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11/build/net6.0/Tizen.NET.API11.props => Tizen.NET.API12/build/net6.0/Tizen.NET.API12.props} (100%) rename pkg/{Tizen.NET.API11/build/net6.0/Tizen.NET.API11.targets => Tizen.NET.API12/build/net6.0/Tizen.NET.API12.targets} (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/LICENSE.Microsoft.NETCore.App.Ref.txt (100%) rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/PlatformManifest.txt (100%) rename pkg/{Tizen.NET.API11/build/tizen11.0/Tizen.NET.API11.props => Tizen.NET.API12/build/tizen11.0/Tizen.NET.API12.props} (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11/build/tizen11.0/Tizen.NET.API11.targets => Tizen.NET.API12/build/tizen11.0/Tizen.NET.API12.targets} (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.CSharp.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.CSharp.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.VisualBasic.Core.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.VisualBasic.Core.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.VisualBasic.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.Win32.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.Win32.Primitives.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.Win32.Registry.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/Microsoft.Win32.Registry.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.AppContext.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Buffers.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.Concurrent.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.Concurrent.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.Immutable.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.Immutable.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.NonGeneric.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.NonGeneric.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.Specialized.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.Specialized.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Collections.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.Annotations.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.Annotations.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.DataAnnotations.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.Primitives.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.TypeConverter.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.TypeConverter.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ComponentModel.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Configuration.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Console.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Console.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Core.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Data.Common.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Data.Common.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Data.DataSetExtensions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Data.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Contracts.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Contracts.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Debug.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Process.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Process.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.StackTrace.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.StackTrace.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Tools.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.TraceSource.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.TraceSource.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Tracing.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Diagnostics.Tracing.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Drawing.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Drawing.Primitives.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Drawing.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Dynamic.Runtime.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Formats.Asn1.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Formats.Asn1.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Globalization.Calendars.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Globalization.Extensions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Globalization.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Compression.Brotli.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Compression.FileSystem.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Compression.ZipFile.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Compression.ZipFile.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Compression.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Compression.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.Watcher.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.Watcher.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.FileSystem.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.IsolatedStorage.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.IsolatedStorage.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.MemoryMappedFiles.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.MemoryMappedFiles.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Pipes.AccessControl.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Pipes.AccessControl.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Pipes.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.Pipes.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.UnmanagedMemoryStream.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.IO.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.Expressions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.Expressions.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.Parallel.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.Parallel.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.Queryable.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.Queryable.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Linq.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Memory.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Memory.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Http.Json.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Http.Json.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Http.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Http.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.HttpListener.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.HttpListener.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Mail.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Mail.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.NameResolution.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.NameResolution.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.NetworkInformation.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.NetworkInformation.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Ping.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Ping.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Primitives.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Requests.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Requests.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Security.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Security.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.ServicePoint.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.ServicePoint.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Sockets.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.Sockets.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebClient.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebClient.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebHeaderCollection.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebHeaderCollection.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebProxy.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebProxy.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebSockets.Client.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebSockets.Client.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebSockets.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.WebSockets.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Net.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Numerics.Vectors.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Numerics.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ObjectModel.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ObjectModel.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.DispatchProxy.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.DispatchProxy.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Emit.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Emit.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Extensions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Metadata.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Metadata.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.Primitives.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.TypeExtensions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.TypeExtensions.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Reflection.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Resources.Reader.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Resources.ResourceManager.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Resources.Writer.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Resources.Writer.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Extensions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Handles.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.InteropServices.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.InteropServices.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Intrinsics.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Intrinsics.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Loader.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Loader.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Numerics.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Numerics.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Json.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Json.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Xml.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.Xml.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.Serialization.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Runtime.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.AccessControl.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.AccessControl.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Claims.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Claims.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Cng.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Cng.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Csp.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Csp.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Encoding.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Encoding.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Primitives.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.Primitives.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Principal.Windows.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Principal.Windows.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.Principal.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.SecureString.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Security.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ServiceModel.Web.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ServiceProcess.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Encoding.CodePages.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Encoding.CodePages.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Encoding.Extensions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Encoding.Extensions.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Encoding.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Encodings.Web.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Encodings.Web.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Json.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.Json.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.RegularExpressions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Text.RegularExpressions.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Channels.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Channels.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Overlapped.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Overlapped.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Tasks.Extensions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Tasks.Parallel.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Tasks.Parallel.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Tasks.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Thread.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Thread.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.ThreadPool.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.ThreadPool.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.Timer.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Threading.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Transactions.Local.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Transactions.Local.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Transactions.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.ValueTuple.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Web.HttpUtility.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Web.HttpUtility.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Web.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Windows.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.Linq.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.ReaderWriter.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.ReaderWriter.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.Serialization.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XDocument.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XDocument.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XPath.XDocument.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XPath.XDocument.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XPath.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XPath.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XmlDocument.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XmlSerializer.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.XmlSerializer.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.Xml.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/System.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/WindowsBase.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/mscorlib.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/netstandard.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/build/tizen11.0/ref/netstandard.xml (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/design/Tizen.NUI.Components.Design.dll (100%) rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/design/Tizen.NUI.Design.dll (100%) rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/Mono.Cecil.Mdb.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/Mono.Cecil.Pdb.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/Mono.Cecil.Rocks.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/Mono.Cecil.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/System.CodeDom.dll (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/Tizen.NUI.XamlBuild.dll (100%) rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/Tizen.NUI.XamlBuild.props (100%) mode change 100755 => 100644 rename pkg/{Tizen.NET.API11 => Tizen.NET.API12}/xamlbuild/Tizen.NUI.XamlBuild.targets (100%) mode change 100755 => 100644 diff --git a/README.md b/README.md index f419cffc99a..05305e127ef 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ The __API#__ branches are the release branch for Tizen .NET __API Level #__. These release branches were __FROZEN__. No new public APIs can be added to these branches, only bug fixes and internal APIs can be added. -## Using `net6.0-tizen` target framework +## Using `net6.0-tizen` target framework for API11 or above If you want to use the `net6.0-tizen` target framework, you need to [install Tizen workload](https://github.com/Samsung/Tizen.NET/wiki/Installing-Tizen-.NET-Workload). ## Using `tizen` target framework @@ -56,6 +56,7 @@ For more information, please see [Using Tizen.NET.Sdk as SDK-style](https://deve ### Minimum required versions of Tizen.NET.Sdk and Visual Studio | API Level | Target Framework | Tizen.NET.Sdk | Visual Studio | |:---------:|------------------|---------------|-------------------| +| API12 | net6.0-tizen9.0 | [Tizen .NET Workloads](https://github.com/samsung/Tizen.NET) | 2022 | | API11 | net6.0-tizen8.0 | [Tizen .NET Workloads](https://github.com/samsung/Tizen.NET) | 2022 | | API10 | tizen10.0 | 1.1.9 | 2019 | | API9 | tizen90 | 1.1.7 | 2019 | diff --git a/packaging/500.tizenfx_upgrade.sh b/packaging/500.tizenfx_upgrade.sh index 6b175c5a080..77ce941ddc7 100644 --- a/packaging/500.tizenfx_upgrade.sh +++ b/packaging/500.tizenfx_upgrade.sh @@ -3,6 +3,6 @@ PATH=/bin:/usr/bin -vconftool set -f -t int db/dotnet/tizen_api_version 10 -vconftool set -f -t string db/dotnet/tizen_rid_version "4.0.0:5.0.0:5.5.0:6.0.0:6.5.0:7.0.0" -vconftool set -f -t string db/dotnet/tizen_tfm_support "tizen10.0:tizen90:tizen80:tizen70:tizen60:tizen50:tizen40" +vconftool set -f -t int db/dotnet/tizen_api_version 12 +vconftool set -f -t string db/dotnet/tizen_rid_version "4.0.0:5.0.0:5.5.0:6.0.0:6.5.0:7.0.0:8.0.0:9.0.0" +vconftool set -f -t string db/dotnet/tizen_tfm_support "net6.0-tizen9.0:net6.0-tizen8.0:tizen10.0:tizen90:tizen80:tizen70:tizen60:tizen50:tizen40" diff --git a/packaging/csapi-tizenfx.spec b/packaging/csapi-tizenfx.spec index 0cf3614f20d..41385b486e3 100644 --- a/packaging/csapi-tizenfx.spec +++ b/packaging/csapi-tizenfx.spec @@ -1,8 +1,8 @@ # Auto-generated from csapi-tizenfx.spec.in by makespec.sh -%define TIZEN_NET_API_VERSION 11 -%define TIZEN_NET_RPM_VERSION 11.0.0.999+nui22245 -%define TIZEN_NET_NUGET_VERSION 11.0.0.99999 +%define TIZEN_NET_API_VERSION 12 +%define TIZEN_NET_RPM_VERSION 12.0.0.999+nui22245 +%define TIZEN_NET_NUGET_VERSION 12.0.0.99999 %define DOTNET_ASSEMBLY_PATH /usr/share/dotnet.tizen/framework %define DOTNET_ASSEMBLY_DUMMY_PATH %{DOTNET_ASSEMBLY_PATH}/ref @@ -11,8 +11,8 @@ %define DOTNET_PRELOAD_PATH /usr/share/dotnet.tizen/preload %define DOTNET_NUGET_SOURCE /nuget -%define TIZEN_NET_RUNTIME_IDENTIFIERS 4.0.0:5.0.0:5.5.0:6.0.0:6.5.0:7.0.0:8.0.0 -%define TIZEN_NET_TARGET_FRAMEWORK_MONIKERS tizen11.0:tizen10.0:tizen90:tizen80:tizen70:tizen60:tizen50:tizen40 +%define TIZEN_NET_RUNTIME_IDENTIFIERS 4.0.0:5.0.0:5.5.0:6.0.0:6.5.0:7.0.0:8.0.0:9.0.0 +%define TIZEN_NET_TARGET_FRAMEWORK_MONIKERS net6.0-tizen9.0:net6.0-tizen8.0:tizen11.0:tizen10.0:tizen90:tizen80:tizen70:tizen60:tizen50:tizen40 %define DOTNET_CORE_RUNTIME_VERSION 6.0 %define UPGRADE_SCRIPT_PATH /usr/share/upgrade/scripts diff --git a/packaging/version.txt b/packaging/version.txt index ab5d5f86eee..35633e8a2ba 100755 --- a/packaging/version.txt +++ b/packaging/version.txt @@ -1,9 +1,9 @@ # Tizen .NET API Level -API_VERSION=11 +API_VERSION=12 # Default Versions (will be replaced by CI) -RPM_VERSION=11.0.0.999 -NUGET_VERSION=11.0.0.99999 +RPM_VERSION=12.0.0.999 +NUGET_VERSION=12.0.0.99999 # RPM Version Suffix RPM_VERSION_SUFFIX=nui22245 diff --git a/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.dll b/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.dll deleted file mode 100644 index 24c85252cbf6ce188a08e7b2e464a51820f0a8ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 515072 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 - Tizen.NET.API11 + Tizen.NET.API12 $fxversion$ Samsung Electronics Samsung Electronics @@ -9,13 +9,13 @@ https://www.apache.org/licenses/LICENSE-2.0 https://www.tizen.org/ https://developer.tizen.org/sites/default/files/images/tizen-pinwheel-on-light-rgb_64_64.png - Reference assemblies of Tizen .NET API Level 11. + Reference assemblies of Tizen .NET API Level 12. © Samsung Electronics Co., Ltd All Rights Reserved - - - + + + diff --git a/pkg/Tizen.NET.API11/build/net6.0/Tizen.NET.API11.props b/pkg/Tizen.NET.API12/build/net6.0/Tizen.NET.API12.props similarity index 100% rename from pkg/Tizen.NET.API11/build/net6.0/Tizen.NET.API11.props rename to pkg/Tizen.NET.API12/build/net6.0/Tizen.NET.API12.props diff --git a/pkg/Tizen.NET.API11/build/net6.0/Tizen.NET.API11.targets b/pkg/Tizen.NET.API12/build/net6.0/Tizen.NET.API12.targets old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/net6.0/Tizen.NET.API11.targets rename to pkg/Tizen.NET.API12/build/net6.0/Tizen.NET.API12.targets diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/LICENSE.Microsoft.NETCore.App.Ref.txt b/pkg/Tizen.NET.API12/build/tizen11.0/LICENSE.Microsoft.NETCore.App.Ref.txt similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/LICENSE.Microsoft.NETCore.App.Ref.txt rename to pkg/Tizen.NET.API12/build/tizen11.0/LICENSE.Microsoft.NETCore.App.Ref.txt diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/PlatformManifest.txt b/pkg/Tizen.NET.API12/build/tizen11.0/PlatformManifest.txt similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/PlatformManifest.txt rename to pkg/Tizen.NET.API12/build/tizen11.0/PlatformManifest.txt diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/Tizen.NET.API11.props b/pkg/Tizen.NET.API12/build/tizen11.0/Tizen.NET.API12.props old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/Tizen.NET.API11.props rename to pkg/Tizen.NET.API12/build/tizen11.0/Tizen.NET.API12.props diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/Tizen.NET.API11.targets b/pkg/Tizen.NET.API12/build/tizen11.0/Tizen.NET.API12.targets old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/Tizen.NET.API11.targets rename to pkg/Tizen.NET.API12/build/tizen11.0/Tizen.NET.API12.targets diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.CSharp.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.CSharp.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.CSharp.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.CSharp.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.CSharp.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.CSharp.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.CSharp.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.CSharp.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.VisualBasic.Core.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.VisualBasic.Core.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.VisualBasic.Core.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.VisualBasic.Core.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.VisualBasic.Core.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.VisualBasic.Core.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.VisualBasic.Core.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.VisualBasic.Core.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.VisualBasic.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.VisualBasic.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.VisualBasic.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.VisualBasic.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Primitives.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Primitives.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Primitives.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Primitives.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Registry.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Registry.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Registry.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Registry.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Registry.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Registry.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/Microsoft.Win32.Registry.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/Microsoft.Win32.Registry.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.AppContext.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.AppContext.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.AppContext.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.AppContext.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Buffers.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Buffers.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Buffers.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Buffers.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Concurrent.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Concurrent.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Concurrent.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Concurrent.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Concurrent.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Concurrent.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Concurrent.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Concurrent.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Immutable.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Immutable.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Immutable.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Immutable.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Immutable.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Immutable.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Immutable.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Immutable.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.NonGeneric.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.NonGeneric.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.NonGeneric.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.NonGeneric.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.NonGeneric.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.NonGeneric.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.NonGeneric.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.NonGeneric.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Specialized.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Specialized.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Specialized.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Specialized.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Specialized.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Specialized.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.Specialized.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.Specialized.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Collections.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Collections.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Annotations.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Annotations.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Annotations.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Annotations.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Annotations.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Annotations.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Annotations.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Annotations.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.DataAnnotations.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.DataAnnotations.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.DataAnnotations.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.DataAnnotations.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.EventBasedAsync.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Primitives.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Primitives.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.Primitives.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.Primitives.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.TypeConverter.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.TypeConverter.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.TypeConverter.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.TypeConverter.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.TypeConverter.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.TypeConverter.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.TypeConverter.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.TypeConverter.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ComponentModel.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ComponentModel.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Configuration.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Configuration.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Configuration.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Configuration.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Console.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Console.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Console.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Console.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Console.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Console.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Console.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Console.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Core.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Core.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Core.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Core.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.Common.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.Common.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.Common.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.Common.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.Common.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.Common.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.Common.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.Common.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.DataSetExtensions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.DataSetExtensions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.DataSetExtensions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.DataSetExtensions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Data.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Data.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Contracts.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Contracts.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Contracts.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Contracts.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Contracts.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Contracts.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Contracts.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Contracts.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Debug.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Debug.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Debug.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Debug.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.DiagnosticSource.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.FileVersionInfo.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Process.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Process.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Process.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Process.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Process.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Process.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Process.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Process.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.StackTrace.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.StackTrace.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.StackTrace.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.StackTrace.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.StackTrace.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.StackTrace.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.StackTrace.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.StackTrace.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TextWriterTraceListener.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Tools.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Tools.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Tools.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Tools.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TraceSource.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TraceSource.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TraceSource.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TraceSource.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TraceSource.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TraceSource.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.TraceSource.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.TraceSource.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Tracing.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Tracing.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Tracing.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Tracing.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Tracing.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Tracing.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Diagnostics.Tracing.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Diagnostics.Tracing.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Drawing.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Drawing.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Drawing.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Drawing.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Drawing.Primitives.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Drawing.Primitives.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Drawing.Primitives.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Drawing.Primitives.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Drawing.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Drawing.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Drawing.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Drawing.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Dynamic.Runtime.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Dynamic.Runtime.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Dynamic.Runtime.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Dynamic.Runtime.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Formats.Asn1.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Formats.Asn1.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Formats.Asn1.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Formats.Asn1.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Formats.Asn1.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Formats.Asn1.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Formats.Asn1.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Formats.Asn1.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Globalization.Calendars.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Globalization.Calendars.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Globalization.Calendars.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Globalization.Calendars.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Globalization.Extensions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Globalization.Extensions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Globalization.Extensions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Globalization.Extensions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Globalization.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Globalization.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Globalization.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Globalization.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.Brotli.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.Brotli.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.Brotli.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.Brotli.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.FileSystem.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.FileSystem.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.FileSystem.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.FileSystem.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.ZipFile.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.ZipFile.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.ZipFile.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.ZipFile.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.ZipFile.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.ZipFile.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.ZipFile.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.ZipFile.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Compression.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Compression.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.AccessControl.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.DriveInfo.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.Watcher.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.Watcher.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.Watcher.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.Watcher.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.Watcher.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.Watcher.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.Watcher.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.Watcher.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.FileSystem.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.FileSystem.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.IsolatedStorage.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.IsolatedStorage.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.IsolatedStorage.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.IsolatedStorage.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.IsolatedStorage.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.IsolatedStorage.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.IsolatedStorage.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.IsolatedStorage.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.MemoryMappedFiles.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.MemoryMappedFiles.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.MemoryMappedFiles.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.MemoryMappedFiles.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.MemoryMappedFiles.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.MemoryMappedFiles.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.MemoryMappedFiles.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.MemoryMappedFiles.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.AccessControl.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.AccessControl.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.AccessControl.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.AccessControl.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.AccessControl.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.AccessControl.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.AccessControl.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.AccessControl.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.Pipes.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.Pipes.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.UnmanagedMemoryStream.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.UnmanagedMemoryStream.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.UnmanagedMemoryStream.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.UnmanagedMemoryStream.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.IO.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.IO.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Expressions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Expressions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Expressions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Expressions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Expressions.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Expressions.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Expressions.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Expressions.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Parallel.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Parallel.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Parallel.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Parallel.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Parallel.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Parallel.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Parallel.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Parallel.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Queryable.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Queryable.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Queryable.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Queryable.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Queryable.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Queryable.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.Queryable.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.Queryable.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Linq.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Linq.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Memory.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Memory.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Memory.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Memory.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Memory.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Memory.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Memory.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Memory.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.Json.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.Json.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.Json.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.Json.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.Json.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.Json.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.Json.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.Json.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Http.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Http.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.HttpListener.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.HttpListener.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.HttpListener.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.HttpListener.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.HttpListener.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.HttpListener.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.HttpListener.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.HttpListener.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Mail.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Mail.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Mail.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Mail.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Mail.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Mail.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Mail.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Mail.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NameResolution.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NameResolution.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NameResolution.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NameResolution.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NameResolution.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NameResolution.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NameResolution.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NameResolution.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NetworkInformation.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NetworkInformation.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NetworkInformation.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NetworkInformation.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NetworkInformation.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NetworkInformation.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.NetworkInformation.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.NetworkInformation.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Ping.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Ping.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Ping.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Ping.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Ping.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Ping.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Ping.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Ping.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Primitives.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Primitives.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Primitives.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Primitives.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Requests.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Requests.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Requests.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Requests.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Requests.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Requests.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Requests.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Requests.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Security.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Security.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Security.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Security.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Security.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Security.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Security.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Security.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.ServicePoint.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.ServicePoint.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.ServicePoint.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.ServicePoint.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.ServicePoint.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.ServicePoint.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.ServicePoint.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.ServicePoint.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Sockets.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Sockets.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Sockets.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Sockets.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Sockets.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Sockets.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.Sockets.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.Sockets.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebClient.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebClient.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebClient.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebClient.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebClient.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebClient.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebClient.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebClient.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebHeaderCollection.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebHeaderCollection.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebHeaderCollection.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebHeaderCollection.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebHeaderCollection.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebHeaderCollection.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebHeaderCollection.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebHeaderCollection.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebProxy.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebProxy.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebProxy.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebProxy.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebProxy.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebProxy.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebProxy.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebProxy.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.Client.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.Client.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.Client.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.Client.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.Client.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.Client.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.Client.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.Client.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.WebSockets.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.WebSockets.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Net.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Net.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Numerics.Vectors.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Numerics.Vectors.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Numerics.Vectors.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Numerics.Vectors.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Numerics.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Numerics.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Numerics.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Numerics.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ObjectModel.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ObjectModel.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ObjectModel.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ObjectModel.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ObjectModel.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ObjectModel.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ObjectModel.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ObjectModel.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.DispatchProxy.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.DispatchProxy.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.DispatchProxy.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.DispatchProxy.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.DispatchProxy.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.DispatchProxy.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.DispatchProxy.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.DispatchProxy.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.ILGeneration.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.Lightweight.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Emit.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Emit.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Extensions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Extensions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Extensions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Extensions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Metadata.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Metadata.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Metadata.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Metadata.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Metadata.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Metadata.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Metadata.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Metadata.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Primitives.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Primitives.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.Primitives.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.Primitives.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.TypeExtensions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.TypeExtensions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.TypeExtensions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.TypeExtensions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.TypeExtensions.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.TypeExtensions.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.TypeExtensions.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.TypeExtensions.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Reflection.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Reflection.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.Reader.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.Reader.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.Reader.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.Reader.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.ResourceManager.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.ResourceManager.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.ResourceManager.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.ResourceManager.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.Writer.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.Writer.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.Writer.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.Writer.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.Writer.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.Writer.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Resources.Writer.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Resources.Writer.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.Unsafe.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.CompilerServices.VisualC.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Extensions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Extensions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Extensions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Extensions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Handles.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Handles.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Handles.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Handles.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.RuntimeInformation.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.InteropServices.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.InteropServices.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Intrinsics.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Intrinsics.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Intrinsics.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Intrinsics.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Intrinsics.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Intrinsics.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Intrinsics.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Intrinsics.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Loader.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Loader.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Loader.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Loader.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Loader.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Loader.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Loader.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Loader.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Numerics.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Numerics.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Numerics.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Numerics.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Numerics.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Numerics.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Numerics.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Numerics.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Formatters.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Json.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Json.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Json.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Json.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Json.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Json.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Json.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Json.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Primitives.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Xml.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Xml.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Xml.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Xml.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Xml.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Xml.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.Xml.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.Xml.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.Serialization.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.Serialization.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Runtime.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Runtime.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.AccessControl.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.AccessControl.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.AccessControl.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.AccessControl.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.AccessControl.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.AccessControl.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.AccessControl.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.AccessControl.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Claims.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Claims.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Claims.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Claims.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Claims.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Claims.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Claims.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Claims.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Algorithms.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Cng.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Cng.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Cng.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Cng.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Cng.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Cng.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Cng.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Cng.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Csp.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Csp.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Csp.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Csp.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Csp.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Csp.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Csp.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Csp.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Encoding.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Encoding.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Encoding.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Encoding.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Encoding.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Encoding.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Encoding.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Encoding.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.OpenSsl.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Primitives.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Primitives.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Primitives.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Primitives.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Primitives.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Primitives.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.Primitives.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.Primitives.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Cryptography.X509Certificates.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Principal.Windows.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Principal.Windows.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Principal.Windows.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Principal.Windows.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Principal.Windows.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Principal.Windows.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Principal.Windows.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Principal.Windows.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Principal.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Principal.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.Principal.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.Principal.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.SecureString.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.SecureString.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.SecureString.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.SecureString.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Security.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Security.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ServiceModel.Web.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ServiceModel.Web.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ServiceModel.Web.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ServiceModel.Web.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ServiceProcess.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ServiceProcess.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ServiceProcess.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ServiceProcess.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.CodePages.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.CodePages.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.CodePages.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.CodePages.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.CodePages.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.CodePages.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.CodePages.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.CodePages.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.Extensions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.Extensions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.Extensions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.Extensions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.Extensions.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.Extensions.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.Extensions.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.Extensions.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encoding.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encoding.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encodings.Web.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encodings.Web.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encodings.Web.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encodings.Web.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encodings.Web.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encodings.Web.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Encodings.Web.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Encodings.Web.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Json.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Json.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Json.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Json.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Json.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Json.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.Json.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.Json.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.RegularExpressions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.RegularExpressions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.RegularExpressions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.RegularExpressions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.RegularExpressions.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.RegularExpressions.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Text.RegularExpressions.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Text.RegularExpressions.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Channels.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Channels.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Channels.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Channels.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Channels.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Channels.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Channels.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Channels.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Overlapped.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Overlapped.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Overlapped.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Overlapped.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Overlapped.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Overlapped.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Overlapped.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Overlapped.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Dataflow.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Extensions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Extensions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Extensions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Extensions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Parallel.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Parallel.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Parallel.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Parallel.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Parallel.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Parallel.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.Parallel.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.Parallel.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Tasks.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Tasks.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Thread.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Thread.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Thread.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Thread.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Thread.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Thread.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Thread.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Thread.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.ThreadPool.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.ThreadPool.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.ThreadPool.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.ThreadPool.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.ThreadPool.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.ThreadPool.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.ThreadPool.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.ThreadPool.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Timer.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Timer.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.Timer.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.Timer.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Threading.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Threading.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Transactions.Local.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Transactions.Local.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Transactions.Local.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Transactions.Local.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Transactions.Local.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Transactions.Local.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Transactions.Local.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Transactions.Local.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Transactions.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Transactions.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Transactions.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Transactions.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ValueTuple.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ValueTuple.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.ValueTuple.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.ValueTuple.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Web.HttpUtility.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Web.HttpUtility.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Web.HttpUtility.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Web.HttpUtility.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Web.HttpUtility.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Web.HttpUtility.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Web.HttpUtility.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Web.HttpUtility.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Web.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Web.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Web.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Web.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Windows.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Windows.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Windows.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Windows.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.Linq.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.Linq.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.Linq.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.Linq.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.ReaderWriter.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.ReaderWriter.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.ReaderWriter.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.ReaderWriter.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.ReaderWriter.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.ReaderWriter.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.ReaderWriter.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.ReaderWriter.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.Serialization.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.Serialization.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.Serialization.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.Serialization.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XDocument.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XDocument.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XDocument.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XDocument.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XDocument.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XDocument.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XDocument.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XDocument.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.XDocument.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.XDocument.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.XDocument.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.XDocument.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.XDocument.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.XDocument.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.XDocument.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.XDocument.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XPath.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XPath.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XmlDocument.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XmlDocument.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XmlDocument.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XmlDocument.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XmlSerializer.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XmlSerializer.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XmlSerializer.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XmlSerializer.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XmlSerializer.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XmlSerializer.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.XmlSerializer.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.XmlSerializer.xml diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.Xml.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.Xml.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/System.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/System.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/System.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/System.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/WindowsBase.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/WindowsBase.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/WindowsBase.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/WindowsBase.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/mscorlib.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/mscorlib.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/mscorlib.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/mscorlib.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/netstandard.dll b/pkg/Tizen.NET.API12/build/tizen11.0/ref/netstandard.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/netstandard.dll rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/netstandard.dll diff --git a/pkg/Tizen.NET.API11/build/tizen11.0/ref/netstandard.xml b/pkg/Tizen.NET.API12/build/tizen11.0/ref/netstandard.xml old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/build/tizen11.0/ref/netstandard.xml rename to pkg/Tizen.NET.API12/build/tizen11.0/ref/netstandard.xml diff --git a/pkg/Tizen.NET.API11/design/Tizen.NUI.Components.Design.dll b/pkg/Tizen.NET.API12/design/Tizen.NUI.Components.Design.dll similarity index 100% rename from pkg/Tizen.NET.API11/design/Tizen.NUI.Components.Design.dll rename to pkg/Tizen.NET.API12/design/Tizen.NUI.Components.Design.dll diff --git a/pkg/Tizen.NET.API11/design/Tizen.NUI.Design.dll b/pkg/Tizen.NET.API12/design/Tizen.NUI.Design.dll similarity index 100% rename from pkg/Tizen.NET.API11/design/Tizen.NUI.Design.dll rename to pkg/Tizen.NET.API12/design/Tizen.NUI.Design.dll diff --git a/pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.Mdb.dll b/pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.Mdb.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.Mdb.dll rename to pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.Mdb.dll diff --git a/pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.Pdb.dll b/pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.Pdb.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.Pdb.dll rename to pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.Pdb.dll diff --git a/pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.Rocks.dll b/pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.Rocks.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.Rocks.dll rename to pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.Rocks.dll diff --git a/pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.dll b/pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/Mono.Cecil.dll rename to pkg/Tizen.NET.API12/xamlbuild/Mono.Cecil.dll diff --git a/pkg/Tizen.NET.API11/xamlbuild/System.CodeDom.dll b/pkg/Tizen.NET.API12/xamlbuild/System.CodeDom.dll old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/System.CodeDom.dll rename to pkg/Tizen.NET.API12/xamlbuild/System.CodeDom.dll diff --git a/pkg/Tizen.NET.API11/xamlbuild/Tizen.NUI.XamlBuild.dll b/pkg/Tizen.NET.API12/xamlbuild/Tizen.NUI.XamlBuild.dll similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/Tizen.NUI.XamlBuild.dll rename to pkg/Tizen.NET.API12/xamlbuild/Tizen.NUI.XamlBuild.dll diff --git a/pkg/Tizen.NET.API11/xamlbuild/Tizen.NUI.XamlBuild.props b/pkg/Tizen.NET.API12/xamlbuild/Tizen.NUI.XamlBuild.props old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/Tizen.NUI.XamlBuild.props rename to pkg/Tizen.NET.API12/xamlbuild/Tizen.NUI.XamlBuild.props diff --git a/pkg/Tizen.NET.API11/xamlbuild/Tizen.NUI.XamlBuild.targets b/pkg/Tizen.NET.API12/xamlbuild/Tizen.NUI.XamlBuild.targets old mode 100755 new mode 100644 similarity index 100% rename from pkg/Tizen.NET.API11/xamlbuild/Tizen.NUI.XamlBuild.targets rename to pkg/Tizen.NET.API12/xamlbuild/Tizen.NUI.XamlBuild.targets diff --git a/test/NUITizenGallery/NUITizenGallery.csproj b/test/NUITizenGallery/NUITizenGallery.csproj index 31dd075b268..a99dc198270 100755 --- a/test/NUITizenGallery/NUITizenGallery.csproj +++ b/test/NUITizenGallery/NUITizenGallery.csproj @@ -33,6 +33,6 @@ - + From d388a7f68b9e8abf4f3d2661118285d50dc4d0dc Mon Sep 17 00:00:00 2001 From: Jay Cho Date: Tue, 10 Oct 2023 14:05:46 +0900 Subject: [PATCH 37/82] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 05305e127ef..34c2ad4be2c 100644 --- a/README.md +++ b/README.md @@ -94,4 +94,5 @@ You can download the latest binaries with TizenFX from the link below : | Tizen 6.0 | http://download.tizen.org/snapshots/TIZEN/Tizen-6.0/Tizen-6.0-Unified/latest/ | | Tizen 6.5 | http://download.tizen.org/snapshots/TIZEN/Tizen-6.5/Tizen-6.5-Unified/latest/ | | Tizen 7.0 | http://download.tizen.org/snapshots/TIZEN/Tizen-7.0/Tizen-7.0-Unified/latest/ | -| Tizen 8.0 | http://download.tizen.org/snapshots/TIZEN/Tizen/Tizen-Unified/ | +| Tizen 8.0 | http://download.tizen.org/snapshots/TIZEN/Tizen-8.0/Tizen-8.0-Unified/latest/ | +| Tizen 9.0 | http://download.tizen.org/snapshots/TIZEN/Tizen/Tizen-Unified/latest | From 417dbaa5b3aa602d8dba97c9da00962a0d89b7a3 Mon Sep 17 00:00:00 2001 From: Jay Cho Date: Tue, 10 Oct 2023 14:08:41 +0900 Subject: [PATCH 38/82] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 34c2ad4be2c..8c31a49867f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ TizenFX API, which allows you to access platform-specific features not covered b | Branch | API Level | Target Framework | API Reference | Platform | myget.org | nuget.org | |--------|:---------:|------------------|---------------|-------------------|-----------|------------| |master | 12 | net6.0-tizen9.0 | [Link](https://samsung.github.io/TizenFX/master/) | Tizen vNext | [![api12_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API12.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | | -|API11 | 11 | net6.0-tizen8.0 | [Link](https://samsung.github.io/TizenFX/master/) | Tizen 8.0 | [![api11_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API11.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | | +|API11 | 11 | net6.0-tizen8.0 | [Link](https://samsung.github.io/TizenFX/API11/) | Tizen 8.0 | [![api11_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API11.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | | |API10 | 10 | tizen10.0 | [Link](https://samsung.github.io/TizenFX/API10/) | Tizen 7.0 | [![api10_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API10.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | [![api10_nuget](https://img.shields.io/nuget/v/Tizen.NET.API10.svg)](https://www.nuget.org/packages/Tizen.NET/) | |API9 | 9 | tizen90 | [Link](https://samsung.github.io/TizenFX/API9/) | Tizen 6.5 | [![api9_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API9.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | [![api9_nuget](https://img.shields.io/nuget/v/Tizen.NET.API9.svg)](https://www.nuget.org/packages/Tizen.NET/) | |API8 | 8 | tizen80 | [Link](https://samsung.github.io/TizenFX/API8/) | Tizen 6.0 | [![api8_myget](https://img.shields.io/tizen.myget/dotnet/vpre/Tizen.NET.API8.svg)](https://tizen.myget.org/feed/dotnet/package/nuget/Tizen.NET) | [![api8_nuget](https://img.shields.io/nuget/v/Tizen.NET.API8.svg)](https://www.nuget.org/packages/Tizen.NET/) | From 781fa26376c3fed146d536173ebe8094fb80ebfa Mon Sep 17 00:00:00 2001 From: priyakohl <114220343+priyakohl@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:08:12 +0530 Subject: [PATCH 39/82] Deprecating Tizen.Location.Geofence APIs (#5598) * Deprecating Tizen.Location.Geofence APIs Signed-off-by: Priya Kohli * Removing type Signed-off-by: Priya Kohli * Indentation fixes Signed-off-by: Priya Kohli * Modified Note Signed-off-by: Priya Kohli --------- Signed-off-by: Priya Kohli Co-authored-by: randeepsingh01 <49635973+randeepsingh01@users.noreply.github.com> --- .../Tizen.Location.Geofence/Fence.cs | 14 ++++++++++++++ .../Tizen.Location.Geofence/FenceData.cs | 10 ++++++++++ .../Tizen.Location.Geofence/FenceStatus.cs | 6 ++++++ .../Tizen.Location.Geofence/GeofenceEnum.cs | 7 +++++++ .../GeofenceErrorFactory.cs | 1 + .../Tizen.Location.Geofence/GeofenceEventArgs.cs | 12 ++++++++++++ .../Tizen.Location.Geofence/GeofenceManager.cs | 10 ++++++++++ .../Tizen.Location.Geofence/VirtualPerimeter.cs | 11 +++++++++++ .../doc/api/Tizen.Location.Geofence.md | 4 ++++ 9 files changed, 75 insertions(+) diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs index 60ae5834b0f..56c8ce7aed3 100755 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/Fence.cs @@ -31,6 +31,7 @@ namespace Tizen.Location.Geofence /// and the manufacturer's assigned 24-bit identifier for the radio chipset in the WAP. ///

/// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class Fence : IDisposable { private bool _disposed = false; @@ -59,6 +60,7 @@ internal Fence(IntPtr handle) /// Gets the type of geofence. ///
/// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public FenceType Type { get @@ -78,6 +80,7 @@ public FenceType Type /// Gets the ID of the place. ///
/// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int PlaceId { get @@ -97,6 +100,7 @@ public int PlaceId /// Gets the longitude of geofence. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public double Longitude { get @@ -117,6 +121,7 @@ public double Longitude /// Gets the latitude of geofence. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public double Latitude { get @@ -136,6 +141,7 @@ public double Latitude /// Gets the radius of geofence. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int Radius { get @@ -155,6 +161,7 @@ public int Radius /// Gets the address of geofence. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string Address { get @@ -174,6 +181,7 @@ public string Address /// Gets the BSSID of geofence. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string Bssid { get @@ -193,6 +201,7 @@ public string Bssid /// Gets the SSID of geofence. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string Ssid { get @@ -221,6 +230,7 @@ public string Ssid /// In case of an invalid parameter. /// In case of any system error. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public static Fence CreateGPSFence(int placeId, double latitude, double longitude, int radius, string address) { IntPtr handle = IntPtr.Zero; @@ -244,6 +254,7 @@ public static Fence CreateGPSFence(int placeId, double latitude, double longitud /// In case of an invalid parameter. /// In case of any system error. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public static Fence CreateWifiFence(int placeId, string bssid, string ssid) { IntPtr handle = IntPtr.Zero; @@ -267,6 +278,7 @@ public static Fence CreateWifiFence(int placeId, string bssid, string ssid) /// In case of an invalid parameter. /// In case of any system error. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public static Fence CreateBTFence(int placeId, string bssid, string ssid) { IntPtr handle = IntPtr.Zero; @@ -283,6 +295,7 @@ public static Fence CreateBTFence(int placeId, string bssid, string ssid) /// The overloaded Dispose API for destroying the fence handle. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public void Dispose() { Dispose(true); @@ -293,6 +306,7 @@ public void Dispose() /// Dispose. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] protected virtual void Dispose(bool disposing) { if (_disposed) diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs index d328f4e4f64..10442195c56 100755 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceData.cs @@ -21,6 +21,7 @@ namespace Tizen.Location.Geofence /// Represents the geofence list item data. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class FenceData { internal FenceData(int fenceId, IntPtr handle, int index, int count) @@ -34,6 +35,7 @@ internal FenceData(int fenceId, IntPtr handle, int index, int count) /// The geofence instance. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public Fence Fence { get; @@ -44,6 +46,7 @@ public Fence Fence /// The geofence ID. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int GeofenceId { get; @@ -55,6 +58,7 @@ public int GeofenceId /// /// 3 /// The index value starts from 1. + [Obsolete("Deprecated since API11. Might be removed in API13")] public int Index { get; @@ -65,6 +69,7 @@ public int Index /// The total number of fences that exists for the requester. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int Count { get; @@ -76,6 +81,7 @@ public int Count /// Represents the place list item data. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class PlaceData { internal PlaceData(int id, string name, int index, int count) @@ -89,6 +95,7 @@ internal PlaceData(int id, string name, int index, int count) /// The current place ID. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int PlaceId { get; @@ -99,6 +106,7 @@ public int PlaceId /// The current place name. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string Name { get; @@ -110,6 +118,7 @@ public string Name /// /// 3 /// The index value starts from 1. + [Obsolete("Deprecated since API11. Might be removed in API13")] public int Index { get; @@ -120,6 +129,7 @@ public int Index /// The total number of places that exists for the requester. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int Count { get; diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs index 23c0efb12f7..0012cb13c59 100644 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/FenceStatus.cs @@ -26,6 +26,7 @@ namespace Tizen.Location.Geofence /// /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class FenceStatus : IDisposable { private bool _disposed = false; @@ -43,6 +44,7 @@ internal IntPtr Handle /// The geofence ID. /// In case of an invalid parameter. /// In case of geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public FenceStatus(int fenceId) { IntPtr handle; @@ -69,6 +71,7 @@ public FenceStatus(int fenceId) /// /// 3 /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public GeofenceState State { get @@ -89,6 +92,7 @@ public GeofenceState State /// /// 3 /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public int Duration { get @@ -108,6 +112,7 @@ public int Duration /// The overloaded Dispose API for destroying the fence handle. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public void Dispose() { Dispose(true); @@ -118,6 +123,7 @@ public void Dispose() /// Dispose. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] protected virtual void Dispose(bool disposing) { if (_disposed) diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs index 9f18ecabd90..48c5601f3c6 100755 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEnum.cs @@ -14,12 +14,15 @@ * limitations under the License. */ +using System; + namespace Tizen.Location.Geofence { /// /// Enumeration for the geofence types. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public enum FenceType { /// @@ -45,6 +48,7 @@ public enum FenceType /// Enumeration for the state of geofence. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public enum GeofenceState { /// @@ -70,6 +74,7 @@ public enum GeofenceState /// Enumeration for the geofence management events. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public enum GeofenceEventType { /// @@ -131,6 +136,7 @@ public enum GeofenceEventType /// Enumeration for the provider of proximity. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public enum ProximityProvider { /// @@ -168,6 +174,7 @@ public enum ProximityProvider /// Enumeration for the state of proximity. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public enum ProximityState { /// diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs index a48e0074913..42f0ea1dbe7 100755 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceErrorFactory.cs @@ -24,6 +24,7 @@ namespace Tizen.Location.Geofence /// Enumeration for the types of error occured, if any. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public enum GeofenceError { /// diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs index b16ee117cac..dd5bbffc300 100755 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceEventArgs.cs @@ -22,6 +22,7 @@ namespace Tizen.Location.Geofence /// Event arguments are passed when an event is triggered to notify the proximity state change. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class ProximityStateEventArgs : EventArgs { /// @@ -42,6 +43,7 @@ internal ProximityStateEventArgs(int id, ProximityState state, ProximityProvider /// The geofence ID. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int GeofenceId { get; @@ -51,6 +53,7 @@ public int GeofenceId /// The proximity state. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public ProximityState State { get; @@ -60,6 +63,7 @@ public ProximityState State /// The proximity provider. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public ProximityProvider Provider { get; @@ -70,6 +74,7 @@ public ProximityProvider Provider /// Event arguments are passed when an event is triggered to notify the geofence state change. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class GeofenceStateEventArgs : EventArgs { /// @@ -88,6 +93,7 @@ internal GeofenceStateEventArgs(int fenceId, GeofenceState state) /// The specified geofence ID. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int GeofenceId { get; @@ -97,6 +103,7 @@ public int GeofenceId /// The geofence state. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public GeofenceState State { get; @@ -107,6 +114,7 @@ public GeofenceState State /// Event arguments are passed when an event occurs in geofence and the place, such as add, update, etc.. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class GeofenceResponseEventArgs : EventArgs { /// @@ -129,6 +137,7 @@ internal GeofenceResponseEventArgs(int placeId, int fenceId, GeofenceError error /// The place ID. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int PlaceId { get; @@ -138,6 +147,7 @@ public int PlaceId /// The specified geofence ID. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public int FenceId { get; @@ -147,6 +157,7 @@ public int FenceId /// The error code for the particular action. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public GeofenceError ErrorCode { get; @@ -156,6 +167,7 @@ public GeofenceError ErrorCode /// The result code for the particular place and geofence management. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public GeofenceEventType EventType { get; diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs index 6019721ff48..11f683e05ba 100755 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/GeofenceManager.cs @@ -36,6 +36,7 @@ namespace Tizen.Location.Geofence /// /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class GeofenceManager : IDisposable { private bool _disposed = false; @@ -53,6 +54,7 @@ internal IntPtr Handle /// In case of out of memory condition. /// In case of any system error. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public GeofenceManager() { IntPtr handle; @@ -78,6 +80,7 @@ public GeofenceManager() /// Checks whether the Geofence manager is available or not. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public static bool IsSupported { get @@ -106,6 +109,7 @@ public static bool IsSupported /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public void Start(int geofenceId) { GeofenceError ret = (GeofenceError)Interop.GeofenceManager.Start(Handle, geofenceId); @@ -129,6 +133,7 @@ public void Start(int geofenceId) /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public void Stop(int geofenceId) { GeofenceError ret = (GeofenceError)Interop.GeofenceManager.Stop(Handle, geofenceId); @@ -155,6 +160,7 @@ public void Stop(int geofenceId) /// Call to Start() will invoke this event. /// /// In case the feature is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public event EventHandler StateChanged { add @@ -200,6 +206,7 @@ public event EventHandler StateChanged /// Call to Start() will invoke this event. /// /// In case the feature is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public event EventHandler ProximityChanged { add @@ -247,6 +254,7 @@ public event EventHandler ProximityChanged /// The value of place_id or geofence_id is -1 when the place ID or geofence ID is not assigned. /// /// In case the feature is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public event EventHandler GeofenceEventChanged { add @@ -279,6 +287,7 @@ public event EventHandler GeofenceEventChanged /// The overloaded Dispose API for destroying the GeofenceManager handle. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public void Dispose() { Dispose(true); @@ -289,6 +298,7 @@ public void Dispose() /// Dispose. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] protected virtual void Dispose(bool disposing) { if (_disposed) diff --git a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs index 3923657bcad..7a3f95f08e4 100755 --- a/src/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs +++ b/src/Tizen.Location.Geofence/Tizen.Location.Geofence/VirtualPerimeter.cs @@ -24,6 +24,7 @@ namespace Tizen.Location.Geofence /// A user can manage all the geofence or place related data and events. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class VirtualPerimeter { private IntPtr Handle; @@ -34,6 +35,7 @@ public class VirtualPerimeter /// 3 /// The GeofenceManager instance. /// In case of an invalid parameter. + [Obsolete("Deprecated since API11. Might be removed in API13")] public VirtualPerimeter(GeofenceManager manager) { if (manager == null) @@ -57,6 +59,7 @@ public VirtualPerimeter(GeofenceManager manager) /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public int AddPlaceName(string name) { int placeId = 0; @@ -80,6 +83,7 @@ public int AddPlaceName(string name) /// In case of any System error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public void UpdatePlace(int placeId, string name) { GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.UpdatePlace(Handle, placeId, name); @@ -99,6 +103,7 @@ public void UpdatePlace(int placeId, string name) /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public void RemovePlace(int placeId) { GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.RemovePlace(Handle, placeId); @@ -120,6 +125,7 @@ public void RemovePlace(int placeId) /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public int AddGeofence(Fence fence) { int fenceId = 0; @@ -142,6 +148,7 @@ public int AddGeofence(Fence fence) /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public void RemoveGeofence(int fenceId) { GeofenceError ret = (GeofenceError)Interop.VirtualPerimeter.RemoveFence(Handle, fenceId); @@ -162,6 +169,7 @@ public void RemoveGeofence(int fenceId) /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public string GetPlaceName(int placeId) { string name = ""; @@ -183,6 +191,7 @@ public string GetPlaceName(int placeId) /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public IEnumerable GetPlaceDataList() { List places = new List(); @@ -214,6 +223,7 @@ public IEnumerable GetPlaceDataList() /// In case of any system error. /// In case privileges are not defined. /// In case geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public IEnumerable GetFenceDataList() { List fences = new List(); @@ -247,6 +257,7 @@ public IEnumerable GetFenceDataList() /// In case of any system error. /// In case privileges are not defined. /// In case the geofence is not supported. + [Obsolete("Deprecated since API11. Might be removed in API13")] public IEnumerable GetGeofenceDataListByPlaceId(int placeId) { List fences = new List(); diff --git a/src/Tizen.Location.Geofence/doc/api/Tizen.Location.Geofence.md b/src/Tizen.Location.Geofence/doc/api/Tizen.Location.Geofence.md index 6d992aee60e..56a923499a7 100755 --- a/src/Tizen.Location.Geofence/doc/api/Tizen.Location.Geofence.md +++ b/src/Tizen.Location.Geofence/doc/api/Tizen.Location.Geofence.md @@ -4,6 +4,10 @@ summary: The Tizen.Location.Geofence namespace provides classes for virtual peri remarks: *content --- ## Overview + +> [!NOTE] +> All Geofence APIs have been deprecated since Tizen 8.0 (API Level 11) which means they are planned to be removed after two releases. + This API provides functions to set the gofence with a geopoint, MAC address of Wi-Fi, and Bluetooth address. Also, notifications on events like changing in service status are provided. From b7950e875f91cdc4b0c50d6106f138ae5b438e92 Mon Sep 17 00:00:00 2001 From: ChangGyu Choi Date: Thu, 12 Oct 2023 09:13:23 +0900 Subject: [PATCH 40/82] [Tdbc] Fix UpdateHookCallback released issue (#5528) The issue is that if you don't keep a reference to the UpdateHookCallback, it may be garbage collected before it is used. UpdateHookCallback should be referenced during used this. Signed-off-by: Changgyu Choi Co-authored-by: pjh9216 --- .../Tizen.Data.Tdbc.Driver.Sqlite/Connection.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Tizen.Data.Tdbc.Driver.Sqlite/Tizen.Data.Tdbc.Driver.Sqlite/Connection.cs b/src/Tizen.Data.Tdbc.Driver.Sqlite/Tizen.Data.Tdbc.Driver.Sqlite/Connection.cs index b1463f6ba44..5518e21f540 100644 --- a/src/Tizen.Data.Tdbc.Driver.Sqlite/Tizen.Data.Tdbc.Driver.Sqlite/Connection.cs +++ b/src/Tizen.Data.Tdbc.Driver.Sqlite/Tizen.Data.Tdbc.Driver.Sqlite/Connection.cs @@ -28,7 +28,7 @@ internal class Connection : IConnection private bool disposedValue; private readonly object _lock = new object(); private EventHandler _recordChanged; - + private Interop.Sqlite.UpdateHookCallback _hook; static Connection() { @@ -70,6 +70,7 @@ public void Close() Interop.Sqlite.UpdateHook(_db, null, IntPtr.Zero); Interop.Sqlite.Close(_db); _opened = false; + _hook = null; } } @@ -154,7 +155,12 @@ public void Open(Uri uri) if (ret != (int)Interop.Sqlite.ResultCode.SQLITE_OK) throw new InvalidOperationException("code:" + ret); - Interop.Sqlite.UpdateHook(_db, UpdateHookCallback, IntPtr.Zero); + if (_hook == null) + { + _hook = new Interop.Sqlite.UpdateHookCallback(UpdateHookCallback); + } + + Interop.Sqlite.UpdateHook(_db, _hook, IntPtr.Zero); _opened = true; } From 8f0787efa9f736a6b2b606c3a6835eb0890f9f1e Mon Sep 17 00:00:00 2001 From: Yunhee Seo Date: Thu, 12 Oct 2023 16:44:39 +0900 Subject: [PATCH 41/82] [System.Feedback] Add new feedback_pattern Below feedback pattern is supported by mapping feedback pattern id number. - FEEDBACK_PATTERN_WELCOME - FEEDBACK_PATTERN_AUTO_DOOR_OPEN Signed-off-by: Yunhee Seo --- src/Tizen.System.Feedback/Feedback/Feedback.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tizen.System.Feedback/Feedback/Feedback.cs b/src/Tizen.System.Feedback/Feedback/Feedback.cs index 306a80dea8a..1ada6727155 100755 --- a/src/Tizen.System.Feedback/Feedback/Feedback.cs +++ b/src/Tizen.System.Feedback/Feedback/Feedback.cs @@ -337,6 +337,8 @@ public class Feedback {"BurnerMoved", 40030}, {"Connected", 40031}, {"Disconnected", 40032}, + {"Welcome", 40033}, + {"AutoDoorOpen", 40034}, }; /// From 193e03d15a598082c07b8607c02edec212b7aa01 Mon Sep 17 00:00:00 2001 From: priyakohl <114220343+priyakohl@users.noreply.github.com> Date: Mon, 16 Oct 2023 17:07:35 +0530 Subject: [PATCH 42/82] Deprecating Tizen.Messaging.Email APIs (#5596) * Deprecating Tizen.Messaging.Email APIs Signed-off-by: Priya Kohli * Added using System Signed-off-by: Priya Kohli * Modified Note Signed-off-by: Priya Kohli --------- Signed-off-by: Priya Kohli Co-authored-by: randeepsingh01 <49635973+randeepsingh01@users.noreply.github.com> --- .../Tizen.Messaging.Email/EmailAttachment.cs | 5 +++++ .../Tizen.Messaging.Email/EmailEnumerations.cs | 3 +++ .../Tizen.Messaging.Email/EmailMessage.cs | 10 ++++++++++ .../Tizen.Messaging.Email/EmailRecipient.cs | 5 +++++ .../Tizen.Messaging.Email/EmailSender.cs | 2 ++ src/Tizen.Messaging/doc/api/Tizen.Messaging.Email.md | 4 ++++ 6 files changed, 29 insertions(+) diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs index b561ddca1af..9f3a44dccc7 100644 --- a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailAttachment.cs @@ -14,23 +14,28 @@ * limitations under the License. */ +using System; + namespace Tizen.Messaging.Email { /// /// Represents an email attachment. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class EmailAttachment { /// /// The absolute full path of the file to be attached. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string FilePath { get; set; } /// /// The constructor. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public EmailAttachment() { diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs index 36d31171ec0..13a58b5bf76 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailEnumerations.cs @@ -14,12 +14,15 @@ * limitations under the License. */ +using System; + namespace Tizen.Messaging.Email { /// /// Result of sending the email. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public enum EmailSendResult { /// diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs index 65306b00a6a..664d41ff001 100644 --- a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailMessage.cs @@ -24,6 +24,7 @@ namespace Tizen.Messaging.Email /// This class contains the Messaging API to support sending email messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class EmailMessage : IDisposable { internal IntPtr _emailHandle = IntPtr.Zero; @@ -39,6 +40,7 @@ public class EmailMessage : IDisposable /// The constructor. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public EmailMessage() { int ret = Interop.Email.CreateEmail(out _emailHandle); @@ -53,6 +55,7 @@ public EmailMessage() /// The subject of the email message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string Subject { set @@ -76,6 +79,7 @@ public string Subject /// The body of the email message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string Body { set @@ -98,6 +102,7 @@ public string Body /// The list of file attachments. /// /// 3 +[Obsolete("Deprecated since API11. Might be removed in API13")] public IList Attachments { get @@ -113,6 +118,7 @@ public IList Attachments /// The email address should be in the standard format (as described in the Internet standards RFC 5321 and RFC 5322). /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public ICollection To { get @@ -128,6 +134,7 @@ public ICollection To /// The email address should be in the standard format (as described in the Internet standards RFC 5321 and RFC 5322). /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public ICollection Cc { get @@ -143,6 +150,7 @@ public ICollection Cc /// The email address should be in the standard format (as described in the Internet standards RFC 5321 and RFC 5322). /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public ICollection Bcc { get @@ -169,6 +177,7 @@ internal void Save() /// Releases all resources used by the EmailMessage. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public void Dispose() { Dispose(true); @@ -180,6 +189,7 @@ public void Dispose() /// /// Disposing by User /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] protected virtual void Dispose(bool disposing) { if (_disposed) diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs index 69ff5039e06..c5ca528a19e 100644 --- a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailRecipient.cs @@ -14,23 +14,28 @@ * limitations under the License. */ +using System; + namespace Tizen.Messaging.Email { /// /// This class represents recipients of an email. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public class EmailRecipient { /// /// The email address of the recipient. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public string Address { get; set; } /// /// The constructor. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public EmailRecipient() { diff --git a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs index 3d60634e1c6..648c0340251 100644 --- a/src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Email/EmailSender.cs @@ -24,6 +24,7 @@ namespace Tizen.Messaging.Email /// This class is used to send email messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public static class EmailSender { static private Dictionary _sendCbMap = new Dictionary(); @@ -35,6 +36,7 @@ public static class EmailSender /// The email message. /// Failure if the email sending activity failed, otherwise Success. /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13")] public static async Task SendAsync(EmailMessage email) { var task = new TaskCompletionSource(); diff --git a/src/Tizen.Messaging/doc/api/Tizen.Messaging.Email.md b/src/Tizen.Messaging/doc/api/Tizen.Messaging.Email.md index def7ad1a8ca..20585513e2e 100644 --- a/src/Tizen.Messaging/doc/api/Tizen.Messaging.Email.md +++ b/src/Tizen.Messaging/doc/api/Tizen.Messaging.Email.md @@ -15,4 +15,8 @@ uid: Tizen.Messaging.Email summary: The Tizen.Messaging.Email namespace contains classes providing the functionality to send emails. + +> [!NOTE] +> All Email APIs have been deprecated since Tizen 8.0 (API Level 11) which means they are planned to be removed after two releases. + --- From cd4f4e2b20cace812672f0e0f5e842ed2e6ecf78 Mon Sep 17 00:00:00 2001 From: hjhun <36876573+hjhun@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:40:33 +0900 Subject: [PATCH 43/82] Use Marshal.FreeHGlobal() instead of Libc.Free() (#5628) Signed-off-by: Hwankyu Jhun --- src/Tizen.Applications.Common/Interop/Interop.Libc.cs | 3 --- .../Tizen.Applications/AppControl.cs | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Tizen.Applications.Common/Interop/Interop.Libc.cs b/src/Tizen.Applications.Common/Interop/Interop.Libc.cs index 81aacdd73c9..09c256e7db9 100644 --- a/src/Tizen.Applications.Common/Interop/Interop.Libc.cs +++ b/src/Tizen.Applications.Common/Interop/Interop.Libc.cs @@ -23,9 +23,6 @@ internal static partial class Interop { internal static partial class Libc { - [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)] - internal static extern int Free(IntPtr ptr); - [DllImport(Libraries.Libc, EntryPoint = "getenv")] internal static extern IntPtr GetEnvironmentVariable(string name); diff --git a/src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs b/src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs index 3bd02e21ef6..60c213fb4d7 100755 --- a/src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs +++ b/src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs @@ -1335,9 +1335,9 @@ public bool TryGet(string key, out IEnumerable value) { IntPtr charArr = Marshal.ReadIntPtr(valuePtr, IntPtr.Size * i); stringList.Add(Marshal.PtrToStringAnsi(charArr)); - _ = Interop.Libc.Free(charArr); + Marshal.FreeHGlobal(charArr); } - _ = Interop.Libc.Free(valuePtr); + Marshal.FreeHGlobal(valuePtr); value = stringList; return true; } @@ -1491,9 +1491,9 @@ private IEnumerable GetDataCollection(string key) { IntPtr charArr = Marshal.ReadIntPtr(valuePtr, IntPtr.Size * i); valueArray.Add(Marshal.PtrToStringAnsi(charArr)); - _ = Interop.Libc.Free(charArr); + Marshal.FreeHGlobal(charArr); } - _ = Interop.Libc.Free(valuePtr); + Marshal.FreeHGlobal(valuePtr); } return valueArray; } From 1f08093200cf36b3f04b5396947b60f6afeec7ef Mon Sep 17 00:00:00 2001 From: hjhun <36876573+hjhun@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:47:29 +0900 Subject: [PATCH 44/82] Change visibility of NUIGadgetResourceManager ctor (#5626) The visibility of NUIGadgetResourceManager(NUIGadgetInfo info) is changed to public. Signed-off-by: Hwankyu Jhun --- .../Tizen.NUI/NUIGadgetResourceManager.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetResourceManager.cs b/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetResourceManager.cs index d9e34708d72..2bb42eb1835 100755 --- a/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetResourceManager.cs +++ b/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetResourceManager.cs @@ -36,8 +36,19 @@ public class NUIGadgetResourceManager private readonly string _resourceClassName; private readonly IDictionary _resourceMap = new Dictionary(); - internal NUIGadgetResourceManager(NUIGadgetInfo info) + /// + /// Initializes the resource manager of the gadget. + /// + /// The information of the gadget. + /// Thrown when failed because of a invalid argument. + /// 11 + public NUIGadgetResourceManager(NUIGadgetInfo info) { + if (info == null) + { + throw new ArgumentNullException(nameof(info)); + } + _resourcePath = info.ResourcePath; _resourceDll = info.ResourceFile; _resourceClassName = info.ResourceClassName; From 257a36812ec2ef31f776d1ebe0f99471879618dc Mon Sep 17 00:00:00 2001 From: k-jaju <146075929+k-jaju@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:27:03 +0530 Subject: [PATCH 45/82] Deprecating Tizen.Messaging.Messages APIs (#5593) Signed-off-by: Krishna Kant Jaju Co-authored-by: randeepsingh01 <49635973+randeepsingh01@users.noreply.github.com> --- .../Tizen.Messaging.Messages/CBMessage.cs | 1 + src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs | 9 +++++++++ .../Tizen.Messaging.Messages/MessageReceivedEventArgs.cs | 2 ++ .../Tizen.Messaging.Messages/MessagesAddress.cs | 3 +++ .../Tizen.Messaging.Messages/MessagesAttachment.cs | 5 +++++ .../Tizen.Messaging.Messages/MessagesEnumerations.cs | 6 ++++++ .../Tizen.Messaging.Messages/MessagesManager.cs | 4 ++++ .../Tizen.Messaging.Messages/MessagesSearchFilter.cs | 7 +++++++ .../Tizen.Messaging.Messages/MmsMessage.cs | 7 +++++++ .../Tizen.Messaging.Messages/PushMessage.cs | 1 + .../Tizen.Messaging.Messages/SmsMessage.cs | 3 +++ src/Tizen.Messaging/doc/api/Tizen.Messaging.Messages.md | 3 +++ 12 files changed, 51 insertions(+) diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs index 08ddae8a9e2..1a24ef0c4f9 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/CBMessage.cs @@ -22,6 +22,7 @@ namespace Tizen.Messaging.Messages /// This class represents the cell broadcast messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class CBMessage : Message { internal CBMessage(IntPtr messageHandle) : base(messageHandle) diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs index c2c2a28f7dc..3ac8630b293 100644 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/Message.cs @@ -24,6 +24,7 @@ namespace Tizen.Messaging.Messages /// This class represents all the messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public abstract class Message : IDisposable { internal IntPtr _messageHandle = IntPtr.Zero; @@ -72,6 +73,7 @@ internal void FillHandle() /// Releases all resources used by the Message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public void Dispose() { Dispose(true); @@ -189,6 +191,7 @@ private void GetAllAddresses() /// After creating the Message object, the default value of this property is 0. After sending, this value is changed. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public int Id { get @@ -208,6 +211,7 @@ public int Id /// The destination port of the message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public int Port { get @@ -227,6 +231,7 @@ public int Port /// The message box type. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MessageBoxType BoxType { get @@ -255,6 +260,7 @@ public MessageBoxType BoxType /// The text of the message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public string Text { get @@ -283,6 +289,7 @@ public string Text /// The time of the message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public DateTime Time { get @@ -311,6 +318,7 @@ public DateTime Time /// The SIM slot index of the message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public SimSlotId SimId { get @@ -339,6 +347,7 @@ public SimSlotId SimId /// Indicates the sender of the message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public IReadOnlyCollection From { get diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs index c91c6019a36..25d60fffeb1 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessageReceivedEventArgs.cs @@ -22,6 +22,7 @@ namespace Tizen.Messaging.Messages /// An extended EventArgs class, which contains a received message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class MessageReceivedEventArgs : EventArgs { private Message _message; @@ -35,6 +36,7 @@ internal MessageReceivedEventArgs(Message message) /// The received message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public Message ReceivedMessage { get diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs index 74f834f10e0..8b03b5d4aae 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAddress.cs @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +using System; namespace Tizen.Messaging.Messages { @@ -20,6 +21,7 @@ namespace Tizen.Messaging.Messages /// This class is used to manage the information of the message address. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class MessagesAddress { internal RecipientType Type; @@ -34,6 +36,7 @@ public class MessagesAddress /// /// The recipient's address to receive a message. /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MessagesAddress(string number) { Number = number; diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs index d06d605b774..bfd4db6b23c 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesAttachment.cs @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +using System; namespace Tizen.Messaging.Messages { @@ -20,18 +21,21 @@ namespace Tizen.Messaging.Messages /// This class is used to manage the information of the message attachment. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class MessagesAttachment { /// /// The media type of the attachment. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MediaType Type { get; } /// /// The file path of the attachment. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public string FilePath { get; } /// @@ -40,6 +44,7 @@ public class MessagesAttachment /// The attachment's type. /// The file path to attach. /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MessagesAttachment(MediaType type, string filePath) { Type = type; diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs index f95ed7c3521..e6cc1f1e039 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesEnumerations.cs @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +using System; namespace Tizen.Messaging.Messages { @@ -20,6 +21,7 @@ namespace Tizen.Messaging.Messages /// Enumeration for the result of sending a message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public enum SentResult { /// @@ -36,6 +38,7 @@ public enum SentResult /// Enumeration for the message type. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public enum MessageType { /// @@ -64,6 +67,7 @@ public enum MessageType /// Enumeration for the message box type. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public enum MessageBoxType { /// @@ -92,6 +96,7 @@ public enum MessageBoxType /// Enumeration for the SIM slot index of a message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public enum SimSlotId { /// @@ -135,6 +140,7 @@ internal enum RecipientType /// Enumeration for the attachment type for the MMS messaging. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public enum MediaType { /// diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs index ce41df0f992..6349861cfcc 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesManager.cs @@ -25,6 +25,7 @@ namespace Tizen.Messaging.Messages /// /// http://tizen.org/privilege/message.read /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public static class MessagesManager { /// @@ -39,6 +40,7 @@ public static class MessagesManager /// Thrown when input coordinates are invalid. /// Thrown when an application does not have proper privileges. /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public static Task SendMessageAsync(Message message, bool saveToSentbox) { return MessagesManagerImpl.Instance.SendMessageAsync(message, saveToSentbox); @@ -56,6 +58,7 @@ public static Task SendMessageAsync(Message message, bool saveToSent /// Thrown when failed due to out of memory. /// Thrown when an application does not have proper privileges. /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public static Task> SearchMessageAsync(MessagesSearchFilter filter) { return MessagesManagerImpl.Instance.SearchMessageAsync(filter); @@ -66,6 +69,7 @@ public static Task> SearchMessageAsync(MessagesSearchFilter /// /// http://tizen.org/privilege/message.read /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] static public event EventHandler MessageReceived { add diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs index 44d7f54a463..03d7dbbd2cc 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MessagesSearchFilter.cs @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +using System; namespace Tizen.Messaging.Messages { @@ -20,12 +21,14 @@ namespace Tizen.Messaging.Messages /// This class represents message search filters. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class MessagesSearchFilter { /// /// Creates a search filter for searching messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MessagesSearchFilter() { } @@ -34,21 +37,25 @@ public MessagesSearchFilter() /// The message box type. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MessageBoxType MessageBoxType { get; set; } /// /// The message type. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MessageType MessageType { get; set; } /// /// The keyword to search in the text and the subject. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public string TextKeyword { get; set; } /// /// The recipient address. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public string AddressKeyword { get; set; } } } diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs index 83d9fdc6ae4..43a8d2ec539 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/MmsMessage.cs @@ -23,6 +23,7 @@ namespace Tizen.Messaging.Messages /// This class represents multimedia messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class MmsMessage : Message { private IList _attachment = new List(); @@ -31,6 +32,7 @@ public class MmsMessage : Message /// Creates a multimedia message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public MmsMessage() : base(MessageType.Mms) { } @@ -44,6 +46,7 @@ internal MmsMessage(IntPtr messageHandle) : base(messageHandle) /// The subject of the multimedia message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public string Subject { get @@ -72,6 +75,7 @@ public string Subject /// The collection of normal message recipients. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public ICollection To { get @@ -84,6 +88,7 @@ public ICollection To /// The collection of CC (carbon copy) message recipients. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public ICollection Cc { get @@ -96,6 +101,7 @@ public ICollection Cc /// The collection of BCC (blind carbon copy) message recipients. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public ICollection Bcc { get @@ -108,6 +114,7 @@ public ICollection Bcc /// The list of attachment files. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public IList Attachments { get diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs index eaca56ac516..2352ce5396d 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/PushMessage.cs @@ -22,6 +22,7 @@ namespace Tizen.Messaging.Messages /// This class represents the WAP push messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class PushMessage : Message { internal PushMessage(IntPtr messageHandle) : base(messageHandle) diff --git a/src/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs b/src/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs index 76f5b1d8f0f..4cdaf962372 100755 --- a/src/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs +++ b/src/Tizen.Messaging/Tizen.Messaging.Messages/SmsMessage.cs @@ -23,12 +23,14 @@ namespace Tizen.Messaging.Messages /// This class represents short text messages. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public class SmsMessage : Message { /// /// Creates a short text message. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public SmsMessage() : base(MessageType.Sms) { } @@ -41,6 +43,7 @@ internal SmsMessage(IntPtr messageHandle) : base(messageHandle) /// The collection of normal message recipients. /// /// 3 + [Obsolete("Deprecated since API11. Might be removed in API13.")] public ICollection To { get diff --git a/src/Tizen.Messaging/doc/api/Tizen.Messaging.Messages.md b/src/Tizen.Messaging/doc/api/Tizen.Messaging.Messages.md index 4036a109c6a..b2d0e619040 100644 --- a/src/Tizen.Messaging/doc/api/Tizen.Messaging.Messages.md +++ b/src/Tizen.Messaging/doc/api/Tizen.Messaging.Messages.md @@ -15,4 +15,7 @@ uid: Tizen.Messaging.Messages summary: The Tizen.Messaging.Messages namespace contains classes providing the functionality to send, receive, and search messages. + + > [!NOTE] + > All Messages APIs have been deprecated since Tizen 8.0 (API Level 11) which means they are planned to be removed after two releases. --- From f1981b6574110cf1cca5c132234271463ab44411 Mon Sep 17 00:00:00 2001 From: Seonah Moon <31679495+SeonahMoon@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:16:24 +0900 Subject: [PATCH 46/82] [Connection] Fix ASAN crash issue (#5625) --- .../Interop/Interop.Glib.cs | 27 +++++++++++++++++++ .../Interop/Interop.Libraries.cs | 1 + .../CellularProfile.cs | 4 +-- .../ConnectionInternalManager.cs | 6 ++--- .../ConnectionProfile.cs | 8 +++--- .../IAddressInformation.cs | 2 +- .../Tizen.Network.Connection/WiFiProfile.cs | 4 +-- 7 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 src/Tizen.Network.Connection/Interop/Interop.Glib.cs diff --git a/src/Tizen.Network.Connection/Interop/Interop.Glib.cs b/src/Tizen.Network.Connection/Interop/Interop.Glib.cs new file mode 100644 index 00000000000..a4961a70064 --- /dev/null +++ b/src/Tizen.Network.Connection/Interop/Interop.Glib.cs @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Glib + { + [DllImport(Libraries.Glib, EntryPoint = "g_free", CallingConvention = CallingConvention.Cdecl)] + internal static extern uint Free(IntPtr data); + } +} diff --git a/src/Tizen.Network.Connection/Interop/Interop.Libraries.cs b/src/Tizen.Network.Connection/Interop/Interop.Libraries.cs index e4c53178bc3..4963b1752eb 100644 --- a/src/Tizen.Network.Connection/Interop/Interop.Libraries.cs +++ b/src/Tizen.Network.Connection/Interop/Interop.Libraries.cs @@ -20,5 +20,6 @@ internal static partial class Libraries { public const string Connection = "libcapi-network-connection.so.1"; public const string Libc = "libc.so.6"; + public const string Glib = "libglib-2.0.so.0"; } } diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs index 91503be50de..7969f7ff6eb 100755 --- a/src/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs +++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/CellularProfile.cs @@ -63,7 +63,7 @@ public string Apn Log.Error(Globals.LogTag, "It failed to get apn, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(Value); - Interop.Libc.Free(Value); + Interop.Glib.Free(Value); return result; } @@ -112,7 +112,7 @@ public string HomeUri Log.Error(Globals.LogTag, "It failed to get home url, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(Value); - Interop.Libc.Free(Value); + Interop.Glib.Free(Value); return result; } diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs index a622a282278..637f3c0a52e 100644 --- a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs +++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionInternalManager.cs @@ -479,7 +479,7 @@ internal System.Net.IPAddress GetIPAddress(AddressFamily family) } string result = Marshal.PtrToStringAnsi(ip); - Interop.Libc.Free(ip); + Interop.Glib.Free(ip); Log.Info(Globals.LogTag, "IPAddress " + result + " (" + result.Length + ")"); if (result.Length == 0) { @@ -535,7 +535,7 @@ internal string GetProxy(AddressFamily family) } string result = Marshal.PtrToStringAnsi(ip); - Interop.Libc.Free(ip); + Interop.Glib.Free(ip); return result; } @@ -553,7 +553,7 @@ internal string GetMacAddress(ConnectionType type) } string result = Marshal.PtrToStringAnsi(mac); - Interop.Libc.Free(mac); + Interop.Glib.Free(mac); return result; } diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs index df518f9d2fd..362e10f57a1 100755 --- a/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs +++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/ConnectionProfile.cs @@ -196,7 +196,7 @@ public string Id Log.Error(Globals.LogTag, "It failed to get id of connection profile, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(Value); - Interop.Libc.Free(Value); + Interop.Glib.Free(Value); return result; } } @@ -217,7 +217,7 @@ public string Name Log.Error(Globals.LogTag, "It failed to get name of connection profile, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(Value); - Interop.Libc.Free(Value); + Interop.Glib.Free(Value); return result; } } @@ -257,7 +257,7 @@ public string InterfaceName Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(Value); - Interop.Libc.Free(Value); + Interop.Glib.Free(Value); return result; } } @@ -391,7 +391,7 @@ public string ProxyAddress Log.Error(Globals.LogTag, "It failed to get proxy address, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(Value); - Interop.Libc.Free(Value); + Interop.Glib.Free(Value); return result; } diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs index ec3ec8f0321..d9d50c22b63 100755 --- a/src/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs +++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/IAddressInformation.cs @@ -353,7 +353,7 @@ private System.Net.IPAddress ParseIPAddress(int ret, IntPtr addrPtr) string addr = Marshal.PtrToStringAnsi(addrPtr); if (addr == null || addr.Length == 0) return DefaultIPAddress(); - Interop.Libc.Free(addrPtr); + Interop.Glib.Free(addrPtr); return System.Net.IPAddress.Parse(addr); } diff --git a/src/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs b/src/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs index 6cfbc3337db..df370be5296 100755 --- a/src/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs +++ b/src/Tizen.Network.Connection/Tizen.Network.Connection/WiFiProfile.cs @@ -55,7 +55,7 @@ public string Essid Log.Error(Globals.LogTag, "It failed to create profile handle, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(value); - Interop.Libc.Free(value); + Interop.Glib.Free(value); return result; } } @@ -76,7 +76,7 @@ public string Bssid Log.Error(Globals.LogTag, "It failed to get bssid, " + (ConnectionError)ret); } string result = Marshal.PtrToStringAnsi(value); - Interop.Libc.Free(value); + Interop.Glib.Free(value); return result; } } From b95715b31b93740577c2769e43d8eaaf5cbc6bf4 Mon Sep 17 00:00:00 2001 From: hjhun <36876573+hjhun@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:38:58 +0900 Subject: [PATCH 47/82] Use Marshal.FreeHGlobal() instead of Libc.Free() (#5636) Signed-off-by: Hwankyu Jhun --- .../Interop/Interop.Libc.cs | 27 ------------------- .../Interop/Interop.Libraries.cs | 1 - .../Tizen.Content.MimeType/MimeUtil.cs | 4 +-- 3 files changed, 2 insertions(+), 30 deletions(-) delete mode 100755 src/Tizen.Content.MimeType/Interop/Interop.Libc.cs diff --git a/src/Tizen.Content.MimeType/Interop/Interop.Libc.cs b/src/Tizen.Content.MimeType/Interop/Interop.Libc.cs deleted file mode 100755 index 825599e274e..00000000000 --- a/src/Tizen.Content.MimeType/Interop/Interop.Libc.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Runtime.InteropServices; - -internal static partial class Interop -{ - internal static partial class Libc - { - [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)] - internal static extern int Free(IntPtr ptr); - } -} diff --git a/src/Tizen.Content.MimeType/Interop/Interop.Libraries.cs b/src/Tizen.Content.MimeType/Interop/Interop.Libraries.cs index 365b82e957e..aa8e2956396 100755 --- a/src/Tizen.Content.MimeType/Interop/Interop.Libraries.cs +++ b/src/Tizen.Content.MimeType/Interop/Interop.Libraries.cs @@ -20,6 +20,5 @@ internal static partial class Libraries { public const string Mime = "libcapi-content-mime-type.so.0"; public const string Glib = "libglib-2.0.so.0"; - public const string Libc = "libc.so.6"; } } diff --git a/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs b/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs index dfce9476d3b..02e45a37ab7 100644 --- a/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs +++ b/src/Tizen.Content.MimeType/Tizen.Content.MimeType/MimeUtil.cs @@ -86,9 +86,9 @@ public static IEnumerable GetFileExtension(string mime) foreach (IntPtr extension in extensionList) { coll.Add(Marshal.PtrToStringAnsi(extension)); - Interop.Libc.Free(extension); + Marshal.FreeHGlobal(extension); } - Interop.Libc.Free(extensionArray); + Marshal.FreeHGlobal(extensionArray); return coll; } From 333b0e473c3f12019c12e06bbb190c046958e110 Mon Sep 17 00:00:00 2001 From: Seonah Moon <31679495+SeonahMoon@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:04:48 +0900 Subject: [PATCH 48/82] [Nsd] Fix ASAN crash (#5632) --- src/Tizen.Network.Nsd/Interop/Interop.Nsd.cs | 6 ++++++ src/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Tizen.Network.Nsd/Interop/Interop.Nsd.cs b/src/Tizen.Network.Nsd/Interop/Interop.Nsd.cs index 87697b2e7d6..5e6bebbf391 100755 --- a/src/Tizen.Network.Nsd/Interop/Interop.Nsd.cs +++ b/src/Tizen.Network.Nsd/Interop/Interop.Nsd.cs @@ -119,4 +119,10 @@ internal static partial class Libc [DllImport(Libraries.Libc, EntryPoint = "free")] public static extern void Free(IntPtr userData); } + + internal static partial class Glib + { + [DllImport(Libraries.Glib, EntryPoint = "g_free", CallingConvention = CallingConvention.Cdecl)] + public static extern void Free(IntPtr userData); + } } diff --git a/src/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs b/src/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs index 494a726c8d0..19049b3ce73 100755 --- a/src/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs +++ b/src/Tizen.Network.Nsd/Tizen.Network.Nsd/DnssdService.cs @@ -241,7 +241,7 @@ public byte[] GetRawTXTRecords() { value = new byte[length]; Marshal.Copy(data, value, 0, length); - Interop.Libc.Free(data); + Interop.Glib.Free(data); } return value; } From 3a250f5df56ce390909ea0b765d563646b54d057 Mon Sep 17 00:00:00 2001 From: Yunhee Seo Date: Thu, 19 Oct 2023 13:37:28 +0900 Subject: [PATCH 49/82] [System.Feedback] Add feedback theme index range description The index of sound theme range is 1 ~ N according to conf file. This index range should be considered when using feedback theme index getter/setter. Signed-off-by: Yunhee Seo --- src/Tizen.System.Feedback/Feedback/Feedback.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Tizen.System.Feedback/Feedback/Feedback.cs b/src/Tizen.System.Feedback/Feedback/Feedback.cs index 1ada6727155..daaf66ba0e6 100755 --- a/src/Tizen.System.Feedback/Feedback/Feedback.cs +++ b/src/Tizen.System.Feedback/Feedback/Feedback.cs @@ -552,6 +552,7 @@ public void Stop() /// /// /// Now this internal API works for FeedbackType.Sound only, FeedbackType.Vibration is not supported. + /// Counts of theme range will be 1 ~ N according to conf file. /// /// 10 /// The feedback type. @@ -598,6 +599,7 @@ public uint GetCountOfThemeInternal(FeedbackType type) /// /// /// Now this internal API works for FeedbackType.Sound only, FeedbackType.Vibration is not supported. + /// Index of theme range will be 1 ~ N according to conf file. /// /// 10 /// The feedback type. @@ -642,6 +644,7 @@ public uint GetThemeIndexInternal(FeedbackType type) /// /// Now this internal API works for FeedbackType.Sound only, FeedbackType.Vibration is not supported. /// To set the index of theme for Sound type, the application should have http://tizen.org/privilege/systemsettings.admin privilege. + /// Index of theme range is 1 ~ N according to conf file. If you put the wrong index, operation cannot be guaranteed. /// /// 10 /// The feedback type. @@ -653,7 +656,7 @@ public uint GetThemeIndexInternal(FeedbackType type) /// /// /// Feedback feedback = new Feedback(); - /// uint indexOfTheme = 0; + /// uint indexOfTheme = 1; /// feedback.SetThemeIndexInternal(FeedbackType.Sound, indexOfTheme); /// /// From 3930b1c7a3c4c9661087b207090518d553806b77 Mon Sep 17 00:00:00 2001 From: Seonah Moon <31679495+SeonahMoon@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:23:50 +0900 Subject: [PATCH 50/82] [WiFi] Fix ASAN crash (#5631) * [WiFi] Fix ASAN crash * [WiFi] Use Marshal.FreeHGlobal() --------- Co-authored-by: chleun-moon <32117100+chleun-moon@users.noreply.github.com> --- src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs | 1 - src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs | 4 ++-- .../Tizen.Network.WiFi/WiFiAddressInformation.cs | 2 +- src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs | 6 +++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs b/src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs index d966df68f4a..1dbe019ec1b 100755 --- a/src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs +++ b/src/Tizen.Network.WiFi/Interop/Interop.Libraries.cs @@ -20,6 +20,5 @@ internal static partial class Libraries { public const string WiFi = "libcapi-network-wifi-manager.so.1"; public const string Glib = "libglib-2.0.so.0"; - public const string Libc = "libc.so.6"; } } diff --git a/src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs b/src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs index 70458db3891..2f46431eb2e 100755 --- a/src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs +++ b/src/Tizen.Network.WiFi/Interop/Interop.WiFi.cs @@ -353,9 +353,9 @@ protected override bool ReleaseHandle() } - internal static partial class Libc + internal static partial class Glib { - [DllImport(Libraries.Libc, EntryPoint = "free")] + [DllImport(Libraries.Glib, EntryPoint = "g_free", CallingConvention = CallingConvention.Cdecl)] public static extern void Free(IntPtr userData); } } diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs index 5b43e3064e8..8d69e7e894e 100755 --- a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs +++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiAddressInformation.cs @@ -252,7 +252,7 @@ private System.Net.IPAddress ParseIPAddress(int ret, IntPtr addrPtr) string addr = Marshal.PtrToStringAnsi(addrPtr); if (addr == null || addr.Length == 0) return DefaultIPAddress(); - Interop.Libc.Free(addrPtr); + Interop.Glib.Free(addrPtr); return System.Net.IPAddress.Parse(addr); } diff --git a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs index 4bb8fa0792e..ede4e4de684 100755 --- a/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs +++ b/src/Tizen.Network.WiFi/Tizen.Network.WiFi/WiFiNetwork.cs @@ -54,7 +54,7 @@ public string Essid else { _essid = Marshal.PtrToStringAnsi(strPtr); - Interop.Libc.Free(strPtr); + Interop.Glib.Free(strPtr); } } return _essid; @@ -83,7 +83,7 @@ public byte[] RawSsid { rawSsid = new byte[length]; Marshal.Copy(ptr, rawSsid, 0, length); - Interop.Libc.Free(ptr); + Interop.Glib.Free(ptr); } return rawSsid; } @@ -364,7 +364,7 @@ public string CountryCode else { code = Marshal.PtrToStringAnsi(strPtr); - Interop.Libc.Free(strPtr); + Marshal.FreeHGlobal(strPtr); } return code; } From 168fe31bb144a0ab38ec3ed1cae6a305091beec8 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 18 Oct 2023 14:31:40 +0900 Subject: [PATCH 51/82] [System.Information] Use Marshal.FreeHGlobal() instead of Libc.Free() Use Marshal.FreeHGlobal() instead of Libc.Free() for ASAN environment. Also, remove not any more used Libc.Free() Interop. In ASAN environment, because Interop uses dlopen(), newly opended libc causes different libc/asan alloc context from already allocaed buffer, and it gives segment fault crash when calling Libc.Free(). Signed-off-by: Seung-Woo Kim --- .../Interop/Interop.Libc.cs | 27 ------------------- .../Interop/Interop.Libraries.cs | 1 - .../Usage/ProcessMemoryUsage.cs | 4 +-- 3 files changed, 2 insertions(+), 30 deletions(-) delete mode 100755 src/Tizen.System.Information/Interop/Interop.Libc.cs diff --git a/src/Tizen.System.Information/Interop/Interop.Libc.cs b/src/Tizen.System.Information/Interop/Interop.Libc.cs deleted file mode 100755 index ef021f18f31..00000000000 --- a/src/Tizen.System.Information/Interop/Interop.Libc.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* -* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -* -* Licensed under the Apache License, Version 2.0 (the License); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an AS IS BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -using System; -using System.Runtime.InteropServices; - -internal static partial class Interop -{ - internal static partial class Libc - { - [DllImport(Libraries.Libc, EntryPoint = "free")] - public static extern void Free(IntPtr ptr); - } -} diff --git a/src/Tizen.System.Information/Interop/Interop.Libraries.cs b/src/Tizen.System.Information/Interop/Interop.Libraries.cs index 60ae7217fcd..ddb18845f92 100755 --- a/src/Tizen.System.Information/Interop/Interop.Libraries.cs +++ b/src/Tizen.System.Information/Interop/Interop.Libraries.cs @@ -20,6 +20,5 @@ internal static partial class Libraries { internal const string RuntimeInfo = "libcapi-system-runtime-info.so.0"; internal const string SystemInfo = "libcapi-system-info.so.0"; - internal const string Libc = "libc.so.6"; } } diff --git a/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs b/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs index 9583f818452..0c4a2a393fe 100755 --- a/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs +++ b/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs @@ -280,7 +280,7 @@ private int[] GetProcessMemoryValueInt(Interop.RuntimeInfo.ProcessMemoryInfoKey } finally { - Interop.Libc.Free(ptr); + Marshal.FreeHGlobal(ptr); } } @@ -319,7 +319,7 @@ public void Update(IEnumerable pid) } finally { - Interop.Libc.Free(ptr); + Marshal.FreeHGlobal(ptr); } Gpus = GetProcessMemoryValueInt(Interop.RuntimeInfo.ProcessMemoryInfoKey.Gpu, pid); From 27de0d26c07290e5f9e74eefb3f6d77ffc23e696 Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Tue, 24 Oct 2023 12:04:31 +0900 Subject: [PATCH 52/82] [Bluetooth] Fix ASAN crash issue (#5624) - Use g_free for data allocated by g_malloc Signed-off-by: Wootak Jung --- src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs | 3 +++ .../Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs | 4 ++-- .../Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs | 10 +++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs b/src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs index 576a6e287cf..ee7a1e1cd98 100644 --- a/src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs +++ b/src/Tizen.Network.Bluetooth/Interop/Interop.Glib.cs @@ -26,5 +26,8 @@ internal static partial class Glib [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)] internal static extern uint IdleAdd(GSourceFunc d, IntPtr data); + + [DllImport(Libraries.Glib, EntryPoint = "g_free", CallingConvention = CallingConvention.Cdecl)] + internal static extern void Gfree(IntPtr ptr); } } diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs index 99a856d1f5f..d74b045fa0f 100644 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs @@ -534,14 +534,14 @@ internal BluetoothOobData GetLocalOobData() byte[] hashArr = new byte[hashLength]; Marshal.Copy(hash, hashArr, 0, hashLength); oobData.HashValue = hashArr; - Interop.Libc.Free(hash); + Interop.Glib.Gfree(hash); } if (randomizerLength > 0) { byte[] randomizerArr = new byte[randomizerLength]; Marshal.Copy(randomizer, randomizerArr, 0, randomizerLength); oobData.RandomizerValue = randomizerArr; - Interop.Libc.Free(randomizer); + Interop.Glib.Gfree(randomizer); } return oobData; diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs index 890c80e3e4a..4cd0a805106 100644 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothLeAdapterImpl.cs @@ -187,10 +187,10 @@ internal IList GetLeScanResultServiceUuids(BluetoothLeScanData scanData, foreach (IntPtr uuids in uuidList) { list.Add(Marshal.PtrToStringAnsi(uuids)); - Interop.Libc.Free(uuids); + Interop.Glib.Gfree(uuids); } - Interop.Libc.Free(uuidListArray); + Interop.Glib.Gfree(uuidListArray); Marshal.FreeHGlobal(scanDataStruct.AdvData); Marshal.FreeHGlobal(scanDataStruct.ScanData); return list; @@ -295,10 +295,10 @@ internal IList GetScanResultSvcSolicitationUuids(BluetoothLeScanData sca foreach (IntPtr uuids in uuidList) { list.Add(Marshal.PtrToStringAnsi(uuids)); - Interop.Libc.Free(uuids); + Interop.Glib.Gfree(uuids); } - Interop.Libc.Free(uuidListArray); + Interop.Glib.Gfree(uuidListArray); Marshal.FreeHGlobal(scanDataStruct.AdvData); Marshal.FreeHGlobal(scanDataStruct.ScanData); return list; @@ -417,7 +417,7 @@ internal ManufacturerData GetScanResultManufacturerData(BluetoothLeScanData scan Marshal.Copy(manufData, data.Data, 0, data.DataLength); } - Interop.Libc.Free(manufData); + Interop.Glib.Gfree(manufData); Marshal.FreeHGlobal(scanDataStruct.AdvData); Marshal.FreeHGlobal(scanDataStruct.ScanData); return data; From 6754a811c5b916eea73af975669d467d9ae9c0d8 Mon Sep 17 00:00:00 2001 From: zhouhao02 Date: Wed, 27 Sep 2023 11:03:30 +0800 Subject: [PATCH 53/82] [NUI] Fix some SVACE issues. --- .../Tizen.NUI/NUIGadgetManager.cs | 5 +++-- .../src/public/chipmunk/BoundingBox.cs | 15 +++++++++------ .../src/public/chipmunk/ContactPoint.cs | 13 ++++++++----- .../src/public/chipmunk/ContactPointSet.cs | 13 ++++++++----- .../src/public/chipmunk/DebugColor.cs | 15 +++++++++------ .../src/public/chipmunk/SegmentQueryInfo.cs | 15 +++++++++------ .../src/public/chipmunk/Transform.cs | 19 +++++++++++-------- .../public/ParticleSystem/ParticleEmitter.cs | 13 ++++++++----- 8 files changed, 65 insertions(+), 43 deletions(-) diff --git a/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetManager.cs b/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetManager.cs index 022d975e82b..bd3025cf5cb 100755 --- a/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetManager.cs +++ b/src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetManager.cs @@ -346,8 +346,9 @@ public static void SendAppControl(NUIGadget gadget, AppControl appControl) internal static bool HandleAppControl(AppControlReceivedEventArgs args) { - if (!args.ReceivedAppControl.ExtraData.TryGet("__K_GADGET_RES_TYPE", out string resourceType) || - !args.ReceivedAppControl.ExtraData.TryGet("__K_GADGET_CLASS_NAME", out string className)) + var extraData = args.ReceivedAppControl?.ExtraData; + if (extraData == null||!extraData.TryGet("__K_GADGET_RES_TYPE", out string resourceType) || + !extraData.TryGet("__K_GADGET_CLASS_NAME", out string className)) { return false; } diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs index 535bf4e258d..99f50d951d4 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/BoundingBox.cs @@ -111,16 +111,19 @@ public override bool Equals(object obj) [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - var hashCode = -1064806749; + unchecked + { + var hashCode = -1064806749; #pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()' - hashCode = hashCode * -1521134295 + left.GetHashCode(); - hashCode = hashCode * -1521134295 + bottom.GetHashCode(); - hashCode = hashCode * -1521134295 + right.GetHashCode(); - hashCode = hashCode * -1521134295 + top.GetHashCode(); + hashCode = hashCode * -1521134295 + left.GetHashCode(); + hashCode = hashCode * -1521134295 + bottom.GetHashCode(); + hashCode = hashCode * -1521134295 + right.GetHashCode(); + hashCode = hashCode * -1521134295 + top.GetHashCode(); #pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()' - return hashCode; + return hashCode; + } } /// diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs index d1233d3cefb..dcd5c08f24f 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPoint.cs @@ -108,13 +108,16 @@ public override bool Equals(object obj) [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - var hashCode = -1285340573; + unchecked + { + var hashCode = -1285340573; - hashCode = hashCode * -1521134295 + pointA.GetHashCode(); - hashCode = hashCode * -1521134295 + pointB.GetHashCode(); - hashCode = hashCode * -1521134295 + distance.GetHashCode(); + hashCode = hashCode * -1521134295 + pointA.GetHashCode(); + hashCode = hashCode * -1521134295 + pointB.GetHashCode(); + hashCode = hashCode * -1521134295 + distance.GetHashCode(); - return hashCode; + return hashCode; + } } /// diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs index 8a623f0157e..f5697096665 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/ContactPointSet.cs @@ -88,13 +88,16 @@ public bool Equals(ContactPointSet other) [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - var hashCode = -475635172; + unchecked + { + var hashCode = -475635172; - hashCode = hashCode * -1521134295 + count.GetHashCode(); - hashCode = hashCode * -1521134295 + normal.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(points); + hashCode = hashCode * -1521134295 + count.GetHashCode(); + hashCode = hashCode * -1521134295 + normal.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(points); - return hashCode; + return hashCode; + } } /// diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs index 223e8698663..90ad56fd615 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/DebugColor.cs @@ -114,14 +114,17 @@ public bool Equals(DebugColor color) [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - var hashCode = -1813971818; + unchecked + { + var hashCode = -1813971818; - hashCode = hashCode * -1521134295 + red.GetHashCode(); - hashCode = hashCode * -1521134295 + green.GetHashCode(); - hashCode = hashCode * -1521134295 + blue.GetHashCode(); - hashCode = hashCode * -1521134295 + alpha.GetHashCode(); + hashCode = hashCode * -1521134295 + red.GetHashCode(); + hashCode = hashCode * -1521134295 + green.GetHashCode(); + hashCode = hashCode * -1521134295 + blue.GetHashCode(); + hashCode = hashCode * -1521134295 + alpha.GetHashCode(); - return hashCode; + return hashCode; + } } /// diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs index 2a9779095cf..e492336cadb 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SegmentQueryInfo.cs @@ -167,12 +167,15 @@ public bool Equals(SegmentQueryInfo other) [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - var hashCode = -1275187100; - hashCode = hashCode * -1521134295 + shape.GetHashCode(); - hashCode = hashCode * -1521134295 + point.GetHashCode(); - hashCode = hashCode * -1521134295 + normal.GetHashCode(); - hashCode = hashCode * -1521134295 + alpha.GetHashCode(); - return hashCode; + unchecked + { + var hashCode = -1275187100; + hashCode = hashCode * -1521134295 + shape.GetHashCode(); + hashCode = hashCode * -1521134295 + point.GetHashCode(); + hashCode = hashCode * -1521134295 + normal.GetHashCode(); + hashCode = hashCode * -1521134295 + alpha.GetHashCode(); + return hashCode; + } } } } diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs index b5f92a3afb0..9eeac762963 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Transform.cs @@ -156,16 +156,19 @@ public bool Equals(Transform other) [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - var hashCode = -884009331; + unchecked + { + var hashCode = -884009331; #pragma warning disable RECS0025 // Non-readonly field referenced in 'GetHashCode()' - hashCode = hashCode * -1521134295 + a.GetHashCode(); - hashCode = hashCode * -1521134295 + b.GetHashCode(); - hashCode = hashCode * -1521134295 + c.GetHashCode(); - hashCode = hashCode * -1521134295 + d.GetHashCode(); - hashCode = hashCode * -1521134295 + tx.GetHashCode(); - hashCode = hashCode * -1521134295 + ty.GetHashCode(); + hashCode = hashCode * -1521134295 + a.GetHashCode(); + hashCode = hashCode * -1521134295 + b.GetHashCode(); + hashCode = hashCode * -1521134295 + c.GetHashCode(); + hashCode = hashCode * -1521134295 + d.GetHashCode(); + hashCode = hashCode * -1521134295 + tx.GetHashCode(); + hashCode = hashCode * -1521134295 + ty.GetHashCode(); #pragma warning restore RECS0025 // Non-readonly field referenced in 'GetHashCode()' - return hashCode; + return hashCode; + } } /// diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index 37d41f466bc..5751fc6f15a 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -568,13 +568,16 @@ internal bool Remove(T iface) internal T Get(IntPtr cPtr) { - var result = mBasePtr.FindIndex(0, x => x == cPtr ); - if (result >= 0) + lock (mBasePtr) { - return mInterfaces[result]; - } + var result = mBasePtr.FindIndex(0, x => x == cPtr); + if (result >= 0) + { + return mInterfaces[result]; + } - return null; + return null; + } } private List mBasePtr = new List(); From cd27b38bbb916d1f0a144f3c0b7f2bfc7c4a0394 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 26 Sep 2023 15:25:43 +0900 Subject: [PATCH 54/82] [NUI] Let registry throw exception at error case Let we throw exception if same object try to register. Moreover, let we print more useful callstack if we got unmatched case. Signed-off-by: Eunki, Hong --- .../src/internal/Common/DaliEnumConstants.cs | 2 +- src/Tizen.NUI/src/internal/Common/Registry.cs | 41 ++++++++++++++++++- src/Tizen.NUI/src/public/Common/BaseHandle.cs | 4 +- src/Tizen.NUI/src/public/Utility/Timer.cs | 6 +-- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Common/DaliEnumConstants.cs b/src/Tizen.NUI/src/internal/Common/DaliEnumConstants.cs index b97b81eceed..c24f9e1184f 100755 --- a/src/Tizen.NUI/src/internal/Common/DaliEnumConstants.cs +++ b/src/Tizen.NUI/src/internal/Common/DaliEnumConstants.cs @@ -251,7 +251,7 @@ public static void ErrorBacktrace(string msg, for (int i = 0; i < st.FrameCount; i++) { global::System.Diagnostics.StackFrame sf = st.GetFrame(i); - Tizen.Log.Error("NUI", " Method " + sf.GetMethod()); + Tizen.Log.Error("NUI", " Method " + sf.GetMethod() + ":" + sf.GetFileName() + ":" + sf.GetFileLineNumber()); } } } diff --git a/src/Tizen.NUI/src/internal/Common/Registry.cs b/src/Tizen.NUI/src/internal/Common/Registry.cs index ecceb81c050..7604d2e6064 100755 --- a/src/Tizen.NUI/src/internal/Common/Registry.cs +++ b/src/Tizen.NUI/src/internal/Common/Registry.cs @@ -60,7 +60,46 @@ internal static void Register(BaseHandle baseHandle) if (Instance._controlMap.TryAdd(refCptr, new WeakReference(baseHandle, false)) != true) { - NUILog.Debug("refCptr is already exist! OR something wrong!"); + WeakReference weakReference; + if(Instance._controlMap.TryGetValue(refCptr, out weakReference)) + { + if (weakReference == null) + { + Tizen.Log.Error("NUI", $"Something Wrong! weakReference is null\n"); + throw new System.InvalidOperationException("Error! NUI Registry weakReference should not be NULL!"); + } + var target = weakReference.Target; + + BaseHandle ret = target as BaseHandle; + if (ret != null) + { + Tizen.Log.Error("NUI", $"refCptr is already exist! input type:{baseHandle.GetType()}, registed type:{ret.GetType()}, refCptr:{refCptr.ToString("X8")}\n"); + throw new System.InvalidOperationException("refCptr is already exist!"); + } + else if(target == null) + { + // Special case. If WeakReference.Target is null, it might be disposed by GC. just Add forcely. + if (Instance._controlMap.TryRemove(refCptr, out weakReference) != true) + { + Tizen.Log.Error("NUI", $"Something Wrong when we try to remove null target\n"); + } + if (Instance._controlMap.TryAdd(refCptr, new WeakReference(baseHandle, false)) != true) + { + Tizen.Log.Error("NUI", $"Something Wrong when we try to replace null target\n"); + throw new System.InvalidOperationException("refCptr register failed"); + } + } + else + { + Tizen.Log.Error("NUI", $"Something Wrong!! target is not BaseHandle! target.GetType() : {target?.GetType()}\n"); + throw new System.InvalidOperationException("refCptr is already exist, but not a BaseHandle!"); + } + } + else + { + Tizen.Log.Error("NUI", $"refCptr is already exist! OR something Wrong!!!\n"); + throw new System.InvalidOperationException("refCptr is already exist, but fail to get handle!"); + } } NUILog.Debug($"[Registry] Register! type:{baseHandle.GetType()} count:{Instance._controlMap.Count} copyNativeHandle:{baseHandle.GetBaseHandleCPtrHandleRef.Handle.ToString("X8")}"); diff --git a/src/Tizen.NUI/src/public/Common/BaseHandle.cs b/src/Tizen.NUI/src/public/Common/BaseHandle.cs index cca7f46e57d..3b2bfafe88a 100755 --- a/src/Tizen.NUI/src/public/Common/BaseHandle.cs +++ b/src/Tizen.NUI/src/public/Common/BaseHandle.cs @@ -617,7 +617,7 @@ public class FocusRequestArgs : EventArgs for (int i = 0; i < st.FrameCount; i++) { global::System.Diagnostics.StackFrame sf = st.GetFrame(i); - Tizen.Log.Fatal("NUI", " Method " + sf.GetMethod()); + Tizen.Log.Fatal("NUI", " Method " + sf.GetMethod() + ":" + sf.GetFileName() + ":" + sf.GetFileLineNumber()); } Tizen.Log.Fatal("NUI", "Error! just return here with null swigCPtr! this can cause unknown error or crash in next step"); @@ -665,7 +665,7 @@ private void disposeDebuggingCtor() for (int i = 0; i < st.FrameCount; i++) { global::System.Diagnostics.StackFrame sf = st.GetFrame(i); - DebugFileLogging.Instance.WriteLog($"[{i}] {sf.GetMethod()}"); + DebugFileLogging.Instance.WriteLog($"[{i}] {sf.GetMethod()}:{sf.GetFileName()}:{sf.GetFileLineNumber()}"); } } } diff --git a/src/Tizen.NUI/src/public/Utility/Timer.cs b/src/Tizen.NUI/src/public/Utility/Timer.cs index 0bb293dc0eb..b17c72c71c4 100755 --- a/src/Tizen.NUI/src/public/Utility/Timer.cs +++ b/src/Tizen.NUI/src/public/Utility/Timer.cs @@ -136,7 +136,7 @@ public void Start() for (int i = 0; i < st.FrameCount; i++) { StackFrame sf = st.GetFrame(i); - Tizen.Log.Error("NUI", " Method " + sf.GetMethod()); + Tizen.Log.Error("NUI", " Method " + sf.GetMethod() + ":" + sf.GetFileName() + ":" + sf.GetFileLineNumber()); } } @@ -166,7 +166,7 @@ public void Stop() for (int i = 0; i < st.FrameCount; i++) { StackFrame sf = st.GetFrame(i); - Tizen.Log.Error("NUI", " Method " + sf.GetMethod()); + Tizen.Log.Error("NUI", " Method " + sf.GetMethod() + ":" + sf.GetFileName() + ":" + sf.GetFileLineNumber()); } } @@ -197,7 +197,7 @@ public bool IsRunning() for (int i = 0; i < st.FrameCount; i++) { StackFrame sf = st.GetFrame(i); - Tizen.Log.Error("NUI", " Method " + sf.GetMethod()); + Tizen.Log.Error("NUI", " Method " + sf.GetMethod() + ":" + sf.GetFileName() + ":" + sf.GetFileLineNumber()); } } From bb8a3c231477c0b8b09fdc24d861c711228547c6 Mon Sep 17 00:00:00 2001 From: zhouhao02 Date: Sun, 8 Oct 2023 17:23:08 +0800 Subject: [PATCH 55/82] [NUI] Fix some SVACE issues of null reference. --- .../Controls/TabButton.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Tizen.NUI.Components/Controls/TabButton.cs b/src/Tizen.NUI.Components/Controls/TabButton.cs index 9c91b2d3114..e9824982b87 100755 --- a/src/Tizen.NUI.Components/Controls/TabButton.cs +++ b/src/Tizen.NUI.Components/Controls/TabButton.cs @@ -301,10 +301,10 @@ private void UpdateSizeAndSpacing() // Text only if (isEmptyIcon && !isEmptyText) { - if (tabButtonStyle.Size != null) + if (tabButtonStyle.Size is var size && size != null) { - WidthSpecification = (int)tabButtonStyle.Size.Width; - HeightSpecification = (int)tabButtonStyle.Size.Height; + WidthSpecification = (int)size.Width; + HeightSpecification = (int)size.Height; } if ((tabButtonStyle.Text != null) && (tabButtonStyle.Text.PixelSize != null) && (tabButtonStyle.Text.PixelSize.Normal != null)) @@ -335,11 +335,11 @@ private void UpdateSizeAndSpacing() WidthSpecification = (int)tabButtonStyle.SizeWithIcon.Width; HeightSpecification = (int)tabButtonStyle.SizeWithIcon.Height; } - - if ((tabButtonStyle.Icon != null) && (tabButtonStyle.Icon.Size != null)) + var size = tabButtonStyle.Icon?.Size; + if (size != null) { - Icon.WidthSpecification = (int)tabButtonStyle.Icon.Size.Width; - Icon.HeightSpecification = (int)tabButtonStyle.Icon.Size.Height; + Icon.WidthSpecification = (int)size.Width; + Icon.HeightSpecification = (int)size.Height; } TextLabel.PixelSize = tabButtonStyle.TextSizeWithIcon; @@ -347,10 +347,10 @@ private void UpdateSizeAndSpacing() // Nothing else { - if (tabButtonStyle.Size != null) + if (tabButtonStyle.Size is var size && size != null) { - WidthSpecification = (int)tabButtonStyle.Size.Width; - HeightSpecification = (int)tabButtonStyle.Size.Height; + WidthSpecification = (int)size.Width; + HeightSpecification = (int)size.Height; } } } From f510b0a96fd0bcb01ebda04ffb3374d16d8f6990 Mon Sep 17 00:00:00 2001 From: zhouhao02 Date: Sun, 8 Oct 2023 09:21:10 +0800 Subject: [PATCH 56/82] [NUI] Fix some SVACE issues related to methods of Marshal. --- .../src/internal/chipmunk/NativeInterop.cs | 5 ++++- .../src/internal/chipmunk/cpSpaceDebugDrawOptions.cs | 11 +++++++++-- src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs | 5 +++-- src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs | 10 ++++++---- .../src/public/chipmunk/SpaceRef.cs | 10 ++++++---- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs index 5859c0b618a..a86f6bf4ce6 100644 --- a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/NativeInterop.cs @@ -111,7 +111,10 @@ public static T[] PtrToStructureArray(IntPtr intPtr, int count) internal static IntPtr StructureArrayToPtr(IReadOnlyList items) { var size = SizeOf(); - var memory = Marshal.AllocHGlobal(size * items.Count); + int allocBytes = checked(size * items.Count); + Debug.Assert(allocBytes > 0, "The memory to be allocated should be greater than 0"); + + var memory = Marshal.AllocHGlobal(allocBytes); for (var i = 0; i < items.Count; i++) { diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs index 18e7fd70990..d787f6e8104 100644 --- a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs @@ -104,8 +104,15 @@ internal struct cpSpaceDebugDrawOptions private IntPtr ToPointer() { IntPtr drawOptionsPtr = NativeInterop.AllocStructure(); - - Marshal.StructureToPtr(this, drawOptionsPtr, false); + try + { + Marshal.StructureToPtr(this, drawOptionsPtr, false); + } + catch (Exception exception) + { + Tizen.Log.Fatal("NUI", "[Error] got exception during Marshal.StructureToPtr, this should not occur, message : " + exception.Message); + } + return drawOptionsPtr; } diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs index 647c0ef5746..31362da5afc 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Body.cs @@ -728,11 +728,12 @@ public IReadOnlyList AllContactedBodies get { int count = NativeMethods.cpBodyGetContactedBodiesCount(body); + int intptrBytes = checked(IntPtr.Size * count); - if (count == 0) + if (intptrBytes == 0) return Array.Empty(); - IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + IntPtr ptrBodies = Marshal.AllocHGlobal(intptrBytes); NativeMethods.cpBodyGetUserDataContactedBodies(body, ptrBodies); IntPtr[] userDataArray = new IntPtr[count]; diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs index db27ebd845b..3013687780b 100755 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/Space.cs @@ -607,11 +607,12 @@ public IReadOnlyList Bodies get { int count = NativeMethods.cpSpaceGetBodyCount(space); + int intptrBytes = checked(IntPtr.Size * count); - if (count == 0) + if (intptrBytes == 0) return Array.Empty(); - IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + IntPtr ptrBodies = Marshal.AllocHGlobal(intptrBytes); NativeMethods.cpSpaceGetBodiesUserDataArray(space, ptrBodies); IntPtr[] userDataArray = new IntPtr[count]; @@ -641,11 +642,12 @@ public IReadOnlyList DynamicBodies get { int count = NativeMethods.cpSpaceGetDynamicBodyCount(space); + int intptrBytes = checked(IntPtr.Size * count); - if (count == 0) + if (intptrBytes == 0) return Array.Empty(); - IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + IntPtr ptrBodies = Marshal.AllocHGlobal(intptrBytes); NativeMethods.cpSpaceGetDynamicBodiesUserDataArray(space, ptrBodies); IntPtr[] userDataArray = new IntPtr[count]; diff --git a/src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs index 9313ff15e2f..926af934ee9 100644 --- a/src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs +++ b/src/Tizen.NUI.Physics2D/src/public/chipmunk/SpaceRef.cs @@ -526,11 +526,12 @@ public IReadOnlyList Bodies get { int count = NativeMethods.cpSpaceGetBodyCount(space); + int intptrBytes = checked(IntPtr.Size * count); - if (count == 0) + if (intptrBytes == 0) return Array.Empty(); - IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + IntPtr ptrBodies = Marshal.AllocHGlobal(intptrBytes); NativeMethods.cpSpaceGetBodiesUserDataArray(space, ptrBodies); IntPtr[] userDataArray = new IntPtr[count]; @@ -560,11 +561,12 @@ public IReadOnlyList DynamicBodies get { int count = NativeMethods.cpSpaceGetDynamicBodyCount(space); + int intptrBytes = checked(IntPtr.Size * count); - if (count == 0) + if (intptrBytes == 0) return Array.Empty(); - IntPtr ptrBodies = Marshal.AllocHGlobal(IntPtr.Size * count); + IntPtr ptrBodies = Marshal.AllocHGlobal(intptrBytes); NativeMethods.cpSpaceGetDynamicBodiesUserDataArray(space, ptrBodies); IntPtr[] userDataArray = new IntPtr[count]; From 47da519e5d874b25969333c537491cdbf3cecc81 Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Sun, 8 Oct 2023 16:32:54 +0900 Subject: [PATCH 57/82] [NUI] Remove build warnings Signed-off-by: Eunki Hong --- src/Tizen.NUI/src/public/Accessibility/IAtspiSelection.cs | 2 +- src/Tizen.NUI/src/public/ParticleSystem/Particle.cs | 3 --- src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs | 2 +- src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Tizen.NUI/src/public/Accessibility/IAtspiSelection.cs b/src/Tizen.NUI/src/public/Accessibility/IAtspiSelection.cs index 38f1a66dcb6..0ee0b18e0cd 100644 --- a/src/Tizen.NUI/src/public/Accessibility/IAtspiSelection.cs +++ b/src/Tizen.NUI/src/public/Accessibility/IAtspiSelection.cs @@ -65,7 +65,7 @@ public interface IAtspiSelection /// Checks whether a child is selected. /// /// The index of the child - /// < True if given child is selected, false otherwise /returns> + /// True if given child is selected, false otherwise [EditorBrowsable(EditorBrowsableState.Never)] bool AccessibilityIsChildSelected(int childIndex); diff --git a/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs b/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs index c5234f79481..667c4383f58 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/Particle.cs @@ -18,9 +18,6 @@ using System; using System.IO; using System.Runtime.InteropServices; -using System; -using System.Runtime.InteropServices; -using global::System.Runtime.InteropServices; using System.ComponentModel; using System.Reflection; diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs index 5751fc6f15a..761c49181de 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleEmitter.cs @@ -103,7 +103,7 @@ internal ParticleEmitter Assign( ParticleEmitter particleEmitter) /// /// Raises the window to the top of the window stack. /// - /// Source object to copy. + /// Source object to copy. [EditorBrowsable(EditorBrowsableState.Never)] public void SetSource(ParticleSource source) where T : ParticleSourceInterface, new() { diff --git a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs index 84350043a0a..d835c2dd870 100644 --- a/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs +++ b/src/Tizen.NUI/src/public/ParticleSystem/ParticleModifier.cs @@ -85,7 +85,7 @@ public virtual void Update(ParticleEmitterProxy emitterProxy, List par /// Modifiers can be stacked (more than one can be added to the ParticleEmitter). /// Output of one modifier becomes input for next modifier. /// - /// Modifier calls into the implementation of class. + /// Modifier calls into the implementation of class. /// /// /// Class of interface that derives from From 8a97b53e908d50ad9be7a765dcddbf28c531e0d3 Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Sun, 8 Oct 2023 16:02:42 +0900 Subject: [PATCH 58/82] [NUI] BaseHandle without Registry but own memory There are some usecase s.t. we have to call ReleaseSwigCPtr but don't want register to Registry. For example, PixelBuffer and PixelData dont need to be create only for main thread. Signed-off-by: Eunki Hong --- src/Tizen.NUI/src/public/Common/BaseHandle.cs | 37 ++++++++++++++-- src/Tizen.NUI/src/public/Events/Hover.cs | 6 ++- src/Tizen.NUI/src/public/Events/Touch.cs | 6 ++- src/Tizen.NUI/src/public/Events/Wheel.cs | 6 ++- .../src/public/Images/PixelBuffer.cs | 7 ++- src/Tizen.NUI/src/public/Images/PixelData.cs | 7 ++- src/Tizen.NUI/src/public/Input/Key.cs | 6 ++- src/Tizen.NUI/src/public/Window/Window.cs | 44 ++----------------- 8 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/Tizen.NUI/src/public/Common/BaseHandle.cs b/src/Tizen.NUI/src/public/Common/BaseHandle.cs index 3b2bfafe88a..5f85509181b 100755 --- a/src/Tizen.NUI/src/public/Common/BaseHandle.cs +++ b/src/Tizen.NUI/src/public/Common/BaseHandle.cs @@ -69,6 +69,29 @@ public BaseHandle(BaseHandle handle) : this(Interop.BaseHandle.NewBaseHandle(Bas if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } + internal BaseHandle(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) + { + //to catch derived classes dali native exceptions + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + DebugFileLogging.Instance.WriteLog($"BaseHandle.contructor with cMemeryOwn:{cMemoryOwn} and cRegister:{cRegister} START"); + + registerMe = cRegister; + swigCMemOwn = cMemoryOwn; + swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + if (registerMe) + { + // Register this instance of BaseHandle in the registry. + Registry.Register(this); + } + + disposeDebuggingCtor(); + DebugFileLogging.Instance.WriteLog($" BaseHandle.contructor with cMemeryOwn and cRegister END"); + DebugFileLogging.Instance.WriteLog($"============================="); + } + internal BaseHandle(global::System.IntPtr cPtr, bool cMemoryOwn) { //to catch derived classes dali native exceptions @@ -511,6 +534,15 @@ internal void NotifyPropertyChanged([CallerMemberName] String propertyName = "") PropertySet?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } + internal void UnregisterFromRegistry() + { + if (registerMe) + { + Registry.Unregister(this); + registerMe = false; + } + } + /// /// Dispose. /// @@ -537,10 +569,7 @@ protected virtual void Dispose(DisposeTypes type) //because the execution order of Finalizes is non-deterministic. //Unreference this instance from Registry. - if (registerMe) - { - Registry.Unregister(this); - } + UnregisterFromRegistry(); disposeDebuggingDispose(type); diff --git a/src/Tizen.NUI/src/public/Events/Hover.cs b/src/Tizen.NUI/src/public/Events/Hover.cs index 20f0e6d1883..a35082684d6 100755 --- a/src/Tizen.NUI/src/public/Events/Hover.cs +++ b/src/Tizen.NUI/src/public/Events/Hover.cs @@ -52,7 +52,11 @@ internal Hover(Hover other) : this(Interop.Hover.NewHover(Hover.getCPtr(other)), if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Hover(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal Hover(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + { + } + + internal Hover(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Events/Touch.cs b/src/Tizen.NUI/src/public/Events/Touch.cs index 7fb042090dd..ee147e960d2 100755 --- a/src/Tizen.NUI/src/public/Events/Touch.cs +++ b/src/Tizen.NUI/src/public/Events/Touch.cs @@ -42,7 +42,11 @@ internal Touch(Touch other) : this(Interop.Touch.NewTouch(Touch.getCPtr(other)), if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Touch(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal Touch(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + { + } + + internal Touch(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Events/Wheel.cs b/src/Tizen.NUI/src/public/Events/Wheel.cs index 368da455ae1..00ef79d95b7 100755 --- a/src/Tizen.NUI/src/public/Events/Wheel.cs +++ b/src/Tizen.NUI/src/public/Events/Wheel.cs @@ -53,7 +53,11 @@ public Wheel(Wheel.WheelType type, int direction, uint modifiers, Vector2 point, if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Wheel(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal Wheel(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + { + } + + internal Wheel(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Images/PixelBuffer.cs b/src/Tizen.NUI/src/public/Images/PixelBuffer.cs index efb90df1974..79c74d09296 100755 --- a/src/Tizen.NUI/src/public/Images/PixelBuffer.cs +++ b/src/Tizen.NUI/src/public/Images/PixelBuffer.cs @@ -56,7 +56,12 @@ internal PixelBuffer(PixelBuffer handle) : this(Interop.PixelBuffer.NewPixelBuff if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal PixelBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal PixelBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, false) + { + // Note : PixelBuffer don't need to be register in Registry default. So we can create this class from worker thread. + } + + internal PixelBuffer(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Images/PixelData.cs b/src/Tizen.NUI/src/public/Images/PixelData.cs index b488f5ea7ab..9f915ad4b2a 100755 --- a/src/Tizen.NUI/src/public/Images/PixelData.cs +++ b/src/Tizen.NUI/src/public/Images/PixelData.cs @@ -72,7 +72,12 @@ public PixelData(byte[] buffer, uint bufferSize, uint width, uint height, PixelF } - internal PixelData(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal PixelData(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, false) + { + // Note : PixelData don't need to be register in Registry default. So we can create this class from worker thread. + } + + internal PixelData(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Input/Key.cs b/src/Tizen.NUI/src/public/Input/Key.cs index 2ce31b9056e..814b9b266c6 100755 --- a/src/Tizen.NUI/src/public/Input/Key.cs +++ b/src/Tizen.NUI/src/public/Input/Key.cs @@ -49,7 +49,11 @@ internal Key(string keyName, string keyString, int keyCode, int keyModifier, uin if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Key(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal Key(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + { + } + + internal Key(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index e25d45e8a6b..36d60001bbe 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -2112,22 +2112,14 @@ public bool IsWindowRotating() /// We will use weak reference of last key events. /// Return value will be invalidated if last key event changed internally. /// - /// - /// Do not Dispose this value. - /// /// The last key event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Key GetLastKeyEvent() { if (internalLastKeyEvent == null) { - // TODO : We need to make automatically release memory of these cached events in future. - if (!(internalLastKeyEvent?.IsNativeHandleInvalid() ?? true)) - { - Interop.Key.DeleteKey(internalLastKeyEvent.SwigCPtr); - } // Create empty event handle without register. - internalLastKeyEvent = new Key(Interop.Key.New(), false); + internalLastKeyEvent = new Key(Interop.Key.New(), true, false); } Interop.Window.InternalRetrievingLastKeyEvent(SwigCPtr, internalLastKeyEvent.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -2141,22 +2133,14 @@ public Key GetLastKeyEvent() /// We will use weak reference of last touch events. /// Return value will be invalidated if last touch event changed internally. /// - /// - /// Do not Dispose this value. - /// /// The last touch event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Touch GetLastTouchEvent() { if (internalLastTouchEvent == null) { - // TODO : We need to make automatically release memory of these cached events in future. - if (!(internalLastTouchEvent?.IsNativeHandleInvalid() ?? true)) - { - Interop.Touch.DeleteTouch(internalLastTouchEvent.SwigCPtr); - } // Create empty event handle without register. - internalLastTouchEvent = new Touch(Interop.Touch.NewTouch(), false); + internalLastTouchEvent = new Touch(Interop.Touch.NewTouch(), true, false); } Interop.Window.InternalRetrievingLastTouchEvent(SwigCPtr, internalLastTouchEvent.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -2170,22 +2154,14 @@ public Touch GetLastTouchEvent() /// We will use weak reference of last hover events. /// Return value will be invalidated if last hover event changed internally. /// - /// - /// Do not Dispose this value. - /// /// The last hover event the window gets. [EditorBrowsable(EditorBrowsableState.Never)] public Hover GetLastHoverEvent() { if (internalLastHoverEvent == null) { - // TODO : We need to make automatically release memory of these cached events in future. - if (!(internalLastHoverEvent?.IsNativeHandleInvalid() ?? true)) - { - Interop.Hover.DeleteHover(internalLastHoverEvent.SwigCPtr); - } // Create empty event handle without register. - internalLastHoverEvent = new Hover(Interop.Hover.New(0u), false); + internalLastHoverEvent = new Hover(Interop.Hover.New(0u), true, false); } Interop.Window.InternalRetrievingLastHoverEvent(SwigCPtr, internalLastHoverEvent.SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -2274,20 +2250,6 @@ protected override void Dispose(DisposeTypes type) localController?.Dispose(); - // TODO : We need to make automatically release memory of these cached events in future. - if (!(internalLastKeyEvent?.IsNativeHandleInvalid() ?? true)) - { - Interop.Key.DeleteKey(internalLastKeyEvent.SwigCPtr); - } - if (!(internalLastTouchEvent?.IsNativeHandleInvalid() ?? true)) - { - Interop.Touch.DeleteTouch(internalLastTouchEvent.SwigCPtr); - } - if (!(internalLastHoverEvent?.IsNativeHandleInvalid() ?? true)) - { - Interop.Hover.DeleteHover(internalLastHoverEvent.SwigCPtr); - } - internalLastKeyEvent?.Dispose(); internalLastKeyEvent = null; internalLastTouchEvent?.Dispose(); From 9ac9e937152dfcb5015106fa5f703d25fa3ffe5a Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Sun, 8 Oct 2023 16:22:56 +0900 Subject: [PATCH 59/82] [NUI] Consider WeakReference resurrection at Registry. Since NUI use DisposeQueue system instead of GC directly, the lifecycle of WeakReference may need to be alive more times. If we make trackResurrection as false, WeakReference.Target become null when the item is in DisposeQueue. Signed-off-by: Eunki Hong --- src/Tizen.NUI/src/internal/Common/Registry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tizen.NUI/src/internal/Common/Registry.cs b/src/Tizen.NUI/src/internal/Common/Registry.cs index 7604d2e6064..7b2d732fd32 100755 --- a/src/Tizen.NUI/src/internal/Common/Registry.cs +++ b/src/Tizen.NUI/src/internal/Common/Registry.cs @@ -58,7 +58,7 @@ internal static void Register(BaseHandle baseHandle) RegistryCurrentThreadCheck(); - if (Instance._controlMap.TryAdd(refCptr, new WeakReference(baseHandle, false)) != true) + if (Instance._controlMap.TryAdd(refCptr, new WeakReference(baseHandle, true)) != true) { WeakReference weakReference; if(Instance._controlMap.TryGetValue(refCptr, out weakReference)) From 5b59d58ba84df37e92f84eb9eaa2b27f1c552edd Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Tue, 10 Oct 2023 14:00:31 +0900 Subject: [PATCH 60/82] [NUI] bug fixed about cMemoryOwn refer : https://github.com/Samsung/TizenFX/pull/5603 --- src/Tizen.NUI/src/public/Events/Hover.cs | 2 +- src/Tizen.NUI/src/public/Events/Touch.cs | 2 +- src/Tizen.NUI/src/public/Events/Wheel.cs | 2 +- src/Tizen.NUI/src/public/Input/Key.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Tizen.NUI/src/public/Events/Hover.cs b/src/Tizen.NUI/src/public/Events/Hover.cs index a35082684d6..2f216d2fc4c 100755 --- a/src/Tizen.NUI/src/public/Events/Hover.cs +++ b/src/Tizen.NUI/src/public/Events/Hover.cs @@ -52,7 +52,7 @@ internal Hover(Hover other) : this(Interop.Hover.NewHover(Hover.getCPtr(other)), if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Hover(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + internal Hover(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) { } diff --git a/src/Tizen.NUI/src/public/Events/Touch.cs b/src/Tizen.NUI/src/public/Events/Touch.cs index ee147e960d2..1028422ff87 100755 --- a/src/Tizen.NUI/src/public/Events/Touch.cs +++ b/src/Tizen.NUI/src/public/Events/Touch.cs @@ -42,7 +42,7 @@ internal Touch(Touch other) : this(Interop.Touch.NewTouch(Touch.getCPtr(other)), if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Touch(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + internal Touch(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) { } diff --git a/src/Tizen.NUI/src/public/Events/Wheel.cs b/src/Tizen.NUI/src/public/Events/Wheel.cs index 00ef79d95b7..ab2d3be73d4 100755 --- a/src/Tizen.NUI/src/public/Events/Wheel.cs +++ b/src/Tizen.NUI/src/public/Events/Wheel.cs @@ -53,7 +53,7 @@ public Wheel(Wheel.WheelType type, int direction, uint modifiers, Vector2 point, if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Wheel(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + internal Wheel(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) { } diff --git a/src/Tizen.NUI/src/public/Input/Key.cs b/src/Tizen.NUI/src/public/Input/Key.cs index 814b9b266c6..4ec0244f84e 100755 --- a/src/Tizen.NUI/src/public/Input/Key.cs +++ b/src/Tizen.NUI/src/public/Input/Key.cs @@ -49,7 +49,7 @@ internal Key(string keyName, string keyString, int keyCode, int keyModifier, uin if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Key(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, true) + internal Key(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) { } From af8e7b5369ae897e7b7f6653bda41909c05a54bf Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Tue, 10 Oct 2023 16:51:35 +0900 Subject: [PATCH 61/82] [NUI] revert default key construct refer : https://github.com/Samsung/TizenFX/pull/5589/ --- src/Tizen.NUI/src/public/Input/Key.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tizen.NUI/src/public/Input/Key.cs b/src/Tizen.NUI/src/public/Input/Key.cs index 4ec0244f84e..ab703231200 100755 --- a/src/Tizen.NUI/src/public/Input/Key.cs +++ b/src/Tizen.NUI/src/public/Input/Key.cs @@ -30,7 +30,7 @@ public class Key : BaseHandle /// The default constructor. /// /// 3 - public Key() : this(Interop.Key.New(), true) + public Key() : this(Interop.Key.New("","",0,0,0u,0), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } From 564869cc92973001bc7a6dea1b642e78fe823dce Mon Sep 17 00:00:00 2001 From: Bowon Ryu Date: Tue, 10 Oct 2023 11:20:47 +0900 Subject: [PATCH 62/82] [NUI] Add TextFitArray Add a new function to satisfy the UX that operates TextFit by considering the PointSize and MinLineSize of the text. For example, TextFit should be able to find the one that fits among [PointSize 24 + MinLineSize 40] or [PointSize 28 + MinLineSize 44]. But the previous TextFit only considers PointSize. TextFitArray can solve this problem, and this implemented it to respond to additional requirements without modifying the API. https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-toolkit/+/299557/ https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-csharp-binder/+/299690/ Signed-off-by: Bowon Ryu --- .../src/internal/Interop/Interop.TextLabel.cs | 8 +- .../public/BaseComponents/TextConstants.cs | 74 ++++++++++++- .../src/public/BaseComponents/TextLabel.cs | 101 +++++++++++++++++- .../public/BaseComponents/TextMapHelper.cs | 12 ++- .../src/public/BaseComponents/TextUtils.cs | 36 ++++++- .../Samples/TextFitChangedSample.cs | 37 +++++++ 6 files changed, 263 insertions(+), 5 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs b/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs index 23ebfe0496a..205cc46ef40 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -165,6 +165,12 @@ internal static partial class TextLabel [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_GetTextPosition")] public static extern global::System.IntPtr GetTextPosition(global::System.Runtime.InteropServices.HandleRef textLabelRef, uint start, uint end); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_SetTextFitArray")] + public static extern void SetTextFitArray(global::System.Runtime.InteropServices.HandleRef textLabel, bool enable, uint arraySize, float[] pointSizeArray, float[] minLineSizeArray); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_GetTextFitArray")] + public static extern global::System.IntPtr GetTextFitArray(global::System.Runtime.InteropServices.HandleRef textLabel); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_AnchorClickedSignal")] public static extern global::System.IntPtr AnchorClickedSignal(global::System.Runtime.InteropServices.HandleRef jarg1); diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextConstants.cs b/src/Tizen.NUI/src/public/BaseComponents/TextConstants.cs index b141b0a680b..85b0b0d0c3d 100644 --- a/src/Tizen.NUI/src/public/BaseComponents/TextConstants.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextConstants.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Samsung Electronics Co., Ltd. +// Copyright (c) 2023 Samsung Electronics Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ // limitations under the License. using System; +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; @@ -546,6 +547,77 @@ public bool Equals(TextFit other) => Enable == other.Enable && MinSize == other. public override int GetHashCode() => (Enable, MinSize, MaxSize, StepSize, FontSizeType, FontSize).GetHashCode(); } + /// + /// A struct to pass data of TextFitArray's OptionList. + /// + /// + /// The TextFitArrayOption struct is used as an item to TextFitArray's OptionList.
+ /// See . + ///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1815: Override equals and operator equals on value types")] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct TextFitArrayOption + { + /// + /// Constructor. + /// + /// The PointSize for TextFitArrayOption + [EditorBrowsable(EditorBrowsableState.Never)] + public TextFitArrayOption(float pointSize) + { + PointSize = pointSize; + MinLineSize = null; + } + + /// + /// Constructor. + /// + /// The PointSize for TextFitArrayOption + /// The MinLineSize for TextFitArrayOption + [EditorBrowsable(EditorBrowsableState.Never)] + public TextFitArrayOption(float pointSize, float? minLineSize) + { + PointSize = pointSize; + MinLineSize = minLineSize; + } + + /// + /// Point size for text fit array. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float PointSize { get; set; } + + /// + /// Min line size for text fit array. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float? MinLineSize { get; set; } + } + + /// + /// A struct to pass data of SetTextFitArray and GetTextFitArray methods. + /// + /// + /// The TextFitArray struct is used as an argument to SetTextFitArray and GetTextFitArray methods.
+ /// See and . + ///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1815: Override equals and operator equals on value types")] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct TextFitArray + { + /// + /// True to enable the text fit array or false to disable (the default value is false). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Enable { get; set; } + + /// + /// A List of TextFitArrayOptions. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public List OptionList { get; set; } + } + /// /// A struct to pass data of Placeholder PropertyMap.
///
diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs index 91e36592140..e9359607296 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1404,6 +1404,105 @@ public TextFit GetTextFit() return textFit; } + /// + /// Set TextFitArray to TextLabel.
+ /// TextFitArray finds and applies the largest PointSize that fits among OptionList. + ///
+ /// The TextFitArray + /// + /// TextFitArray tries binary search by default.
+ /// The precondition for TextFitArray to perform binary search is sorting in ascending order of MinLineSize.
+ /// Because if MinLineSize is not sorted in ascending order,
+ /// binary search cannot guarantee that it will always find the best value.
+ /// In this case, the search sequentially starts from the largest PointSize.
+ /// If TextFitArrayOption's MinLineSize is set to null or 0,
+ /// TextFitArray is calculated without applying MinLineSize.
+ /// If TextFitArray is enabled, TextLabel's MinLineSize property is ignored.
+ /// See and . + ///
+ /// + /// The following example demonstrates how to use the SetTextFitArray method.
+ /// + /// var textFitArray = new Tizen.NUI.Text.TextFitArray(); + /// textFitArray.Enable = true; + /// textFitArray.OptionList = new List() + /// { + /// new Tizen.NUI.Text.TextFitArrayOption(12, 18), + /// new Tizen.NUI.Text.TextFitArrayOption(24, 40), + /// new Tizen.NUI.Text.TextFitArrayOption(28, 48), + /// new Tizen.NUI.Text.TextFitArrayOption(32, 56), + /// new Tizen.NUI.Text.TextFitArrayOption(50, 72), + /// }; + /// label.SetTextFitArray(textFitArray); + /// + ///
+ /// The table below shows cases where binary search is possible and where it is not possible.
+ /// + /// [Binary search possible] + /// | | List index | 0 | 1 | 2 | 3 | + /// | OptionList | PointSize | 24 | 28 | 32 | 48 | + /// | | MinLineSize | 40 | 48 | 48 | 62 | << MinLineSize sorted in ascending order + /// ^ ^ + /// same values ​are not a problem + /// + /// [Binary search not possible] + /// | | List index | 0 | 1 | 2 | 3 | + /// | OptionList | PointSize | 24 | 28 | 32 | 48 | + /// | | MinLineSize | 40 | 48 | 38 | 62 | << MinLineSize is not sorted in ascending order + /// ^ + /// + ///
+ [EditorBrowsable(EditorBrowsableState.Never)] + public void SetTextFitArray(TextFitArray textFitArray) + { + bool enable = textFitArray.Enable; + int optionListSize = textFitArray.OptionList?.Count ?? 0; + + float[] pointSizeArray = new float[optionListSize]; + float[] minLineSizeArray = new float[optionListSize]; + + for (int i = 0 ; i < optionListSize ; i ++) + { + TextFitArrayOption option = textFitArray.OptionList[i]; + pointSizeArray[i] = option.PointSize; + minLineSizeArray[i] = option.MinLineSize ?? 0; + } + + Interop.TextLabel.SetTextFitArray(SwigCPtr, enable, (uint)optionListSize, pointSizeArray, minLineSizeArray); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Get TextFitArray from TextLabel. + /// + /// The TextFitArray + /// + /// See and . + /// + /// + /// The following example demonstrates how to use the GetTextFitArray method.
+ /// + /// Tizen.NUI.Text.TextFitArray textFitArray = label.GetTextFitArray(); + /// bool enable = textFitArray.Enable; + /// var optionList = textFitArray.OptionList; + /// foreach(Tizen.NUI.Text.TextFitArrayOption option in optionList) + /// { + /// float pointSize = option.PointSize; + /// float minLinesize = option.MinLineSize; + /// } + /// + ///
+ [EditorBrowsable(EditorBrowsableState.Never)] + public TextFitArray GetTextFitArray() + { + using PropertyMap textFitArrayMap = new PropertyMap(Interop.TextLabel.GetTextFitArray(SwigCPtr), true); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + + TextFitArray textFitArray; + textFitArray = TextUtils.GetMapToTextFitArray(textFitArrayMap); + return textFitArray; + } + /// /// The MinLineSize property.
/// The height of the line in points.
diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextMapHelper.cs b/src/Tizen.NUI/src/public/BaseComponents/TextMapHelper.cs index d90ce64441f..cf0454940f1 100644 --- a/src/Tizen.NUI/src/public/BaseComponents/TextMapHelper.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextMapHelper.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -737,6 +737,16 @@ internal static PropertyMap GetMapFromMap(PropertyMap map, int key) return value; } + internal static PropertyArray GetArrayFromMap(PropertyMap map, string key) + { + PropertyArray value = new PropertyArray(); + using (var propertyValue = map.Find(0, key)) + { + if (null != propertyValue) propertyValue.Get(value); + } + return value; + } + internal static int? GetNullableIntFromMap(PropertyMap map, int key) { using (var propertyValue = map.Find(key)) diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextUtils.cs b/src/Tizen.NUI/src/public/BaseComponents/TextUtils.cs index 93edc25bdd9..b1255b01418 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/TextUtils.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextUtils.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2020 Samsung Electronics Co., Ltd. + * Copyright(c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1122,6 +1122,40 @@ public static List GetFontInfoList(PropertyArray fontArray) return fontList; } + /// + /// This method converts a TextFitArray property map to a TextFitArray and returns it. + /// The TextFitArray PropertyMap. + /// A TextFitArray struct. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static TextFitArray GetMapToTextFitArray(PropertyMap textFitArrayMap) + { + var textFitArray = new TextFitArray(); + if (textFitArrayMap != null) + { + textFitArray.Enable = TextMapHelper.GetBoolFromMap(textFitArrayMap, "enable", false); + textFitArray.OptionList = new List(); + + var pointSizeArray = TextMapHelper.GetArrayFromMap(textFitArrayMap, "pointSizeArray"); + var minLineSizeArray = TextMapHelper.GetArrayFromMap(textFitArrayMap, "minLineSizeArray"); + + if (pointSizeArray != null && minLineSizeArray != null && pointSizeArray.Count() == minLineSizeArray.Count()) + { + for (uint i = 0 ; i < pointSizeArray.Count() ; i ++) + { + using (var pointSizeValue = pointSizeArray[i]) + using (var minLineSizeValue = minLineSizeArray[i]) + { + minLineSizeValue.Get(out float minLineSize); + pointSizeValue.Get(out float pointSize); + textFitArray.OptionList.Add(new TextFitArrayOption(pointSize, minLineSize)); + } + } + } + } + return textFitArray; + } + #if PROFILE_TV private const float FontSizeScaleSmall = 0.8f; private const float FontSizeScaleNormal = 1.0f; diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/TextFitChangedSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/TextFitChangedSample.cs index dc6d731488b..a2116aff02e 100755 --- a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/TextFitChangedSample.cs +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/TextFitChangedSample.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Tizen.NUI; using Tizen.NUI.BaseComponents; using Tizen.NUI.Components; @@ -8,10 +9,13 @@ namespace Tizen.NUI.Samples public class TextFitChangedSample : IExample { private TextLabel label; + private TextLabel labelFitArray; public void Activate() { Window window = NUIApplication.GetDefaultWindow(); + + // TextFit var fit = new TextFit(); fit.Enable = true; fit.MinSize = 5.0f; @@ -34,6 +38,39 @@ public void Activate() TextFit textfit = label.GetTextFit(); Tizen.Log.Error("NUI", $"FontSize : {textfit.FontSize}\n"); }; + + // TextFitArray + labelFitArray = new TextLabel() + { + Text = "ABCDE", + Size = new Size(300, 100), + PointSize = 10, + Position = new Position(100, 250), + BackgroundColor = Color.Yellow, + }; + window.Add(labelFitArray); + + var textFitArray = new Tizen.NUI.Text.TextFitArray(); + textFitArray.Enable = true; + textFitArray.OptionList = new List() + { + new Tizen.NUI.Text.TextFitArrayOption(5, 10), + new Tizen.NUI.Text.TextFitArrayOption(10, 15), + new Tizen.NUI.Text.TextFitArrayOption(15, 15), + new Tizen.NUI.Text.TextFitArrayOption(20, 25), + new Tizen.NUI.Text.TextFitArrayOption(50, 70), + new Tizen.NUI.Text.TextFitArrayOption(60, 70), + new Tizen.NUI.Text.TextFitArrayOption(70, 70), + }; + labelFitArray.SetTextFitArray(textFitArray); + + var getFitArray = labelFitArray.GetTextFitArray(); + + Tizen.Log.Error("NUI", $"GetTextFitArray:enable:[{getFitArray.Enable}] \n"); + for (int i = 0 ; i < getFitArray.OptionList.Count ; i ++) + { + Tizen.Log.Error("NUI", $"GetTextFitArray:option:[{getFitArray.OptionList[i].PointSize}, {getFitArray.OptionList[i].MinLineSize}] \n"); + } } public void Deactivate() From a85ebe23e31644c0b35f467c3cff4b6684bbf0bf Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Thu, 12 Oct 2023 23:51:41 +0900 Subject: [PATCH 63/82] [NUI] Resolve TextLable build warning Reference documents : https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/ To refer to XML elements (for example, your function processes specific XML elements that you want to describe in an XML documentation comment), you can use the standard quoting mechanism (< and >). Signed-off-by: Eunki Hong --- src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs index e9359607296..1c979212c11 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs @@ -1425,7 +1425,7 @@ public TextFit GetTextFit() /// /// var textFitArray = new Tizen.NUI.Text.TextFitArray(); /// textFitArray.Enable = true; - /// textFitArray.OptionList = new List() + /// textFitArray.OptionList = new List<Tizen.NUI.Text.TextFitArrayOption>() /// { /// new Tizen.NUI.Text.TextFitArrayOption(12, 18), /// new Tizen.NUI.Text.TextFitArrayOption(24, 40), @@ -1441,14 +1441,14 @@ public TextFit GetTextFit() /// [Binary search possible] /// | | List index | 0 | 1 | 2 | 3 | /// | OptionList | PointSize | 24 | 28 | 32 | 48 | - /// | | MinLineSize | 40 | 48 | 48 | 62 | << MinLineSize sorted in ascending order + /// | | MinLineSize | 40 | 48 | 48 | 62 | << MinLineSize sorted in ascending order /// ^ ^ /// same values ​are not a problem /// /// [Binary search not possible] /// | | List index | 0 | 1 | 2 | 3 | /// | OptionList | PointSize | 24 | 28 | 32 | 48 | - /// | | MinLineSize | 40 | 48 | 38 | 62 | << MinLineSize is not sorted in ascending order + /// | | MinLineSize | 40 | 48 | 38 | 62 | << MinLineSize is not sorted in ascending order /// ^ /// /// From 49f5d2035ca9d1f20083e3c0ee1192e15af3e02f Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Thu, 12 Oct 2023 23:24:45 +0900 Subject: [PATCH 64/82] [NUI] Fix Registry exception for custom view wrapper 1. PanGesture from Accessibility create new handle in dali csharp side. We need to have memory ownership, but don't need to register it on NUI side. We can ignore it. 2. For Animation and StyleManager, it is possible to use that 'already registered' BaseHandle. But in this case, we should not dispose it by our self. Signed-off-by: Eunki Hong --- .../src/internal/Common/ViewWrapperImpl.cs | 51 ++++++++++++++++--- src/Tizen.NUI/src/public/Events/Gesture.cs | 6 ++- .../src/public/Events/LongPressGesture.cs | 6 ++- src/Tizen.NUI/src/public/Events/PanGesture.cs | 6 ++- .../src/public/Events/PinchGesture.cs | 6 ++- .../src/public/Events/RotationGesture.cs | 5 +- src/Tizen.NUI/src/public/Events/TapGesture.cs | 6 ++- 7 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Common/ViewWrapperImpl.cs b/src/Tizen.NUI/src/internal/Common/ViewWrapperImpl.cs index 63314650c5c..fcb85a1d76f 100755 --- a/src/Tizen.NUI/src/internal/Common/ViewWrapperImpl.cs +++ b/src/Tizen.NUI/src/internal/Common/ViewWrapperImpl.cs @@ -389,11 +389,30 @@ private void DirectorOnSizeSet(global::System.IntPtr targetSize) private void DirectorOnSizeAnimation(global::System.IntPtr animation, global::System.IntPtr targetSize) { - var ani = new Animation(animation, true); + bool useRegisterAnimation = false; + + var ani = Registry.GetManagedBaseHandleFromNativePtr(animation) as Animation; + if (ani != null) + { + HandleRef CPtr = new HandleRef(this, animation); + Interop.BaseHandle.DeleteBaseHandle(CPtr); + CPtr = new HandleRef(null, global::System.IntPtr.Zero); + + useRegisterAnimation = true; + } + else + { + ani = new Animation(animation, true); + } var vector3 = new Vector3(targetSize, false); OnSizeAnimation?.Invoke(ani, vector3); - ani.Dispose(); vector3.Dispose(); + + // Dispose only if we create new Animation here. + if (!useRegisterAnimation) + { + ani.Dispose(); + } } private bool DirectorOnKey(global::System.IntPtr arg0) @@ -469,9 +488,28 @@ private void DirectorOnInitialize() private void DirectorOnStyleChange(global::System.IntPtr styleManager, int change) { - var styleManger = new StyleManager(styleManager, true); - OnStyleChange?.Invoke(styleManger, (StyleChangeType)change); - styleManger.Dispose(); + bool useRegisterStyleManager = false; + + var nuiStyleManger = Registry.GetManagedBaseHandleFromNativePtr(styleManager) as StyleManager; + if (nuiStyleManger != null) + { + HandleRef CPtr = new HandleRef(this, styleManager); + Interop.BaseHandle.DeleteBaseHandle(CPtr); + CPtr = new HandleRef(null, global::System.IntPtr.Zero); + + useRegisterStyleManager = true; + } + else + { + nuiStyleManger = new StyleManager(styleManager, true); + } + OnStyleChange?.Invoke(nuiStyleManger, (StyleChangeType)change); + + // Dispose only if we create new StyleManager here. + if (!useRegisterStyleManager) + { + nuiStyleManger.Dispose(); + } } private bool DirectorOnAccessibilityActivated() @@ -481,7 +519,8 @@ private bool DirectorOnAccessibilityActivated() private bool DirectorOnAccessibilityPan(global::System.IntPtr gesture) { - var panGesture = new PanGesture(gesture, true); + // Take memory ownership, but do not register into Registry. + var panGesture = new PanGesture(gesture, true, false); var ret = OnAccessibilityPan?.Invoke(panGesture) ?? false; panGesture.Dispose(); return ret; diff --git a/src/Tizen.NUI/src/public/Events/Gesture.cs b/src/Tizen.NUI/src/public/Events/Gesture.cs index 9eb8b6fc67b..87f015e86b4 100755 --- a/src/Tizen.NUI/src/public/Events/Gesture.cs +++ b/src/Tizen.NUI/src/public/Events/Gesture.cs @@ -37,7 +37,11 @@ public Gesture(Gesture rhs) : this(Interop.Gesture.NewGesture(Gesture.getCPtr(rh if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal Gesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal Gesture(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) + { + } + + internal Gesture(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Events/LongPressGesture.cs b/src/Tizen.NUI/src/public/Events/LongPressGesture.cs index ff21038d631..14e63ff0688 100755 --- a/src/Tizen.NUI/src/public/Events/LongPressGesture.cs +++ b/src/Tizen.NUI/src/public/Events/LongPressGesture.cs @@ -35,7 +35,11 @@ public LongPressGesture(Gesture.StateType state) : this(Interop.LongPressGesture if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal LongPressGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal LongPressGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) + { + } + + internal LongPressGesture(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Events/PanGesture.cs b/src/Tizen.NUI/src/public/Events/PanGesture.cs index 7e4fadf6647..8587a69af1b 100755 --- a/src/Tizen.NUI/src/public/Events/PanGesture.cs +++ b/src/Tizen.NUI/src/public/Events/PanGesture.cs @@ -49,7 +49,11 @@ internal PanGesture(Gesture.StateType state) : this(Interop.PanGestureDetector.P if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal PanGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PanGestureDetector.PanGestureUpcast(cPtr), cMemoryOwn) + internal PanGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : this(Interop.PanGestureDetector.PanGestureUpcast(cPtr), cMemoryOwn, cMemoryOwn) + { + } + + internal PanGesture(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(Interop.PanGestureDetector.PanGestureUpcast(cPtr), cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Events/PinchGesture.cs b/src/Tizen.NUI/src/public/Events/PinchGesture.cs index 10394b2529e..25be2635bca 100755 --- a/src/Tizen.NUI/src/public/Events/PinchGesture.cs +++ b/src/Tizen.NUI/src/public/Events/PinchGesture.cs @@ -25,7 +25,11 @@ namespace Tizen.NUI /// 3 public class PinchGesture : Gesture { - internal PinchGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal PinchGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) + { + } + + internal PinchGesture(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Events/RotationGesture.cs b/src/Tizen.NUI/src/public/Events/RotationGesture.cs index 7057c713cfc..a5658328901 100755 --- a/src/Tizen.NUI/src/public/Events/RotationGesture.cs +++ b/src/Tizen.NUI/src/public/Events/RotationGesture.cs @@ -26,8 +26,11 @@ namespace Tizen.NUI [EditorBrowsable(EditorBrowsableState.Never)] public class RotationGesture : Gesture { + internal RotationGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) + { + } - internal RotationGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal RotationGesture(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } diff --git a/src/Tizen.NUI/src/public/Events/TapGesture.cs b/src/Tizen.NUI/src/public/Events/TapGesture.cs index 71045114d89..f9fe9818147 100755 --- a/src/Tizen.NUI/src/public/Events/TapGesture.cs +++ b/src/Tizen.NUI/src/public/Events/TapGesture.cs @@ -36,7 +36,11 @@ public TapGesture() : this(Interop.TapGesture.New(0), true) if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } - internal TapGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) + internal TapGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn) + { + } + + internal TapGesture(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister) { } From 8778ac941d3e9f1b5c66ca6c92ca68e5530ce07d Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Fri, 13 Oct 2023 13:40:56 +0900 Subject: [PATCH 65/82] [NUI] Resolve registry issue for CanvasView Gradient Since we always try to register to Registry for Gradient case, there can make some error for Shape use case. Signed-off-by: Eunki, Hong --- .../BaseComponents/VectorGraphics/Shape.cs | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Tizen.NUI/src/public/BaseComponents/VectorGraphics/Shape.cs b/src/Tizen.NUI/src/public/BaseComponents/VectorGraphics/Shape.cs index 903563fcf96..56f9941621a 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/VectorGraphics/Shape.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/VectorGraphics/Shape.cs @@ -20,6 +20,7 @@ using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; namespace Tizen.NUI.BaseComponents.VectorGraphics { @@ -73,7 +74,18 @@ public Gradient FillGradient get { global::System.IntPtr cPtr = Interop.Shape.GetFillGradient(BaseHandle.getCPtr(this)); - Gradient ret = new Gradient(cPtr, true); + + Gradient ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Gradient; + if (ret != null) + { + HandleRef CPtr = new HandleRef(this, cPtr); + Interop.BaseHandle.DeleteBaseHandle(CPtr); + CPtr = new HandleRef(null, global::System.IntPtr.Zero); + } + else + { + ret = new Gradient(cPtr, true); + } return ret; } set @@ -149,7 +161,18 @@ public Gradient StrokeGradient get { global::System.IntPtr cPtr = Interop.Shape.GetStrokeGradient(BaseHandle.getCPtr(this)); - Gradient ret = new Gradient(cPtr, true); + + Gradient ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Gradient; + if (ret != null) + { + HandleRef CPtr = new HandleRef(this, cPtr); + Interop.BaseHandle.DeleteBaseHandle(CPtr); + CPtr = new HandleRef(null, global::System.IntPtr.Zero); + } + else + { + ret = new Gradient(cPtr, true); + } return ret; } set From 54aad26f8e47beb80c0c4272d8dcb5e2ba68e7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20=C5=9Awigo=C5=84?= Date: Mon, 16 Oct 2023 11:31:42 +0200 Subject: [PATCH 66/82] [NUI][AT-SPI] Fix Accessibility.Say interop (#5612) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is one of the oldest interops and was actually problematic for multiple reasons; the return type didn't match and the third parameter was expected to have exactly the same value in every invocation. While fixing these issues, parsing the status string was moved from C++ to C# for readability. Co-authored-by: Artur Świgoń --- .../internal/Interop/Interop.Accessibility.cs | 6 ++-- .../src/public/Accessibility/Accessibility.cs | 32 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs b/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs index f296e1fca5a..4ef8e470807 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs @@ -24,9 +24,11 @@ internal static partial class Interop { internal static partial class Accessibility { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SayCallback(string status); + [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_say")] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool Say(string jarg1, bool jarg2, IntPtr jarg3); + public static extern void Say(string arg1_text, bool arg2_discardable, SayCallback arg3_callback); [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_pause_resume")] public static extern void PauseResume(bool jarg1); diff --git a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs index 77ac71117af..425c3bc59dd 100755 --- a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs +++ b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs @@ -16,10 +16,11 @@ */ using System; +using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using Tizen.NUI.BaseComponents; -using System.Diagnostics.CodeAnalysis; namespace Tizen.NUI.Accessibility { @@ -105,12 +106,10 @@ public static bool IsScreenReaderEnabled /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public static bool Say(string sentence, bool discardable) + public static void Say(string sentence, bool discardable) { - bool ret = Interop.Accessibility.Say(sentence, discardable, Marshal.GetFunctionPointerForDelegate(callback)); - + Interop.Accessibility.Say(sentence, discardable, SayFinishedEventCallback); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - return ret; } /// @@ -314,12 +313,6 @@ public enum SayFinishedState #endregion Event, Enum, Struct, ETC #region Private - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void SayFinishedEventCallbackType(int result); - - private static SayFinishedEventCallbackType callback = SayFinishedEventCallback; - private static Interop.Accessibility.EnabledDisabledSignalHandler enabledSignalHandler = null; private static Interop.Accessibility.EnabledDisabledSignalHandler disabledSignalHandler = null; @@ -328,9 +321,20 @@ public enum SayFinishedState private static Interop.Accessibility.EnabledDisabledSignalHandler screenReaderDisabledSignalHandler = null; - private static void SayFinishedEventCallback(int result) + private static readonly IReadOnlyDictionary sayFinishedStateDictionary = new Dictionary { + ["ReadingCancelled"] = SayFinishedState.Cancelled, + ["ReadingStopped"] = SayFinishedState.Stopped, + ["ReadingSkipped"] = SayFinishedState.Skipped, + ["ReadingPaused"] = SayFinishedState.Paused, + ["ReadingResumed"] = SayFinishedState.Resumed, + }; + + private static void SayFinishedEventCallback(string status) + { + var result = sayFinishedStateDictionary.GetValueOrDefault(status, SayFinishedState.Invalid); NUILog.Debug($"sayFinishedEventCallback(res={result}) called!"); + SayFinished?.Invoke(typeof(Accessibility), new SayFinishedEventArgs(result)); } @@ -357,9 +361,9 @@ public Accessibility.SayFinishedState State get; } - internal SayFinishedEventArgs(int result) + internal SayFinishedEventArgs(Accessibility.SayFinishedState state) { - State = (Accessibility.SayFinishedState)(result); + State = state; NUILog.Debug($"SayFinishedEventArgs Constructor! State={State}"); } } From cfbf799ba2bda72f4ea4ee29e9447728590d2f5c Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Sun, 15 Oct 2023 10:13:11 +0900 Subject: [PATCH 67/82] [NUI.Wearable] Remove build warning - Add comment for public API - Remove some unused private value/method Signed-off-by: Eunki Hong --- .../src/public/CircularPagination.cs | 21 ------------------- .../src/public/RecyclerView/RecyclerView.cs | 13 +++++++++++- .../src/public/WearableList.cs | 4 ++++ 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/Tizen.NUI.Wearable/src/public/CircularPagination.cs b/src/Tizen.NUI.Wearable/src/public/CircularPagination.cs index 70183d20456..3258e8e3b9a 100755 --- a/src/Tizen.NUI.Wearable/src/public/CircularPagination.cs +++ b/src/Tizen.NUI.Wearable/src/public/CircularPagination.cs @@ -47,8 +47,6 @@ public class CircularPagination : Control private bool isCurrentIndicatorCentered = false; // When the current indicator is the center one, this variable becomes true. private bool isOddNumber = true; private bool uninitializedLeftIndicator = true; // Need it when the indicators are asymmetry and the right indicator count is set earlier than left one. - private Animation selectAnimation = null; - private bool isNeedAnimation = false; // TODO : Animation will support using override function later. Position2D[] oddArray = new Position2D[] { new Position2D(36, 74), new Position2D(47, 60), new Position2D(60, 47), new Position2D(74, 36), new Position2D(89, 26), new Position2D(105, 18), new Position2D(122, 11), new Position2D(139, 7), @@ -203,7 +201,6 @@ public bool IsSymmetrical } } - /// /// Gets or sets the number of the pages/indicators. /// @@ -516,14 +513,6 @@ public virtual void SetIndicatorPosition(int index, Position position) UpdateVisual(); } - private void CreateSelectAnimation() - { - if (selectAnimation == null) - { - selectAnimation = new Animation(250); - } - } - /// /// You can override it to do your select out operation. /// @@ -593,16 +582,6 @@ protected override void Dispose(DisposeTypes type) if (type == DisposeTypes.Explicit) { - if (selectAnimation != null) - { - if (selectAnimation.State == Animation.States.Playing) - { - selectAnimation.Stop(); - } - selectAnimation.Dispose(); - selectAnimation = null; - } - container.RemoveAll(); indicatorList.Clear(); diff --git a/src/Tizen.NUI.Wearable/src/public/RecyclerView/RecyclerView.cs b/src/Tizen.NUI.Wearable/src/public/RecyclerView/RecyclerView.cs index 94e2c2d497d..a311455d2f1 100755 --- a/src/Tizen.NUI.Wearable/src/public/RecyclerView/RecyclerView.cs +++ b/src/Tizen.NUI.Wearable/src/public/RecyclerView/RecyclerView.cs @@ -76,6 +76,11 @@ private void OnItemSizeChanged(object source, PropertyNotification.NotifyEventAr layoutManager.Layout(ScrollingDirection == Direction.Horizontal ? ContentContainer.CurrentPosition.X : ContentContainer.CurrentPosition.Y); } + /// + /// Gets / Sets total number of items. + /// + /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API + [EditorBrowsable(EditorBrowsableState.Never)] public int TotalItemCount { get @@ -127,7 +132,11 @@ private void InitializeItems() } } - + /// + /// Scrolling direction mode for RecyclerView. . + /// + /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API + [EditorBrowsable(EditorBrowsableState.Never)] public new Direction ScrollingDirection { get @@ -253,6 +262,8 @@ protected override float AdjustTargetPositionOfScrollAnimation(float position) private View focusedView; private int prevFocusedDataIndex = 0; + /// + [EditorBrowsable(EditorBrowsableState.Never)] public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled) { View nextFocusedView = null; diff --git a/src/Tizen.NUI.Wearable/src/public/WearableList.cs b/src/Tizen.NUI.Wearable/src/public/WearableList.cs index a7f4c3293b8..9df4a1661b6 100755 --- a/src/Tizen.NUI.Wearable/src/public/WearableList.cs +++ b/src/Tizen.NUI.Wearable/src/public/WearableList.cs @@ -57,6 +57,8 @@ public class WearableList : RecyclerView DecelerationRate = 0.991f; } + /// + [EditorBrowsable(EditorBrowsableState.Never)] protected override void SetScrollbar() { if(LayoutManager != null) @@ -65,6 +67,8 @@ protected override void SetScrollbar() } } + /// + [EditorBrowsable(EditorBrowsableState.Never)] public new RecycleAdapter Adapter { get From c3a4fad0ce78aba9b03df1426614864dee62601c Mon Sep 17 00:00:00 2001 From: zhouhao02 Date: Tue, 17 Oct 2023 10:29:02 +0800 Subject: [PATCH 68/82] [NUI] Fix the SVACE issue. --- src/Tizen.NUI.Components/Controls/Button.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Tizen.NUI.Components/Controls/Button.cs b/src/Tizen.NUI.Components/Controls/Button.cs index 6601b2b05c8..a4e0b90d6bd 100755 --- a/src/Tizen.NUI.Components/Controls/Button.cs +++ b/src/Tizen.NUI.Components/Controls/Button.cs @@ -790,7 +790,15 @@ public StringSelector IconURLSelector } private StringSelector InternalIconURLSelector { - get => buttonIcon?.ResourceUrlSelector == null ? null : new StringSelector(buttonIcon.ResourceUrlSelector); + get + { + Selector resourceUrlSelector = buttonIcon?.ResourceUrlSelector; + if(resourceUrlSelector == null) + { + return null; + } + return new StringSelector(resourceUrlSelector); + } set { if (value == null || buttonIcon == null) From 40f895b0e3f72e8c7bbdb529599f5c152f25124e Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 17 Oct 2023 15:24:58 +0900 Subject: [PATCH 69/82] [NUI] Resolve registry issue for RenderTaskList After patch #5595 merged, there was some hidden bugs occured. This PR is one of portential bug fix. Signed-off-by: Eunki, Hong --- .../src/internal/Common/RenderTaskList.cs | 16 +++++++++++++++- src/Tizen.NUI/src/public/Window/Window.cs | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Common/RenderTaskList.cs b/src/Tizen.NUI/src/internal/Common/RenderTaskList.cs index 987e8408834..f47c59a52fd 100755 --- a/src/Tizen.NUI/src/internal/Common/RenderTaskList.cs +++ b/src/Tizen.NUI/src/internal/Common/RenderTaskList.cs @@ -17,6 +17,7 @@ using System; using System.ComponentModel; +using System.Runtime.InteropServices; namespace Tizen.NUI { @@ -95,7 +96,20 @@ public uint GetTaskCount() [EditorBrowsable(EditorBrowsableState.Never)] public RenderTask GetTask(uint index) { - RenderTask ret = new RenderTask(Interop.RenderTask.RenderTaskListGetTask(SwigCPtr, index), true); + global::System.IntPtr cPtr = Interop.RenderTask.RenderTaskListGetTask(SwigCPtr, index); + + RenderTask ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as RenderTask; + if (ret != null) + { + HandleRef CPtr = new HandleRef(this, cPtr); + Interop.BaseHandle.DeleteBaseHandle(CPtr); + CPtr = new HandleRef(null, global::System.IntPtr.Zero); + } + else + { + ret = new RenderTask(cPtr, true); + } + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index 36d60001bbe..12eff2773bf 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -1554,7 +1554,20 @@ internal Vector2 GetSize() [EditorBrowsable(EditorBrowsableState.Never)] public RenderTaskList GetRenderTaskList() { - RenderTaskList ret = new RenderTaskList(Interop.Stage.GetRenderTaskList(stageCPtr), true); + global::System.IntPtr cPtr = Interop.Stage.GetRenderTaskList(stageCPtr); + + RenderTaskList ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as RenderTaskList; + if (ret != null) + { + HandleRef CPtr = new HandleRef(this, cPtr); + Interop.BaseHandle.DeleteBaseHandle(CPtr); + CPtr = new HandleRef(null, global::System.IntPtr.Zero); + } + else + { + ret = new RenderTaskList(cPtr, true); + } + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } From e5f034908690ff2f8187dc7de872349e6e33af0d Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Wed, 18 Oct 2023 15:17:35 +0900 Subject: [PATCH 70/82] [NUI] Make AddFrameUpdateCallback with root view Previously, we can only add the root view of FrameUpdateCallback as root layer of window. Now let we add some API that user can set specific view for given FrameUpdateCallback will use. This API will be used when we want to optimize callback behaviour. Signed-off-by: Eunki, Hong --- src/Tizen.NUI/src/public/Window/Window.cs | 13 +++++++++++++ .../Samples/FrameUpdateCallbackTest.cs | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index 12eff2773bf..3779dfeb3e9 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -2218,6 +2218,19 @@ public void AddFrameUpdateCallback(FrameUpdateCallbackInterface frameUpdateCallb frameUpdateCallback?.AddFrameUpdateCallback(stageCPtr, Layer.getCPtr(GetRootLayer())); } + /// + /// Add FrameUpdateCallback with root view. + /// FrameUpdateCallbackInterface can only detach Views under given view. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddFrameUpdateCallback(FrameUpdateCallbackInterface frameUpdateCallback, View rootView) + { + if(rootView != null) + { + frameUpdateCallback?.AddFrameUpdateCallback(stageCPtr, View.getCPtr(rootView)); + } + } + /// /// Remove FrameUpdateCallback /// diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/FrameUpdateCallbackTest.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/FrameUpdateCallbackTest.cs index fe02d9ae05b..80751c103dc 100644 --- a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/FrameUpdateCallbackTest.cs +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/FrameUpdateCallbackTest.cs @@ -540,7 +540,8 @@ private void SetFrameUpdateCallback(float position) // Add frame callback on window. // OnUpdate callback of frameUpdateCallback will be called before every render frame. - window.AddFrameUpdateCallback(frameUpdateCallback); + // We can set root view what given frameUpdateCallback used + window.AddFrameUpdateCallback(frameUpdateCallback, controlView); // compute limit position the container could go. leftDirectionLimit = (float)window.Size.Width - (totalSize + (float)(INITIAL_POSITION)); From 8823da25378c8e602891f4493e27a92b99553c88 Mon Sep 17 00:00:00 2001 From: Taehyub Kim Date: Wed, 18 Oct 2023 20:07:38 +0900 Subject: [PATCH 71/82] [NUI] Add an API to set offset for drag window --- .../src/public/DragAndDrop/DragAndDrop.cs | 16 +++++++++++++++- test/NUIDnDSource/NUIDnDSource.cs | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs index 0e77eb85f8c..52b0c9eb33d 100755 --- a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs +++ b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs @@ -43,6 +43,8 @@ public class DragAndDrop : BaseHandle private Window mDragWindow; private int shadowWidth; private int shadowHeight; + private int dragWindowOffsetX = 0; + private int dragWindowOffsetY = 0; private bool initDrag = false; @@ -123,7 +125,7 @@ public void StartDragAndDrop(View sourceView, View shadowView, DragData dragData shadowHeight = MinDragWindowHeight; } - mDragWindow = new Window("DragWindow", new Rectangle(-shadowWidth, -shadowHeight, shadowWidth, shadowHeight), true) + mDragWindow = new Window("DragWindow", new Rectangle(dragWindowOffsetX, dragWindowOffsetY, shadowWidth, shadowHeight), true) { BackgroundColor = Color.Transparent, }; @@ -313,5 +315,17 @@ public void RemoveListener(Window targetWindow, DragAndDropWindowEventHandler ca throw new InvalidOperationException("Fail to RemoveListener for Window"); } } + + /// + /// Sets drag window offset + /// + /// The x direction offset + /// The y direction offset + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetDragWindowOffset(int x, int y) + { + dragWindowOffsetX = x; + dragWindowOffsetY = y; + } } } diff --git a/test/NUIDnDSource/NUIDnDSource.cs b/test/NUIDnDSource/NUIDnDSource.cs index 660db6c3489..7bceebef55c 100644 --- a/test/NUIDnDSource/NUIDnDSource.cs +++ b/test/NUIDnDSource/NUIDnDSource.cs @@ -24,6 +24,7 @@ void Initialize() { // Create DnD Instance dnd = DragAndDrop.Instance; + dnd.SetDragWindowOffset(-75, -75); Window.Instance.KeyEvent += OnKeyEvent; Window.Instance.WindowSize = new Size(900, 1080); From 3fcc1eb7bc23b5bd642df4b2c181c13ea748e824 Mon Sep 17 00:00:00 2001 From: Xianbing Teng Date: Tue, 17 Oct 2023 18:49:49 +0800 Subject: [PATCH 72/82] [NUI] Public RemoveBinding and ClearBinding apis --- .../src/public/XamlBinding/BindableObject.cs | 45 +++++++------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs index 2beb056fe4f..b5390fa7791 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs @@ -62,10 +62,7 @@ public object BindingContext [EditorBrowsable(EditorBrowsableState.Never)] public int LinePosition { get; set; } = -1; - void IDynamicResourceHandler.SetDynamicResource(BindableProperty property, string key) - { - SetDynamicResource(property, key, false); - } + void IDynamicResourceHandler.SetDynamicResource(BindableProperty property, string key) => SetDynamicResource(property, key, false); /// /// Raised when a property has changed. @@ -136,10 +133,7 @@ public void CopyBindingRelationShip(BindableObject other) [EditorBrowsable(EditorBrowsableState.Never)] public event EventHandler BindingContextChanged; - internal void ClearValue(BindableProperty property, bool fromStyle) - { - ClearValue(property, fromStyle: fromStyle, checkAccess: true); - } + internal void ClearValue(BindableProperty property, bool fromStyle) => ClearValue(property, fromStyle: fromStyle, checkAccess: true); /// /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue. @@ -213,7 +207,8 @@ public object GetValue(BindableProperty property) /// Removes a previously set binding. /// /// The BindableProperty from which to remove bindings. - internal void RemoveBinding(BindableProperty property) + [EditorBrowsable(EditorBrowsableState.Never)] + public void RemoveBinding(BindableProperty property) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -232,10 +227,7 @@ internal void RemoveBinding(BindableProperty property) /// The binding to set. /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] - public void SetBinding(BindableProperty targetProperty, BindingBase binding) - { - SetBinding(targetProperty, binding, false); - } + public void SetBinding(BindableProperty targetProperty, BindingBase binding) => SetBinding(targetProperty, binding, false); /// Internal used, will never changed to not hidden. [EditorBrowsable(EditorBrowsableState.Never)] @@ -326,6 +318,7 @@ internal void InternalSetValue(BindableProperty property, object value) context.Value = value; } + property.PropertyChanging?.Invoke(this, oldvalue, value); property.PropertyChanged?.Invoke(this, oldvalue, value); OnPropertyChanged(property.PropertyName); @@ -423,10 +416,7 @@ public static void RegisterPropertyGroup(BindableProperty property, HashSet /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] - protected void ApplyBindings() - { - ApplyBindings(skipBindingContext: false, fromBindingContextChanged: false); - } + protected void ApplyBindings() => ApplyBindings(skipBindingContext: false, fromBindingContextChanged: false); /// /// Override this method to execute an action when the BindingContext changes. @@ -650,10 +640,7 @@ bool CanBeSetFromStyle(BindableProperty property) return false; } - internal void SetDynamicResource(BindableProperty property, string key) - { - SetDynamicResource(property, key, false); - } + internal void SetDynamicResource(BindableProperty property, string key) => SetDynamicResource(property, key, false); internal void SetDynamicResource(BindableProperty property, string key, bool fromStyle) { @@ -675,10 +662,7 @@ internal void SetDynamicResource(BindableProperty property, string key, bool fro OnSetDynamicResource(property, key); } - internal void SetValue(BindableProperty property, object value, bool fromStyle) - { - SetValue(property, value, fromStyle, true); - } + internal void SetValue(BindableProperty property, object value, bool fromStyle) => SetValue(property, value, fromStyle, true); internal void SetValueCore(BindablePropertyKey propertyKey, object value, SetValueFlags attributes = SetValueFlags.None) { @@ -692,10 +676,7 @@ internal void SetValueCore(BindablePropertyKey propertyKey, object value, SetVal /// The value to set /// The set value flag [EditorBrowsable(EditorBrowsableState.Never)] - internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes = SetValueFlags.None) - { - SetValueCore(property, value, attributes, SetValuePrivateFlags.Default); - } + internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes = SetValueFlags.None) => SetValueCore(property, value, attributes, SetValuePrivateFlags.Default); internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes) { @@ -1115,7 +1096,11 @@ internal void ReplaceBindingElement(Dictionary oldNameScope, Dic } } - internal void ClearBinding() + /// + /// Unapplies all previously set bindings. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ClearBinding() { foreach (var property in properties) { From debba29c126f583bcfc62fb6b08a7ba6ffe9fa24 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 24 Oct 2023 11:55:19 +0900 Subject: [PATCH 73/82] [NUI] Flush action implement for LottieAnimationView Implement Flush action. It will be used when user want to ensure the Lottie property changed applied sequencly. Signed-off-by: Eunki, Hong --- .../internal/Interop/Interop.LottieAnimationView.cs | 5 ++++- .../src/public/BaseComponents/LottieAnimationView.cs | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.LottieAnimationView.cs b/src/Tizen.NUI/src/internal/Interop/Interop.LottieAnimationView.cs index 89c0a505713..f249c1aa52a 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.LottieAnimationView.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.LottieAnimationView.cs @@ -33,7 +33,10 @@ internal static partial class LottieAnimationView public static extern int AnimatedVectorImageVisualActionJumpToGet(); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_AnimatedVectorImageVisual_Actions_SET_DYNAMIC_PROPERTY_get")] - public static extern int AnimatedVectorImageVisualActionSetDynamicProperty(); + public static extern int AnimatedVectorImageVisualActionSetDynamicPropertyGet(); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_AnimatedVectorImageVisual_Actions_FLUSH_get")] + public static extern int AnimatedVectorImageVisualActionFlushGet(); } } } diff --git a/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs b/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs index 91ec9121c84..a4447f2adb9 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs @@ -970,7 +970,8 @@ public enum VectorProperty internal static readonly int ActionJumpTo = Interop.LottieAnimationView.AnimatedVectorImageVisualActionJumpToGet(); // This is used for internal purpose. - internal static readonly int ActionSetDynamicProperty = Interop.LottieAnimationView.AnimatedVectorImageVisualActionSetDynamicProperty(); + internal static readonly int ActionSetDynamicProperty = Interop.LottieAnimationView.AnimatedVectorImageVisualActionSetDynamicPropertyGet(); + internal static readonly int ActionFlush = Interop.LottieAnimationView.AnimatedVectorImageVisualActionFlushGet(); internal class VisualEventSignalArgs : EventArgs { @@ -1110,6 +1111,13 @@ static internal void RootCallback(int id, int returnType, uint frameNumber, ref } ret?.Dispose(); } + + internal void FlushLottieMessages() + { + NUILog.Debug($"<[{GetId()}]FLUSH>"); + + Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionFlush); + } #endregion Internal From 0a05a28ed7feb89887bb8afef65e687d75824f50 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Mon, 23 Oct 2023 11:50:27 +0900 Subject: [PATCH 74/82] [NUI.Scene3D] Bug fix when we get ModelNode from Model Since View constructor automatically change 'PositionUsesPivotPoint' value as false, some logic might changed when we Register ModelNode newly. Signed-off-by: Eunki, Hong --- .../src/public/Controls/Model.cs | 18 ++++++++++++++++-- .../src/public/ModelComponents/ModelNode.cs | 9 ++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs b/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs index 484a7dde87f..b778cbece0b 100755 --- a/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs +++ b/src/Tizen.NUI.Scene3D/src/public/Controls/Model.cs @@ -95,7 +95,7 @@ internal Model(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemory public Model(string modelUrl, string resourceDirectoryUrl = "") : this(Interop.Model.ModelNew(modelUrl, resourceDirectoryUrl), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - this.PositionUsesAnchorPoint = true; + this.PositionUsesPivotPoint = true; } /// @@ -106,7 +106,7 @@ public Model(string modelUrl, string resourceDirectoryUrl = "") : this(Interop.M public Model() : this(Interop.Model.ModelNew(), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - this.PositionUsesAnchorPoint = true; + this.PositionUsesPivotPoint = true; } /// @@ -117,6 +117,7 @@ public Model() : this(Interop.Model.ModelNew(), true) public Model(Model model) : this(Interop.Model.NewModel(Model.getCPtr(model)), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + this.PositionUsesPivotPoint = model.PositionUsesPivotPoint; } /// @@ -128,6 +129,7 @@ internal Model Assign(Model model) { Model ret = new Model(Interop.Model.ModelAssign(SwigCPtr, Model.getCPtr(model)), false); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + ret.PositionUsesPivotPoint = model.PositionUsesPivotPoint; return ret; } @@ -199,8 +201,14 @@ public ModelNode FindChildModelNodeByName(string nodeName) ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode; if (ret == null) { + // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.) + HandleRef handle = new HandleRef(this, cPtr); + bool originalPositionUsesAnchorPoint = Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint); + handle = new HandleRef(null, IntPtr.Zero); + // Register new animatable into Registry. ret = new ModelNode(cPtr, true); + ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint; } else { @@ -569,8 +577,14 @@ private ModelNode GetModelRoot() ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode; if (ret == null) { + // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.) + HandleRef handle = new HandleRef(this, cPtr); + bool originalPositionUsesAnchorPoint = Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint); + handle = new HandleRef(null, IntPtr.Zero); + // Register new animatable into Registry. ret = new ModelNode(cPtr, true); + ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint; } else { diff --git a/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs b/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs index 8974205c164..1f23f10aa20 100755 --- a/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs +++ b/src/Tizen.NUI.Scene3D/src/public/ModelComponents/ModelNode.cs @@ -58,7 +58,7 @@ internal ModelNode(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMe public ModelNode() : this(Interop.ModelNode.ModelNodeNew(), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - this.PositionUsesAnchorPoint = true; + this.PositionUsesPivotPoint = true; } /// @@ -80,6 +80,7 @@ internal ModelNode Assign(ModelNode modelNode) { ModelNode ret = new ModelNode(Interop.ModelNode.ModelNodeAssign(SwigCPtr, ModelNode.getCPtr(modelNode)), false); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + ret.PositionUsesPivotPoint = modelNode.PositionUsesPivotPoint; return ret; } @@ -172,8 +173,14 @@ public ModelNode FindChildModelNodeByName(string nodeName) ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode; if (ret == null) { + // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.) + HandleRef handle = new HandleRef(this, cPtr); + bool originalPositionUsesAnchorPoint = Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint); + handle = new HandleRef(null, IntPtr.Zero); + // Register new animatable into Registry. ret = new ModelNode(cPtr, true); + ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint; } else { From bee9ece00e8b1b034863d07c5d853d62a8e239e1 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 24 Oct 2023 10:47:09 +0900 Subject: [PATCH 75/82] [NUI] Preload some static values Since C# initialize static values when that namespace / class access first time, We need to access some static values at static Preload() timing. Signed-off-by: Eunki, Hong --- src/Tizen.NUI/src/internal/Common/Disposable.cs | 5 +++++ .../src/internal/Interop/NDalicPINVOKE.cs | 8 ++++++++ src/Tizen.NUI/src/public/Animation/Animatable.cs | 5 +++++ .../src/public/Application/NUIApplication.cs | 16 ++++++++++++++++ .../src/public/BaseComponents/ImageView.cs | 14 ++++++++++++++ .../src/public/BaseComponents/TextEditor.cs | 13 +++++++++++++ .../src/public/BaseComponents/TextField.cs | 13 +++++++++++++ .../src/public/BaseComponents/TextLabel.cs | 13 +++++++++++++ src/Tizen.NUI/src/public/BaseComponents/View.cs | 10 ++++++++++ src/Tizen.NUI/src/public/Common/BaseHandle.cs | 5 +++++ src/Tizen.NUI/src/public/Common/Container.cs | 8 ++++++++ 11 files changed, 110 insertions(+) diff --git a/src/Tizen.NUI/src/internal/Common/Disposable.cs b/src/Tizen.NUI/src/internal/Common/Disposable.cs index 7884c303e28..72d1dc8ef47 100644 --- a/src/Tizen.NUI/src/internal/Common/Disposable.cs +++ b/src/Tizen.NUI/src/internal/Common/Disposable.cs @@ -25,6 +25,11 @@ namespace Tizen.NUI /// 6 public class Disposable : global::System.IDisposable { + static internal void Preload() + { + // Do nothing. Just call for load static values. + } + /// /// The flag to check if it is already disposed of. /// diff --git a/src/Tizen.NUI/src/internal/Interop/NDalicPINVOKE.cs b/src/Tizen.NUI/src/internal/Interop/NDalicPINVOKE.cs index a55f6227534..560684c28b5 100755 --- a/src/Tizen.NUI/src/internal/Interop/NDalicPINVOKE.cs +++ b/src/Tizen.NUI/src/internal/Interop/NDalicPINVOKE.cs @@ -245,6 +245,14 @@ static NDalicPINVOKE() { } + static internal void Preload() + { + // Do nothing. Just call for load static values. + var temporalSwigExceptionHelper = swigExceptionHelper; + var temporalSwigStringHelper = swigStringHelper; + ThrowExceptionIfExists(); + } + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_BaseHandle")] public static extern void DeleteBaseHandle(global::System.Runtime.InteropServices.HandleRef jarg1); diff --git a/src/Tizen.NUI/src/public/Animation/Animatable.cs b/src/Tizen.NUI/src/public/Animation/Animatable.cs index 91233e65d70..b587488e575 100755 --- a/src/Tizen.NUI/src/public/Animation/Animatable.cs +++ b/src/Tizen.NUI/src/public/Animation/Animatable.cs @@ -26,6 +26,11 @@ namespace Tizen.NUI /// 3 public class Animatable : BaseHandle { + static internal new void Preload() + { + BaseHandle.Preload(); + // Do nothing. Just call for load static values. + } /// /// Create an instance of animatable. diff --git a/src/Tizen.NUI/src/public/Application/NUIApplication.cs b/src/Tizen.NUI/src/public/Application/NUIApplication.cs index 457b5916e09..eabcdef9ef4 100755 --- a/src/Tizen.NUI/src/public/Application/NUIApplication.cs +++ b/src/Tizen.NUI/src/public/Application/NUIApplication.cs @@ -640,6 +640,22 @@ protected override void OnCreate() static public void Preload() { Interop.Application.PreInitialize(); + + // Initialize some static utility + var disposalbeQueue = DisposeQueue.Instance; + var registry = Registry.Instance; + + // Initialize some BaseComponent static variables now + BaseComponents.View.Preload(); + BaseComponents.ImageView.Preload(); + BaseComponents.TextLabel.Preload(); + BaseComponents.TextEditor.Preload(); + BaseComponents.TextField.Preload(); + Disposable.Preload(); + + // Initialize exception tasks. It must be called end of Preload() + NDalicPINVOKE.Preload(); + IsPreload = true; } diff --git a/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs b/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs index dd9f625486e..407d042d46b 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs @@ -32,6 +32,15 @@ public partial class ImageView : View { static ImageView() { } + static internal new void Preload() + { + // Do not call View.Preload(), since we already call it + + Property.Preload(); + // Do nothing. Just call for load static values. + var temporalCachedImagePropertyKeyList = cachedImagePropertyKeyList; + } + private EventHandler _resourceReadyEventHandler; private ResourceReadyEventCallbackType _resourceReadyEventCallback; private EventHandler _resourceLoadedEventHandler; @@ -1882,6 +1891,11 @@ public ResourceLoadingStatusType Status internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet(); internal static readonly int PlaceHolderUrl = Interop.ImageView.PlaceHolderImageGet(); internal static readonly int TransitionEffect = Interop.ImageView.TransitionEffectGet(); + + internal static void Preload() + { + // Do nothing. Just call for load static values. + } } private enum ImageType diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextEditor.cs b/src/Tizen.NUI/src/public/BaseComponents/TextEditor.cs index 85f6d988080..61b41598341 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/TextEditor.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextEditor.cs @@ -57,6 +57,14 @@ public partial class TextEditor : View static TextEditor() { } + static internal new void Preload() + { + // Do not call View.Preload(), since we already call it + + Property.Preload(); + // Do nothing. Just call for load static values. + } + /// /// Creates the TextEditor control. /// @@ -2767,6 +2775,11 @@ private void TextEditorTextChanged(object sender, TextChangedEventArgs e) internal static readonly int InputFilter = Interop.TextEditor.InputFilterGet(); internal static readonly int Strikethrough = Interop.TextEditor.StrikethroughGet(); internal static readonly int CharacterSpacing = Interop.TextEditor.CharacterSpacingGet(); + + internal static void Preload() + { + // Do nothing. Just call for load static values. + } } internal class InputStyle diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextField.cs b/src/Tizen.NUI/src/public/BaseComponents/TextField.cs index 36f50b05b27..e2506a78f7a 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/TextField.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextField.cs @@ -57,6 +57,14 @@ public partial class TextField : View static TextField() { } + static internal new void Preload() + { + // Do not call View.Preload(), since we already call it + + Property.Preload(); + // Do nothing. Just call for load static values. + } + /// /// Creates the TextField control. /// @@ -2765,6 +2773,11 @@ private void TextFieldTextChanged(object sender, TextChangedEventArgs e) internal static readonly int InputFilter = Interop.TextField.InputFilterGet(); internal static readonly int Strikethrough = Interop.TextField.StrikethroughGet(); internal static readonly int CharacterSpacing = Interop.TextField.CharacterSpacingGet(); + + internal static void Preload() + { + // Do nothing. Just call for load static values. + } } internal class InputStyle diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs index 1c979212c11..98474f4e8a7 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs @@ -84,6 +84,14 @@ protected override void OnMeasure(MeasureSpecification widthMeasureSpec, Measure static TextLabel() { } + static internal new void Preload() + { + // Do not call View.Preload(), since we already call it + + Property.Preload(); + // Do nothing. Just call for load static values. + } + private static SystemFontTypeChanged systemFontTypeChanged = new SystemFontTypeChanged(); private static SystemLocaleLanguageChanged systemLocaleLanguageChanged = new SystemLocaleLanguageChanged(); static private string defaultStyleName = "Tizen.NUI.BaseComponents.TextLabel"; @@ -1847,6 +1855,11 @@ private void RequestLayout() internal static readonly int EllipsisPosition = Interop.TextLabel.EllipsisPositionGet(); internal static readonly int Strikethrough = Interop.TextLabel.StrikethroughGet(); internal static readonly int CharacterSpacing = Interop.TextLabel.CharacterSpacingGet(); + + internal static void Preload() + { + // Do nothing. Just call for load static values. + } } private void OnShadowColorChanged(float x, float y, float z, float w) diff --git a/src/Tizen.NUI/src/public/BaseComponents/View.cs b/src/Tizen.NUI/src/public/BaseComponents/View.cs index 059284387b0..a2ca0546522 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/View.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/View.cs @@ -105,6 +105,16 @@ static View() RegisterAccessibilityDelegate(); } + static internal new void Preload() + { + Container.Preload(); + + // Do nothing. Just call for load static values. + var temporalPositionPropertyGroup = positionPropertyGroup; + var temporalSizePropertyGroup = sizePropertyGroup; + var temporalScalePropertyGroup = scalePropertyGroup; + } + /// /// Accessibility mode for controlling View's Accessible implementation. /// It is only relevant when deriving custom controls from View directly, diff --git a/src/Tizen.NUI/src/public/Common/BaseHandle.cs b/src/Tizen.NUI/src/public/Common/BaseHandle.cs index 5f85509181b..b8e7eb3ce76 100755 --- a/src/Tizen.NUI/src/public/Common/BaseHandle.cs +++ b/src/Tizen.NUI/src/public/Common/BaseHandle.cs @@ -28,6 +28,11 @@ namespace Tizen.NUI /// 3 public class BaseHandle : Element, global::System.IDisposable { + static internal void Preload() + { + // Do nothing. Just call for load static values. + } + /// /// swigCMemOwn /// diff --git a/src/Tizen.NUI/src/public/Common/Container.cs b/src/Tizen.NUI/src/public/Common/Container.cs index 13577bf0c79..fdfbf2c9c81 100755 --- a/src/Tizen.NUI/src/public/Common/Container.cs +++ b/src/Tizen.NUI/src/public/Common/Container.cs @@ -41,6 +41,14 @@ public abstract class Container : Animatable, IResourcesProvider ResourceDictionary _resources; bool IResourcesProvider.IsResourcesCreated => _resources != null; + static internal new void Preload() + { + Animatable.Preload(); + + // Do nothing. Just call for load static values. + var temporalXamlStyleProperty = XamlStyleProperty; + } + internal Container(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) { // No un-managed data hence no need to store a native ptr From ec95af606d3c791af5ac8b2fdb3c16e245e3883f Mon Sep 17 00:00:00 2001 From: Wonsik Jung Date: Tue, 24 Oct 2023 16:22:16 +0900 Subject: [PATCH 76/82] [NUI] Supports to set/get full screen sized window To support set/get full screen sized window. The full screen sized window means the window is resized with screen size. In addition, this window is the z-order is the highest. --- .../src/internal/Interop/Interop.Window.cs | 7 +++++ src/Tizen.NUI/src/public/Window/Window.cs | 26 +++++++++++++++++++ .../Tizen.NUI.Samples/Samples/WindowTest.cs | 10 +++++++ .../testcase/public/Window/TSWindow.cs | 24 +++++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs b/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs index 5cf427cf10f..84427a9d14a 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.Window.cs @@ -393,6 +393,13 @@ internal static partial class Window [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_KeyboardUnGrab")] [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] public static extern bool KeyboardUnGrab(global::System.Runtime.InteropServices.HandleRef window); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_SetFullScreen")] + public static extern void SetFullScreen(global::System.Runtime.InteropServices.HandleRef window, bool fullscreen); + + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_GetFullScreen")] + [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] + public static extern bool GetFullScreen(global::System.Runtime.InteropServices.HandleRef window); } } } diff --git a/src/Tizen.NUI/src/public/Window/Window.cs b/src/Tizen.NUI/src/public/Window/Window.cs index 3779dfeb3e9..6df4dd112cf 100755 --- a/src/Tizen.NUI/src/public/Window/Window.cs +++ b/src/Tizen.NUI/src/public/Window/Window.cs @@ -2423,6 +2423,32 @@ public Layer FindLayerByID(uint id) return ret; } + /// + /// Sets to resize window with full screen. + /// If full screen size is set for the window, + /// window will be resized with full screen. + /// In addition, the full screen sized window's z-order is the highest. + /// + /// If fullscreen is true, set fullscreen or unset. + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetFullScreen(bool fullscreen) + { + Interop.Window.SetFullScreen(SwigCPtr, fullscreen); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Gets whether the full screen sized window or not. + /// + /// Returns true if the full screen sized window is. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool GetFullScreen() + { + bool ret = Interop.Window.GetFullScreen(SwigCPtr); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + /// /// Get Native Window handle. /// diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs index f3fe59be6e8..583bc7da17d 100644 --- a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs @@ -179,6 +179,16 @@ public void OnKeyEvent(object sender, Window.KeyEventArgs e) case KEY_NUM_7: mainWin.SetMimimumSize(new Size2D(100, 100)); break; + case KEY_NUM_8: + if(mainWin.GetFullScreen() == false) + { + mainWin.SetFullScreen(true); + } + else + { + mainWin.SetFullScreen(false); + } + break; default: log.Fatal(tag, $"no test!"); diff --git a/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Window/TSWindow.cs b/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Window/TSWindow.cs index 0e5955f1ab3..e4e814a7518 100755 --- a/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Window/TSWindow.cs +++ b/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Window/TSWindow.cs @@ -1625,5 +1625,29 @@ public void WindowRequestResizeToServer() tlog.Debug(tag, $"WindowRequestResizeToServer END (OK)"); } + + [Test] + [Category("P1")] + [Description("Window SetFullScreen")] + [Property("SPEC", "Tizen.NUI.Window.SetFullScreen M")] + [Property("SPEC_URL", "-")] + [Property("CRITERIA", "MR")] + public void SetFullScreen() + { + tlog.Debug(tag, $"SetFullScreen START"); + + try + { + win.SetFullScreen(true); + Assert.IsTrue(win.GetFullScreen()); + } + catch (Exception e) + { + tlog.Debug(tag, e.Message.ToString()); + Assert.Fail("Caught Exception : Failed!"); + } + + tlog.Debug(tag, $"SetFullScreen END (OK)"); + } } } From 609c20000bcadfea43034649457d0260394778a1 Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Tue, 24 Oct 2023 23:20:08 +0900 Subject: [PATCH 77/82] [NUI.Components] Remove build warning for Control.Preload() We implement View.Preload() API now. So compiler can feel dizzy which one is Control.Preload() should do. To avoid this compilation warning, let we add 'new' keyword for it. Signed-off-by: Eunki Hong --- src/Tizen.NUI.Components/Controls/Control.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tizen.NUI.Components/Controls/Control.cs b/src/Tizen.NUI.Components/Controls/Control.cs index 3145db3dc3f..3007d93dcd5 100755 --- a/src/Tizen.NUI.Components/Controls/Control.cs +++ b/src/Tizen.NUI.Components/Controls/Control.cs @@ -72,7 +72,7 @@ static Control() /// This is used to improve theme performance. /// [EditorBrowsable(EditorBrowsableState.Never)] - static public void Preload() + static public new void Preload() { DefaultThemeCreator.Preload(); } From 1673f0268c8c1457729c36e5139e324840dd284c Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Wed, 18 Oct 2023 16:16:27 +0900 Subject: [PATCH 78/82] [NUI] Make View.TooltipText return valid value Let we remove useless error message + Make getter return valid setting value for View.TooltipText property. Signed-off-by: Eunki, Hong --- .../src/public/BaseComponents/View.cs | 20 +++++++++++++++---- .../testcase/public/TSView.cs | 19 ++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Tizen.NUI/src/public/BaseComponents/View.cs b/src/Tizen.NUI/src/public/BaseComponents/View.cs index a2ca0546522..0876bf7ff02 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/View.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/View.cs @@ -866,12 +866,24 @@ private string InternalTooltipText { using (var propertyValue = GetProperty(Property.TOOLTIP)) { - if (propertyValue != null && propertyValue.Get(out string retrivedValue)) + using var propertyMap = new PropertyMap(); + if (propertyValue != null && propertyValue.Get(propertyMap)) { - return retrivedValue; + using var retrivedContentValue = propertyMap?.Find(NDalic.TooltipContent); + if (retrivedContentValue != null) + { + using var contextPropertyMap = new PropertyMap(); + if (retrivedContentValue.Get(contextPropertyMap)) + { + using var retrivedTextValue = contextPropertyMap?.Find(NDalic.TextVisualText); + if (retrivedTextValue != null && retrivedTextValue.Get(out string retrivedValue)) + { + return retrivedValue; + } + } + } } - NUILog.Error($"[ERROR] Fail to get TooltipText! Return error MSG (error to get TooltipText)!"); - return "error to get TooltipText"; + return ""; } } set diff --git a/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs b/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs index b350ca8e481..3a2ecb63dbb 100644 --- a/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs +++ b/test/Tizen.NUI.Devel.Tests.Ubuntu/Tizen.NUI.Devel.Tests/testcase/public/TSView.cs @@ -207,5 +207,24 @@ public void ColorBlue_GET_SET_VALUE() testView.Dispose(); } + + + [Test] + [Category("P1")] + [Description("Get value test for View.ToolTipText")] + [Property("SPEC", "Tizen.NUI.BaseComponents.View.ToolTipText")] + [Property("SPEC_URL", "-")] + [Property("CRITERIA", "PRW")] + [Property("AUTHOR", "eunkiki.hong@samsung.com")] + public void ToolTipText_GET_SET_VALUE() + { + /* TEST CODE */ + View testView = new View(); + + testView.TooltipText = "tooltipText"; + Assert.AreEqual("tooltipText", testView.TooltipText, "Should get equal string value what we set before"); + + testView.Dispose(); + } } } From 23fbd1924fa77dfeb89ca6d60a1ef20c0d29c65d Mon Sep 17 00:00:00 2001 From: zhouhao02 Date: Wed, 11 Oct 2023 14:05:52 +0800 Subject: [PATCH 79/82] [NUI] Fix some SVACE issues. --- .../chipmunk/cpSpaceDebugDrawOptions.cs | 12 ++++------ .../src/internal/Xaml/CreateValuesVisitor.cs | 6 ++--- .../BaseComponents/DirectRenderingGLView.cs | 23 +++++++++++-------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs index d787f6e8104..7b9afef9716 100644 --- a/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs +++ b/src/Tizen.NUI.Physics2D/src/internal/chipmunk/cpSpaceDebugDrawOptions.cs @@ -104,15 +104,13 @@ internal struct cpSpaceDebugDrawOptions private IntPtr ToPointer() { IntPtr drawOptionsPtr = NativeInterop.AllocStructure(); - try + if (Marshal.SizeOf(typeof(cpSpaceDebugDrawOptions)) == 0) { - Marshal.StructureToPtr(this, drawOptionsPtr, false); + throw new ArgumentNullException("The size of type cpSpaceDebugDrawOptions should not be 0."); } - catch (Exception exception) - { - Tizen.Log.Fatal("NUI", "[Error] got exception during Marshal.StructureToPtr, this should not occur, message : " + exception.Message); - } - + + Marshal.StructureToPtr(this, drawOptionsPtr, false); + return drawOptionsPtr; } diff --git a/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs b/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs index 266e0b4603e..a7b98c68939 100755 --- a/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs +++ b/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs @@ -202,9 +202,9 @@ public void Visit(ElementNode node, INode parentNode) Values[node] = value; } - - if (value != null && value is BindableObject) - NameScope.SetNameScope(value as BindableObject, node.Namescope); + var bindableObject = value as BindableObject; + if (bindableObject != null) + NameScope.SetNameScope(bindableObject, node.Namescope); } public void Visit(RootNode node, INode parentNode) diff --git a/src/Tizen.NUI/src/public/BaseComponents/DirectRenderingGLView.cs b/src/Tizen.NUI/src/public/BaseComponents/DirectRenderingGLView.cs index b2bf0d90560..2946cb4ebba 100644 --- a/src/Tizen.NUI/src/public/BaseComponents/DirectRenderingGLView.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/DirectRenderingGLView.cs @@ -183,18 +183,23 @@ public void BindTextureResources(List textures) { unsafe { - if (textures != null && sizeof(IntPtr) * textures.Count > 0) + + if (textures != null) { - IntPtr unmanagedPointer = Marshal.AllocHGlobal(checked(sizeof(IntPtr) * textures.Count)); - IntPtr[] texturesArray = new IntPtr[textures.Count]; - for (int i = 0; i < textures.Count; i++) + int intptrBytes = checked(sizeof(IntPtr) * textures.Count); + if (intptrBytes>0) { - texturesArray[i] = HandleRef.ToIntPtr(Texture.getCPtr(textures[i])); - } - System.Runtime.InteropServices.Marshal.Copy(texturesArray, 0, unmanagedPointer, textures.Count); + IntPtr unmanagedPointer = Marshal.AllocHGlobal(intptrBytes); + IntPtr[] texturesArray = new IntPtr[textures.Count]; + for (int i = 0; i < textures.Count; i++) + { + texturesArray[i] = HandleRef.ToIntPtr(Texture.getCPtr(textures[i])); + } + System.Runtime.InteropServices.Marshal.Copy(texturesArray, 0, unmanagedPointer, textures.Count); - Interop.GLView.GlViewBindTextureResources(SwigCPtr, unmanagedPointer, textures.Count); - Marshal.FreeHGlobal(unmanagedPointer); + Interop.GLView.GlViewBindTextureResources(SwigCPtr, unmanagedPointer, textures.Count); + Marshal.FreeHGlobal(unmanagedPointer); + } } } } From 54c0a28cc53453778e1c228aca47599e7f2d027a Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 24 Oct 2023 17:26:26 +0900 Subject: [PATCH 80/82] [NUI] Change Accessibility.cs don't use net6.0 specific function Let we minimize the net core dependency Signed-off-by: Eunki, Hong --- src/Tizen.NUI/src/public/Accessibility/Accessibility.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs index 425c3bc59dd..a8ef2c92127 100755 --- a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs +++ b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs @@ -332,7 +332,11 @@ public enum SayFinishedState private static void SayFinishedEventCallback(string status) { - var result = sayFinishedStateDictionary.GetValueOrDefault(status, SayFinishedState.Invalid); + SayFinishedState result; + if (!sayFinishedStateDictionary.TryGetValue(status, out result)) + { + result = SayFinishedState.Invalid; + } NUILog.Debug($"sayFinishedEventCallback(res={result}) called!"); SayFinished?.Invoke(typeof(Accessibility), new SayFinishedEventArgs(result)); From 47da1cf234aacc5dd521c78c7d5100bca3b2fd14 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Wed, 25 Oct 2023 16:32:47 +0900 Subject: [PATCH 81/82] [NUI] Version up nui22249 Signed-off-by: Eunki, Hong --- packaging/csapi-tizenfx.spec | 2 +- packaging/version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/csapi-tizenfx.spec b/packaging/csapi-tizenfx.spec index 41385b486e3..a8b1ebae132 100644 --- a/packaging/csapi-tizenfx.spec +++ b/packaging/csapi-tizenfx.spec @@ -1,7 +1,7 @@ # Auto-generated from csapi-tizenfx.spec.in by makespec.sh %define TIZEN_NET_API_VERSION 12 -%define TIZEN_NET_RPM_VERSION 12.0.0.999+nui22245 +%define TIZEN_NET_RPM_VERSION 12.0.0.999+nui22249 %define TIZEN_NET_NUGET_VERSION 12.0.0.99999 %define DOTNET_ASSEMBLY_PATH /usr/share/dotnet.tizen/framework diff --git a/packaging/version.txt b/packaging/version.txt index 35633e8a2ba..c75a1afc92a 100755 --- a/packaging/version.txt +++ b/packaging/version.txt @@ -6,4 +6,4 @@ RPM_VERSION=12.0.0.999 NUGET_VERSION=12.0.0.99999 # RPM Version Suffix -RPM_VERSION_SUFFIX=nui22245 +RPM_VERSION_SUFFIX=nui22249 From a3659d0a2d090fabbf979cf4aaa3154c2f588e4a Mon Sep 17 00:00:00 2001 From: Wonsik Jung Date: Mon, 30 Oct 2023 11:30:01 +0900 Subject: [PATCH 82/82] [NUI] Reinforce window sample ReInforce window samples to verify window's functions --- .../Tizen.NUI.Samples/Samples/WindowTest.cs | 560 +++++++++++++++-- .../Tizen.NUI.Samples/Samples/WindowTest1.cs | 562 ++++++++++++++++++ 2 files changed, 1087 insertions(+), 35 deletions(-) create mode 100644 test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest1.cs diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs index 583bc7da17d..ccdb093cdd2 100644 --- a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest.cs @@ -2,6 +2,7 @@ using global::System; using Tizen.NUI; using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; using Tizen.System; using System.Collections.Generic; using NUnit.Framework; @@ -20,6 +21,7 @@ public class WindowTest : IExample Timer tm; bool manualRotation; int rotationCount; + private Window subWindow = null; private const string KEY_NUM_1 = "1"; private const string KEY_NUM_2 = "2"; @@ -32,6 +34,260 @@ public class WindowTest : IExample private const string KEY_NUM_9 = "9"; private const string KEY_NUM_0 = "0"; + private static readonly string ImagePath = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "/images/Dali/CubeTransitionEffect/"; + + class CustomBorder : DefaultBorder + { + private static readonly string ResourcePath = Tizen.Applications.Application.Current.DirectoryInfo.Resource; + private static readonly string MinimalizeIcon = ResourcePath + "/images/minimalize.png"; + private static readonly string MaximalizeIcon = ResourcePath + "/images/maximalize.png"; + private static readonly string RestoreIcon = ResourcePath + "/images/smallwindow.png"; + private static readonly string CloseIcon = ResourcePath + "/images/close.png"; + private static readonly string LeftCornerIcon = ResourcePath + "/images/leftCorner.png"; + private static readonly string RightCornerIcon = ResourcePath + "/images/rightCorner.png"; + + private int width = 500; + private bool hide = false; + private View borderView; + private TextLabel title; + + private ImageView minimalizeIcon; + private ImageView maximalizeIcon; + private ImageView closeIcon; + private ImageView leftCornerIcon; + private ImageView rightCornerIcon; + + private Rectangle preWinPositonSize; + + public CustomBorder() : base() + { + BorderHeight = 50; + OverlayMode = true; + BorderLineThickness = 0; + } + + public override bool CreateTopBorderView(View topView) + { + if (topView == null) + { + return false; + } + topView.Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + VerticalAlignment = VerticalAlignment.Center, + CellPadding = new Size2D(20, 20), + }; + title = new TextLabel() + { + Text = "CustomBorder", + }; + + var button = new Button() + { + Text = "AlwaysOnTop", + }; + button.Clicked += (s, e) => + { + BorderWindow.EnableFloatingMode(true); + }; + topView.Add(title); + topView.Add(button); + return true; + } + + public override bool CreateBottomBorderView(View bottomView) + { + if (bottomView == null) + { + return false; + } + bottomView.Layout = new RelativeLayout(); + + minimalizeIcon = new ImageView() + { + ResourceUrl = MinimalizeIcon, + AccessibilityHighlightable = true, + }; + + maximalizeIcon = new ImageView() + { + ResourceUrl = MaximalizeIcon, + AccessibilityHighlightable = true, + }; + + closeIcon = new ImageView() + { + ResourceUrl = CloseIcon, + AccessibilityHighlightable = true, + }; + + leftCornerIcon = new ImageView() + { + ResourceUrl = LeftCornerIcon, + AccessibilityHighlightable = true, + }; + + rightCornerIcon = new ImageView() + { + ResourceUrl = RightCornerIcon, + AccessibilityHighlightable = true, + }; + + RelativeLayout.SetRightTarget(minimalizeIcon, maximalizeIcon); + RelativeLayout.SetRightRelativeOffset(minimalizeIcon, 0.0f); + RelativeLayout.SetHorizontalAlignment(minimalizeIcon, RelativeLayout.Alignment.End); + RelativeLayout.SetRightTarget(maximalizeIcon, closeIcon); + RelativeLayout.SetRightRelativeOffset(maximalizeIcon, 0.0f); + RelativeLayout.SetHorizontalAlignment(maximalizeIcon, RelativeLayout.Alignment.End); + RelativeLayout.SetRightTarget(closeIcon, rightCornerIcon); + RelativeLayout.SetRightRelativeOffset(closeIcon, 0.0f); + RelativeLayout.SetHorizontalAlignment(closeIcon, RelativeLayout.Alignment.End); + RelativeLayout.SetRightRelativeOffset(rightCornerIcon, 1.0f); + RelativeLayout.SetHorizontalAlignment(rightCornerIcon, RelativeLayout.Alignment.End); + bottomView.Add(leftCornerIcon); + bottomView.Add(minimalizeIcon); + bottomView.Add(maximalizeIcon); + bottomView.Add(closeIcon); + bottomView.Add(rightCornerIcon); + + + minimalizeIcon.TouchEvent += OnMinimizeIconTouched; + maximalizeIcon.TouchEvent += OnMaximizeIconTouched; + closeIcon.TouchEvent += OnCloseIconTouched; + leftCornerIcon.TouchEvent += OnLeftBottomCornerIconTouched; + rightCornerIcon.TouchEvent += OnRightBottomCornerIconTouched; + + minimalizeIcon.AccessibilityActivated += (s, e) => + { + MinimizeBorderWindow(); + }; + maximalizeIcon.AccessibilityActivated += (s, e) => + { + MaximizeBorderWindow(); + }; + closeIcon.AccessibilityActivated += (s, e) => + { + CloseBorderWindow(); + }; + + minimalizeIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Minimize"; + }; + maximalizeIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Maximize"; + }; + closeIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Close"; + }; + leftCornerIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Resize"; + }; + rightCornerIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Resize"; + }; + + minimalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + maximalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + closeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + leftCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + rightCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + + return true; + } + + public override void CreateBorderView(View borderView) + { + this.borderView = borderView; + borderView.CornerRadius = new Vector4(0.03f, 0.03f, 0.03f, 0.03f); + borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative; + borderView.BackgroundColor = new Color(1, 1, 1, 0.3f); + } + + public override void OnCreated(View borderView) + { + base.OnCreated(borderView); + UpdateIcons(); + } + + public override bool OnCloseIconTouched(object sender, View.TouchEventArgs e) + { + base.OnCloseIconTouched(sender, e); + return true; + } + + public override bool OnMinimizeIconTouched(object sender, View.TouchEventArgs e) + { + if (e.Touch.GetState(0) == PointStateType.Up) + { + if (BorderWindow.IsMaximized() == true) + { + BorderWindow.Maximize(false); + } + preWinPositonSize = BorderWindow.WindowPositionSize; + BorderWindow.WindowPositionSize = new Rectangle(preWinPositonSize.X, preWinPositonSize.Y, 500, 0); + } + return true; + } + + public override void OnRequestResize() + { + if (borderView != null) + { + borderView.BackgroundColor = new Color(0, 1, 0, 0.3f); // 보더의 배경을 변경할 수 있습니다. + } + } + + public override void OnResized(int width, int height) + { + if (borderView != null) + { + if (this.width > width && hide == false) + { + title.Hide(); + hide = true; + } + else if (this.width < width && hide == true) + { + title.Show(); + hide = false; + } + borderView.BackgroundColor = new Color(1, 1, 1, 0.3f); // 리사이즈가 끝나면 보더의 색깔은 원래대로 돌려놓습니다. + base.OnResized(width, height); + UpdateIcons(); + } + } + + private void UpdateIcons() + { + if (BorderWindow != null && borderView != null) + { + if (BorderWindow.IsMaximized() == true) + { + if (maximalizeIcon != null) + { + maximalizeIcon.ResourceUrl = RestoreIcon; + } + } + else + { + if (maximalizeIcon != null) + { + maximalizeIcon.ResourceUrl = MaximalizeIcon; + } + } + } + } + + } + + + void Initialize() { @@ -43,7 +299,7 @@ void Initialize() Information.TryGetValue("http://tizen.org/feature/screen.width", out screenWidth); Information.TryGetValue("http://tizen.org/feature/screen.height", out screenHeight); log.Fatal(tag, $"Initialize= screenWidth {screenWidth}, screenHeight {screenHeight} "); - Rectangle inputRegion = new Rectangle(0,0,screenWidth,screenHeight/2); + Rectangle inputRegion = new Rectangle(0, 0, screenWidth, screenHeight / 2); mainWin.IncludeInputRegion(inputRegion); addingInput = 0; @@ -75,24 +331,20 @@ void Initialize() manualRotation = false; rotationCount = 0; - - tm = new Timer(100); - tm.Tick += Tm_Tick; - tm.Start(); } private bool Tm_Tick(object source, Timer.TickEventArgs e) { bool rotating = mainWin.IsWindowRotating(); log.Fatal(tag, $"window is Rotating: {rotating}"); - if(rotating && manualRotation) + if (rotating && manualRotation) { rotationCount++; - if(rotationCount > 100) + if (rotationCount > 100) { - log.Fatal(tag, $"call SendRotationCompletedAcknowledgement"); - mainWin.SendRotationCompletedAcknowledgement(); - rotationCount = 0; + log.Fatal(tag, $"call SendRotationCompletedAcknowledgement"); + mainWin.SendRotationCompletedAcknowledgement(); + rotationCount = 0; } } return true; @@ -105,23 +357,23 @@ private void WinTouchEvent(object sender, Window.TouchEventArgs e) Vector2 touchpoint = e.Touch.GetScreenPosition(0); log.Fatal(tag, $"WinTouchEvent={touchpoint.X}, {touchpoint.Y}"); int xPosition = 0; - if(addingInput == 0) + if (addingInput == 0) { - if(touchpoint.Y > (screenHeight/2 - 50)) + if (touchpoint.Y > (screenHeight / 2 - 50)) { - int yPostion = screenHeight/2 + 1; - int height = screenHeight/2; + int yPostion = screenHeight / 2 + 1; + int height = screenHeight / 2; log.Fatal(tag, $"WinTouchEvent= Include {xPosition},{yPostion} {screenWidth}x{height} "); - mainWin.IncludeInputRegion(new Rectangle(xPosition,yPostion,screenWidth,height)); + mainWin.IncludeInputRegion(new Rectangle(xPosition, yPostion, screenWidth, height)); addingInput = 1; } } else { - if(touchpoint.Y > (screenHeight - 50)) + if (touchpoint.Y > (screenHeight - 50)) { - int yPostion = screenHeight/2 + 1; - int height = screenHeight/2; + int yPostion = screenHeight / 2 + 1; + int height = screenHeight / 2; log.Fatal(tag, $"WinTouchEvent= Exclude {xPosition},{yPostion} {screenWidth}x{height} "); mainWin.ExcludeInputRegion(new Rectangle(xPosition, yPostion, screenWidth, height)); addingInput = 0; @@ -143,30 +395,47 @@ public void OnKeyEvent(object sender, Window.KeyEventArgs e) //Exit(); break; - case KEY_NUM_1: - log.Fatal(tag, $"pressed Key Num 1!"); + case KEY_NUM_0: + CreateSubWindow(); break; - case KEY_NUM_2: - mainWin.Maximize(true); + case KEY_NUM_1: + log.Fatal(tag, $"SetClass test"); + mainWin.SetClass("windowTitle", "windowClass"); break; - case KEY_NUM_3: - if(mainWin.IsMaximized()) + case KEY_NUM_2: + log.Fatal(tag, $"Maximize test"); + if (mainWin.IsMaximized()) { + log.Fatal(tag, $"Unset Maximize"); mainWin.Maximize(false); } + else + { + log.Fatal(tag, $"Set Maximize"); + mainWin.Maximize(true); + } break; - case KEY_NUM_4: + + case KEY_NUM_3: + log.Fatal(tag, $"Set MaximumSize test"); mainWin.SetMaximumSize(new Size2D(700, 700)); break; - case KEY_NUM_5: + + case KEY_NUM_4: + log.Fatal(tag, $"Set MimimumSize test"); mainWin.SetMimimumSize(new Size2D(100, 100)); break; - case KEY_NUM_6: - if(manualRotation == false) + + case KEY_NUM_5: + log.Fatal(tag, $"manual rotation test"); + if (manualRotation == false) { manualRotation = true; + tm = new Timer(100); + tm.Tick += Tm_Tick; + tm.Start(); log.Fatal(tag, $"Enable manual rotation"); } else @@ -176,11 +445,10 @@ public void OnKeyEvent(object sender, Window.KeyEventArgs e) } mainWin.SetNeedsRotationCompletedAcknowledgement(manualRotation); break; - case KEY_NUM_7: - mainWin.SetMimimumSize(new Size2D(100, 100)); - break; - case KEY_NUM_8: - if(mainWin.GetFullScreen() == false) + + case KEY_NUM_6: + log.Fatal(tag, $"Fullscreen Test"); + if (mainWin.GetFullScreen() == false) { mainWin.SetFullScreen(true); } @@ -190,6 +458,21 @@ public void OnKeyEvent(object sender, Window.KeyEventArgs e) } break; + case KEY_NUM_7: + log.Fatal(tag, $"Raise Test"); + mainWin.Raise(); + break; + + case KEY_NUM_8: + log.Fatal(tag, $"Lower Test"); + mainWin.Lower(); + break; + + case KEY_NUM_9: + log.Fatal(tag, $"Activate Test"); + mainWin.Activate(); + break; + default: log.Fatal(tag, $"no test!"); break; @@ -197,7 +480,214 @@ public void OnKeyEvent(object sender, Window.KeyEventArgs e) } } - public void Activate() { Initialize(); } - public void Deactivate() { } + void CreateSubWindow() + { + if (subWindow == null) + { + CustomBorder customBorder = new CustomBorder(); + subWindow = new Window("subwin", customBorder, new Rectangle(60, 20, 800, 800), false); + subWindow.InterceptTouchEvent += (s, e) => + { + Tizen.Log.Error("NUI", $"subWindow.InterceptTouchEvent\n"); + if (e.Touch.GetState(0) == PointStateType.Down) + { + customBorder.OverlayBorderShow(); + } + return false; + }; + + var root = new View() + { + Layout = new LinearLayout() + { + HorizontalAlignment = HorizontalAlignment.Center, + }, + WidthResizePolicy = ResizePolicyType.FillToParent, + HeightResizePolicy = ResizePolicyType.FillToParent, + BackgroundColor = Color.Brown, + }; + + var image = new ImageView() + { + Size = new Size(300, 300), + ResourceUrl = ImagePath + "gallery-large-5.jpg", + CornerRadius = new Vector4(0.03f, 0.03f, 0, 0), + CornerRadiusPolicy = VisualTransformPolicyType.Relative, + }; + root.Add(image); + subWindow.GetDefaultLayer().Add(root); + + List list = new List(); + + list.Add(Window.WindowOrientation.Landscape); + list.Add(Window.WindowOrientation.LandscapeInverse); + list.Add(Window.WindowOrientation.NoOrientationPreference); + list.Add(Window.WindowOrientation.Portrait); + list.Add(Window.WindowOrientation.PortraitInverse); + + subWindow.SetAvailableOrientations(list); + + subWindow.Moved += OnSubWindowMoved; + subWindow.KeyEvent += OnSubWindowKeyEvent; + subWindow.MoveCompleted += OnSubWindowMoveCompleted; + subWindow.ResizeCompleted += OnSubWindowResizeCompleted; + } + else + { + subWindow.Minimize(false); + } + } + + private void OnSubWindowMoved(object sender, WindowMovedEventArgs e) + { + Position2D position = e.WindowPosition; + log.Fatal(tag, $"OnSubWindowMoved() called!, x:{position.X}, y:{position.Y}"); + } + + private void OnSubWindowMoveCompleted(object sender, WindowMoveCompletedEventArgs e) + { + Position2D position = e.WindowCompletedPosition; + log.Fatal(tag, $"OnSubWindowMoveCompleted() called!, x:{position.X}, y:{position.Y}"); + } + + private void OnSubWindowResizeCompleted(object sender, WindowResizeCompletedEventArgs e) + { + Size2D size = e.WindowCompletedSize; + log.Fatal(tag, $"OnSubWindowResizeCompleted() called!, width:{size.Width}, height:{size.Height}"); + } + + + public void OnSubWindowKeyEvent(object sender, Window.KeyEventArgs e) + { + if (e.Key.State == Key.StateType.Down) + { + log.Fatal(tag, $"key down! key={e.Key.KeyPressedName}"); + + switch (e.Key.KeyPressedName) + { + case "XF86Back": + case "Escape": + log.Fatal(tag, $"sub window dispose test!!!"); + subWindow.Dispose(); + break; + + case KEY_NUM_0: + log.Fatal(tag, $"Remove Available Orientation test"); + subWindow.RemoveAvailableOrientation(Window.WindowOrientation.Portrait); + break; + + case KEY_NUM_1: + log.Fatal(tag, $"Set/Get Orientation test"); + subWindow.SetPreferredOrientation(Window.WindowOrientation.Portrait); + Window.WindowOrientation currentPreferredOrientation = subWindow.GetPreferredOrientation(); + log.Fatal(tag, $"current Preferred Orientation: {currentPreferredOrientation}"); + Window.WindowOrientation currentOrientation = subWindow.GetCurrentOrientation(); + log.Fatal(tag, $"current Orientation: {currentOrientation}"); + break; + + case KEY_NUM_2: + log.Fatal(tag, $"Set Accept Focus test"); + subWindow.SetAcceptFocus(true); + if (subWindow.IsFocusAcceptable()) + { + log.Fatal(tag, $"focus is acceptable"); + } + else + { + log.Fatal(tag, $"focus is not acceptable"); + } + break; + + case KEY_NUM_3: + log.Fatal(tag, $"visible/show/hide test"); + if (subWindow.IsVisible()) + { + log.Fatal(tag, $"subwindow is hideing"); + subWindow.Hide(); + } + else + { + log.Fatal(tag, $"subwindow is showing"); + subWindow.Show(); + } + break; + + case KEY_NUM_4: + log.Fatal(tag, $"Get/Set, Notification Level test"); + if (subWindow.Type != WindowType.Notification) + { + log.Fatal(tag, $"Set notification window type"); + subWindow.Type = WindowType.Notification; + log.Fatal(tag, $"Set notification level with high"); + subWindow.SetNotificationLevel(NotificationLevel.High); + if (subWindow.GetNotificationLevel() == NotificationLevel.High) + { + log.Fatal(tag, $"Current notificaiton level is high"); + } + else + { + log.Fatal(tag, $"Current notificaiton level is not high"); + } + } + break; + + case KEY_NUM_5: + log.Fatal(tag, $"opaque test"); + if (subWindow.IsOpaqueState()) + { + log.Fatal(tag, $"Set opaque state with false"); + subWindow.SetOpaqueState(false); + } + else + { + log.Fatal(tag, $"Set opaque state with true"); + subWindow.SetOpaqueState(true); + } + break; + + case KEY_NUM_6: + log.Fatal(tag, $"Set/Get ScreenOffMode test"); + if (subWindow.GetScreenOffMode() == ScreenOffMode.Timout) + { + log.Fatal(tag, $"SetScreenOffMode with ScreenOffMode.Never"); + subWindow.SetScreenOffMode(ScreenOffMode.Never); + } + else + { + log.Fatal(tag, $"SetScreenOffMode with ScreenOffMode.Timout"); + subWindow.SetScreenOffMode(ScreenOffMode.Timout); + } + + break; + + case KEY_NUM_7: + log.Fatal(tag, $"Set/Get Brightness test"); + subWindow.SetBrightness(95); + int currentBrightness = subWindow.GetBrightness(); + log.Fatal(tag, $"Current Brightness: {currentBrightness}"); + break; + + case KEY_NUM_8: + log.Fatal(tag, $"Get/Set WindowPosition Test"); + subWindow.WindowPosition = new Position2D(10, 10); + log.Fatal(tag, $"subWindow x: {subWindow.WindowPosition.X}, y: {subWindow.WindowPosition.Y}"); + //log.Fatal(tag, $"WindowPosition : " + subWindow.WindowPosition); + break; + + case KEY_NUM_9: + log.Fatal(tag, $"Get/Set WindowPositionSize Test"); + Rectangle rec = new Rectangle(20, 10, 100, 200); + subWindow.WindowPositionSize = rec; + log.Fatal(tag, $"WindowPositionSize : " + subWindow.WindowPositionSize); + break; + + default: + log.Fatal(tag, $"no test!"); + break; + } + } + } + public void Activate() { Initialize(); } + public void Deactivate() { } } } diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest1.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest1.cs new file mode 100644 index 00000000000..6325880f4e4 --- /dev/null +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/WindowTest1.cs @@ -0,0 +1,562 @@ + +using global::System; +using Tizen.NUI; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; +using Tizen.System; +using System.Collections.Generic; +using NUnit.Framework; + +namespace Tizen.NUI.Samples +{ + using log = Tizen.Log; + public class WindowTest1 : IExample + { + string tag = "NUITEST"; + Window mainWin; + int screenWidth; + int screenHeight; + + int addingInput; + private Window subWindow = null; + + private const string KEY_NUM_1 = "1"; + private const string KEY_NUM_2 = "2"; + private const string KEY_NUM_3 = "3"; + private const string KEY_NUM_4 = "4"; + private const string KEY_NUM_5 = "5"; + private const string KEY_NUM_6 = "6"; + private const string KEY_NUM_7 = "7"; + private const string KEY_NUM_8 = "8"; + private const string KEY_NUM_9 = "9"; + private const string KEY_NUM_0 = "0"; + + private static readonly string ImagePath = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "/images/Dali/CubeTransitionEffect/"; + + class CustomBorder : DefaultBorder + { + private static readonly string ResourcePath = Tizen.Applications.Application.Current.DirectoryInfo.Resource; + private static readonly string MinimalizeIcon = ResourcePath + "/images/minimalize.png"; + private static readonly string MaximalizeIcon = ResourcePath + "/images/maximalize.png"; + private static readonly string RestoreIcon = ResourcePath + "/images/smallwindow.png"; + private static readonly string CloseIcon = ResourcePath + "/images/close.png"; + private static readonly string LeftCornerIcon = ResourcePath + "/images/leftCorner.png"; + private static readonly string RightCornerIcon = ResourcePath + "/images/rightCorner.png"; + + private int width = 500; + private bool hide = false; + private View borderView; + private TextLabel title; + + private ImageView minimalizeIcon; + private ImageView maximalizeIcon; + private ImageView closeIcon; + private ImageView leftCornerIcon; + private ImageView rightCornerIcon; + + private Rectangle preWinPositonSize; + + public CustomBorder() : base() + { + BorderHeight = 50; + OverlayMode = true; + BorderLineThickness = 0; + } + + public override bool CreateTopBorderView(View topView) + { + if (topView == null) + { + return false; + } + topView.Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + VerticalAlignment = VerticalAlignment.Center, + CellPadding = new Size2D(20, 20), + }; + title = new TextLabel() + { + Text = "CustomBorder", + }; + + var button = new Button() + { + Text = "AlwaysOnTop", + }; + button.Clicked += (s, e) => + { + BorderWindow.EnableFloatingMode(true); + }; + topView.Add(title); + topView.Add(button); + return true; + } + + public override bool CreateBottomBorderView(View bottomView) + { + if (bottomView == null) + { + return false; + } + bottomView.Layout = new RelativeLayout(); + + minimalizeIcon = new ImageView() + { + ResourceUrl = MinimalizeIcon, + AccessibilityHighlightable = true, + }; + + maximalizeIcon = new ImageView() + { + ResourceUrl = MaximalizeIcon, + AccessibilityHighlightable = true, + }; + + closeIcon = new ImageView() + { + ResourceUrl = CloseIcon, + AccessibilityHighlightable = true, + }; + + leftCornerIcon = new ImageView() + { + ResourceUrl = LeftCornerIcon, + AccessibilityHighlightable = true, + }; + + rightCornerIcon = new ImageView() + { + ResourceUrl = RightCornerIcon, + AccessibilityHighlightable = true, + }; + + RelativeLayout.SetRightTarget(minimalizeIcon, maximalizeIcon); + RelativeLayout.SetRightRelativeOffset(minimalizeIcon, 0.0f); + RelativeLayout.SetHorizontalAlignment(minimalizeIcon, RelativeLayout.Alignment.End); + RelativeLayout.SetRightTarget(maximalizeIcon, closeIcon); + RelativeLayout.SetRightRelativeOffset(maximalizeIcon, 0.0f); + RelativeLayout.SetHorizontalAlignment(maximalizeIcon, RelativeLayout.Alignment.End); + RelativeLayout.SetRightTarget(closeIcon, rightCornerIcon); + RelativeLayout.SetRightRelativeOffset(closeIcon, 0.0f); + RelativeLayout.SetHorizontalAlignment(closeIcon, RelativeLayout.Alignment.End); + RelativeLayout.SetRightRelativeOffset(rightCornerIcon, 1.0f); + RelativeLayout.SetHorizontalAlignment(rightCornerIcon, RelativeLayout.Alignment.End); + bottomView.Add(leftCornerIcon); + bottomView.Add(minimalizeIcon); + bottomView.Add(maximalizeIcon); + bottomView.Add(closeIcon); + bottomView.Add(rightCornerIcon); + + + minimalizeIcon.TouchEvent += OnMinimizeIconTouched; + maximalizeIcon.TouchEvent += OnMaximizeIconTouched; + closeIcon.TouchEvent += OnCloseIconTouched; + leftCornerIcon.TouchEvent += OnLeftBottomCornerIconTouched; + rightCornerIcon.TouchEvent += OnRightBottomCornerIconTouched; + + minimalizeIcon.AccessibilityActivated += (s, e) => + { + MinimizeBorderWindow(); + }; + maximalizeIcon.AccessibilityActivated += (s, e) => + { + MaximizeBorderWindow(); + }; + closeIcon.AccessibilityActivated += (s, e) => + { + CloseBorderWindow(); + }; + + minimalizeIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Minimize"; + }; + maximalizeIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Maximize"; + }; + closeIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Close"; + }; + leftCornerIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Resize"; + }; + rightCornerIcon.AccessibilityNameRequested += (s, e) => + { + e.Name = "Resize"; + }; + + minimalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + maximalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + closeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + leftCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + rightCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name); + + return true; + } + + public override void CreateBorderView(View borderView) + { + this.borderView = borderView; + borderView.CornerRadius = new Vector4(0.03f, 0.03f, 0.03f, 0.03f); + borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative; + borderView.BackgroundColor = new Color(1, 1, 1, 0.3f); + } + + public override void OnCreated(View borderView) + { + base.OnCreated(borderView); + UpdateIcons(); + } + + public override bool OnCloseIconTouched(object sender, View.TouchEventArgs e) + { + base.OnCloseIconTouched(sender, e); + return true; + } + + public override bool OnMinimizeIconTouched(object sender, View.TouchEventArgs e) + { + if (e.Touch.GetState(0) == PointStateType.Up) + { + if (BorderWindow.IsMaximized() == true) + { + BorderWindow.Maximize(false); + } + preWinPositonSize = BorderWindow.WindowPositionSize; + BorderWindow.WindowPositionSize = new Rectangle(preWinPositonSize.X, preWinPositonSize.Y, 500, 0); + } + return true; + } + + public override void OnRequestResize() + { + if (borderView != null) + { + borderView.BackgroundColor = new Color(0, 1, 0, 0.3f); // 보더의 배경을 변경할 수 있습니다. + } + } + + public override void OnResized(int width, int height) + { + if (borderView != null) + { + if (this.width > width && hide == false) + { + title.Hide(); + hide = true; + } + else if (this.width < width && hide == true) + { + title.Show(); + hide = false; + } + borderView.BackgroundColor = new Color(1, 1, 1, 0.3f); // 리사이즈가 끝나면 보더의 색깔은 원래대로 돌려놓습니다. + base.OnResized(width, height); + UpdateIcons(); + } + } + + private void UpdateIcons() + { + if (BorderWindow != null && borderView != null) + { + if (BorderWindow.IsMaximized() == true) + { + if (maximalizeIcon != null) + { + maximalizeIcon.ResourceUrl = RestoreIcon; + } + } + else + { + if (maximalizeIcon != null) + { + maximalizeIcon.ResourceUrl = MaximalizeIcon; + } + } + } + } + + } + + + void Initialize() + { + mainWin = NUIApplication.GetDefaultWindow(); + mainWin.KeyEvent += OnKeyEvent; + mainWin.TouchEvent += WinTouchEvent; + mainWin.BackgroundColor = Color.Cyan; + + Information.TryGetValue("http://tizen.org/feature/screen.width", out screenWidth); + Information.TryGetValue("http://tizen.org/feature/screen.height", out screenHeight); + log.Fatal(tag, $"Initialize= screenWidth {screenWidth}, screenHeight {screenHeight} "); + + addingInput = 0; + + TextLabel text = new TextLabel("NUI Window Test1"); + text.HorizontalAlignment = HorizontalAlignment.Center; + text.VerticalAlignment = VerticalAlignment.Center; + text.TextColor = Color.Blue; + text.PointSize = 12.0f; + text.HeightResizePolicy = ResizePolicyType.FillToParent; + text.WidthResizePolicy = ResizePolicyType.FillToParent; + mainWin.Add(text); + + List list = new List(); + + list.Add(Window.WindowOrientation.Landscape); + list.Add(Window.WindowOrientation.LandscapeInverse); + list.Add(Window.WindowOrientation.NoOrientationPreference); + list.Add(Window.WindowOrientation.Portrait); + list.Add(Window.WindowOrientation.PortraitInverse); + + mainWin.SetAvailableOrientations(list); + + Animation animation = new Animation(2000); + animation.AnimateTo(text, "Orientation", new Rotation(new Radian(new Degree(180.0f)), PositionAxis.X), 0, 500); + animation.AnimateTo(text, "Orientation", new Rotation(new Radian(new Degree(0.0f)), PositionAxis.X), 500, 1000); + animation.Looping = true; + animation.Play(); + } + + private void WinTouchEvent(object sender, Window.TouchEventArgs e) + { + if (e.Touch.GetState(0) == PointStateType.Down) + { + } + } + + public void OnKeyEvent(object sender, Window.KeyEventArgs e) + { + if (e.Key.State == Key.StateType.Down) + { + log.Fatal(tag, $"key down! key={e.Key.KeyPressedName}"); + + switch (e.Key.KeyPressedName) + { + case "XF86Back": + case "Escape": + //Exit(); + break; + + case KEY_NUM_0: + CreateSubWindow(); + break; + + case KEY_NUM_1: + log.Fatal(tag, $"GetOverlayLayer test"); + Layer layer = mainWin.GetOverlayLayer(); + break; + + case KEY_NUM_2: + log.Fatal(tag, $"Get Native ID test"); + int nativeID = mainWin.GetNativeId(); + log.Fatal(tag, $"Get Native ID {nativeID}"); + break; + + case KEY_NUM_3: + log.Fatal(tag, $"Partial update test"); + if (mainWin.PartialUpdate) + { + log.Fatal(tag, $"upset partial update"); + mainWin.PartialUpdate = false; + } + else + { + log.Fatal(tag, $"set partial update"); + mainWin.PartialUpdate = true; + } + break; + + case KEY_NUM_4: + log.Fatal(tag, $"Keep Rendering test"); + mainWin.KeepRendering(3000); + break; + + case KEY_NUM_5: + break; + + case KEY_NUM_6: + break; + + case KEY_NUM_7: + break; + + case KEY_NUM_8: + break; + + case KEY_NUM_9: + + break; + + default: + log.Fatal(tag, $"no test!"); + break; + } + } + } + + void CreateSubWindow() + { + if (subWindow == null) + { + CustomBorder customBorder = new CustomBorder(); + subWindow = new Window("subwin", customBorder, new Rectangle(60, 20, 800, 800), false); + subWindow.InterceptTouchEvent += (s, e) => + { + Tizen.Log.Error("NUI", $"subWindow.InterceptTouchEvent\n"); + if (e.Touch.GetState(0) == PointStateType.Down) + { + customBorder.OverlayBorderShow(); + } + return false; + }; + + var root = new View() + { + Layout = new LinearLayout() + { + HorizontalAlignment = HorizontalAlignment.Center, + }, + WidthResizePolicy = ResizePolicyType.FillToParent, + HeightResizePolicy = ResizePolicyType.FillToParent, + BackgroundColor = Color.Brown, + }; + + var image = new ImageView() + { + Size = new Size(300, 300), + ResourceUrl = ImagePath + "gallery-large-5.jpg", + CornerRadius = new Vector4(0.03f, 0.03f, 0, 0), + CornerRadiusPolicy = VisualTransformPolicyType.Relative, + }; + root.Add(image); + subWindow.GetDefaultLayer().Add(root); + + List list = new List(); + + list.Add(Window.WindowOrientation.Landscape); + list.Add(Window.WindowOrientation.LandscapeInverse); + list.Add(Window.WindowOrientation.NoOrientationPreference); + list.Add(Window.WindowOrientation.Portrait); + list.Add(Window.WindowOrientation.PortraitInverse); + + subWindow.SetAvailableOrientations(list); + + subWindow.Moved += OnSubWindowMoved; + subWindow.KeyEvent += OnSubWindowKeyEvent; + subWindow.MoveCompleted += OnSubWindowMoveCompleted; + subWindow.ResizeCompleted += OnSubWindowResizeCompleted; + } + else + { + subWindow.Minimize(false); + } + } + + private void OnSubWindowMoved(object sender, WindowMovedEventArgs e) + { + Position2D position = e.WindowPosition; + log.Fatal(tag, $"OnSubWindowMoved() called!, x:{position.X}, y:{position.Y}"); + } + + private void OnSubWindowMoveCompleted(object sender, WindowMoveCompletedEventArgs e) + { + Position2D position = e.WindowCompletedPosition; + log.Fatal(tag, $"OnSubWindowMoveCompleted() called!, x:{position.X}, y:{position.Y}"); + } + + private void OnSubWindowResizeCompleted(object sender, WindowResizeCompletedEventArgs e) + { + Size2D size = e.WindowCompletedSize; + log.Fatal(tag, $"OnSubWindowResizeCompleted() called!, width:{size.Width}, height:{size.Height}"); + } + + + public void OnSubWindowKeyEvent(object sender, Window.KeyEventArgs e) + { + if (e.Key.State == Key.StateType.Down) + { + log.Fatal(tag, $"key down! key={e.Key.KeyPressedName}"); + + switch (e.Key.KeyPressedName) + { + case "XF86Back": + case "Escape": + log.Fatal(tag, $"sub window dispose test!!!"); + subWindow.Dispose(); + break; + + case KEY_NUM_0: + log.Fatal(tag, $"Get/Set Size Test"); + subWindow.WindowSize = new Size2D(200, 500); + log.Fatal(tag, $"WindowSize : " + subWindow.WindowSize); + break; + + case KEY_NUM_1: + log.Fatal(tag, $"set Transparancy"); + subWindow.SetTransparency(true); + break; + + case KEY_NUM_2: + log.Fatal(tag, $"Get/Set BackgroundColor test"); + subWindow.BackgroundColor = Color.Black; + if (subWindow.BackgroundColor == Color.Black) + { + subWindow.BackgroundColor = Color.White; + } + break; + + case KEY_NUM_3: + log.Fatal(tag, $"Get/Set Parent test"); + subWindow.SetParent(mainWin); + if (subWindow.GetParent() == mainWin) + { + subWindow.Unparent(); + subWindow.SetParent(mainWin, true); + if (subWindow.GetParent() == mainWin) + { + log.Fatal(tag, $"success to test Set Parent"); + subWindow.Unparent(); + } + } + break; + + case KEY_NUM_4: + log.Fatal(tag, $"inputRegion test"); + Rectangle inputRegion = new Rectangle(0, 0, 200, 500); + subWindow.IncludeInputRegion(inputRegion); + break; + + case KEY_NUM_5: + log.Fatal(tag, $"excludeInputRegion test"); + Rectangle excludeInputRegion = new Rectangle(10, 10, 100, 200); + subWindow.ExcludeInputRegion(excludeInputRegion); + break; + + case KEY_NUM_6: + break; + + case KEY_NUM_7: + break; + + case KEY_NUM_8: + break; + + case KEY_NUM_9: + break; + + default: + log.Fatal(tag, $"no test!"); + break; + } + } + } + public void Activate() { Initialize(); } + public void Deactivate() { } + } +}