2 * Copyright(c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Collections.Generic;
20 using System.Threading;
25 /// This is used to store a mapping between C++ base handle objects and it's C# instances.
28 internal sealed class Registry
30 private static readonly Registry registry = new Registry();
33 /// static initialization singleton
35 internal static Registry Instance
37 get { return registry; }
41 /// Given a C++ object, the dictionary allows us to find which C# object it belongs to.
42 /// By keeping the weak reference only, it will allow the object to be garbage collected.
44 private Dictionary<IntPtr, WeakReference> _controlMap;
48 _controlMap = new Dictionary<IntPtr, WeakReference>();
53 /// Stores the mapping between this instance of BaseHandle (C# base class) and native part.
55 /// <param name="baseHandle">The instance of BaseHandle (C# base class).</param>
56 internal static void Register(BaseHandle baseHandle)
58 if(savedApplicationThread?.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)
60 throw new global::System.ApplicationException("NUI object is attempt to be created in another thread. It should be created in main thread only!");
63 // We store a pointer to the RefObject for the control
64 RefObject refObj = baseHandle.GetObjectPtr();
65 IntPtr refCptr = (IntPtr)RefObject.getCPtr(refObj);
67 //NUILog.Debug("Storing ref object cptr in control map Hex: {0:X}" + refCptr);
69 if (!Instance._controlMap.ContainsKey(refCptr))
71 Instance._controlMap.Add(refCptr, new WeakReference(baseHandle, false));
78 /// Removes this instance of BaseHandle (C# base class) and native part from the mapping table.
80 /// <param name="baseHandle"> The instance of BaseHandle (C# base class)</param>
81 internal static void Unregister(BaseHandle baseHandle)
83 RefObject refObj = baseHandle.GetObjectPtr();
84 IntPtr refCptr = (IntPtr)RefObject.getCPtr(refObj);
86 if (Instance._controlMap.ContainsKey(refCptr))
88 Instance._controlMap.Remove(refCptr);
94 internal static BaseHandle GetManagedBaseHandleFromNativePtr(BaseHandle baseHandle)
96 RefObject refObj = baseHandle.GetObjectPtr();
97 IntPtr refObjectPtr = (IntPtr)RefObject.getCPtr(refObj);
99 // we store a dictionary of ref-obects (C++ land) to managed obects (C# land)
100 return GetManagedBaseHandleFromRefObject(refObjectPtr);
103 internal static BaseHandle GetManagedBaseHandleFromNativePtr(IntPtr cPtr)
105 IntPtr refObjectPtr = NDalicPINVOKE.GetRefObjectPtr(cPtr);
107 // we store a dictionary of ref-obects (C++ land) to managed obects (C# land)
108 return GetManagedBaseHandleFromRefObject(refObjectPtr);
111 internal static BaseHandle GetManagedBaseHandleFromRefObject(IntPtr refObjectPtr)
113 // we store a dictionary of ref-obects (C++ land) to managed obects (C# land)
114 WeakReference weakReference;
116 if (Instance._controlMap.TryGetValue(refObjectPtr, out weakReference))
118 if(weakReference == null) { throw new System.InvalidOperationException("Error! NUI Registry weakReference should not be NULL!"); }
119 BaseHandle ret = weakReference.Target as BaseHandle;
128 private static Thread savedApplicationThread;
129 internal Thread SavedApplicationThread
133 return savedApplicationThread;
137 savedApplicationThread = value;