Store weak reference of C# object in the view registry to make the object garbage...
[platform/core/uifw/dali-toolkit.git] / plugins / dali-swig / manual / csharp / ViewRegistry.cs
index c2be678..b055a7d 100644 (file)
@@ -51,14 +51,14 @@ namespace Dali
   ///  in MyControl.h
   ///  class MyControl : public Control
   ///  {
-  ///      struct Property
+  ///    struct Property
+  ///    {
+  ///      enum
   ///      {
-  ///         enum
-  ///        {
-  ///              HOURS =  Control::CONTROL_PROPERTY_END_INDEX + 1
-  ///        }
-  ///     }
-  ///
+  ///        HOURS =  Control::CONTROL_PROPERTY_END_INDEX + 1
+  ///      }
+  ///    }
+  ///  }
   ///
   /// in MyControl-impl.cpp
   ///
@@ -139,9 +139,10 @@ namespace Dali
     private PropertyRangeManager _propertyRangeManager;
 
     /// <summary>
-    /// Given a C++ custom control the dictionary allows us to find what CustomView it belongs to
+    /// Given a C++ control the dictionary allows us to find which C# control (View) it belongs to.
+    /// By keeping the weak reference only, it will allow the object to be garbage collected.
     /// </summary>
-    private Dictionary<IntPtr, Dali.CustomView> _controlMap;
+    private Dictionary<IntPtr, WeakReference> _controlMap;
 
     ///<summary>
     // Maps the name of a custom view to a create instance function
@@ -177,7 +178,7 @@ namespace Dali
       _getPropertyCallback = new GetPropertyDelegate (GetProperty);
       _setPropertyCallback  = new SetPropertyDelegate (SetProperty);
 
-      _controlMap = new Dictionary<IntPtr, CustomView>();
+      _controlMap = new Dictionary<IntPtr, WeakReference>();
       _constructorMap = new Dictionary<string, Func<CustomView>>();
       _propertyRangeManager = new PropertyRangeManager();
 
@@ -199,7 +200,7 @@ namespace Dali
     }
 
     /// <summary>
-    /// Called directly from DALi C++ type registry to create a control (View)  uses no marshalling.
+    /// Called directly from DALi C++ type registry to create a control (View) using no marshalling.
     /// </summary>
     /// <returns>Pointer to the Control (Views) handle </returns>
     /// <param name="cPtrControlName"> C pointer to the Control (View) name</param>
@@ -215,17 +216,7 @@ namespace Dali
       {
         // Create the control
         CustomView newControl = controlConstructor ();
-
-        // Store the mapping between this instance of the custom control and native part
-        // We store a pointer to the RefObject for the control
-        IntPtr cPtr = newControl.GetPtrfromActor();
-        RefObject refObj = newControl.GetObjectPtr ();
-        IntPtr refCptr = (IntPtr) RefObject.getCPtr(refObj);
-
-        //Console.WriteLine ("________Storing ref object cptr in control map Hex: {0:X}", refCptr);
-        Instance._controlMap.Add (refCptr , newControl );
-
-        return cPtr;  // return pointer to handle
+        return newControl.GetPtrfromActor();  // return pointer to handle
       }
       else
       {
@@ -234,6 +225,42 @@ namespace Dali
       }
     }
 
+    /// <summary>
+    /// Store the mapping between this instance of control (View) and native part.
+    /// </summary>
+    /// <param name="view"> The instance of control (View)</param>
+    public static void RegisterView( View view )
+    {
+      // We store a pointer to the RefObject for the control
+      RefObject refObj = view.GetObjectPtr();
+      IntPtr refCptr = (IntPtr) RefObject.getCPtr(refObj);
+
+      //Console.WriteLine ("________Storing ref object cptr in control map Hex: {0:X}", refCptr);
+      if ( !Instance._controlMap.ContainsKey(refCptr) )
+      {
+        Instance._controlMap.Add(refCptr, new WeakReference(view, false));
+      }
+
+      return;
+    }
+
+    /// <summary>
+    /// Remove the this instance of control (View) and native part from the mapping table.
+    /// </summary>
+    /// <param name="view"> The instance of control (View)</param>
+    public static void UnregisterView( View view )
+    {
+      RefObject refObj = view.GetObjectPtr();
+      IntPtr refCptr = (IntPtr) RefObject.getCPtr(refObj);
+
+      if ( Instance._controlMap.ContainsKey(refCptr) )
+      {
+        Instance._controlMap.Remove(refCptr);
+      }
+
+      return;
+    }
+
     private static IntPtr GetProperty( IntPtr controlPtr, IntPtr propertyName )
     {
       string name = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (propertyName);
@@ -260,19 +287,17 @@ namespace Dali
       }
     }
 
-    public static CustomView GetCustomViewFromActor( Actor actor )
+    public static View GetViewFromActor( Actor actor )
     {
       // we store a dictionary of ref-obects (C++ land) to custom views (C# land)
-      Dali.CustomView view;
 
       RefObject refObj = actor.GetObjectPtr ();
       IntPtr refObjectPtr = (IntPtr) RefObject.getCPtr(refObj);
 
-      if ( Instance._controlMap.TryGetValue ( refObjectPtr, out view) )
+      WeakReference viewReference;
+      if ( Instance._controlMap.TryGetValue ( refObjectPtr, out viewReference) )
       {
-
-        // call the get property function
-
+        View view = viewReference.Target as View;
         return view;
       }
       else
@@ -346,16 +371,16 @@ namespace Dali
     private IntPtr GetPropertyValue ( IntPtr controlPtr, string propertyName)
     {
       // Get the C# control that maps to the C++ control
-      Dali.CustomView view;
-
       BaseHandle baseHandle = new BaseHandle (controlPtr, false);
 
       RefObject refObj = baseHandle.GetObjectPtr ();
 
       IntPtr refObjectPtr = (IntPtr) RefObject.getCPtr(refObj);
 
-      if ( _controlMap.TryGetValue ( refObjectPtr, out view) )
+      WeakReference viewReference;
+      if ( _controlMap.TryGetValue ( refObjectPtr, out viewReference) )
       {
+        View view = viewReference.Target as View;
 
         // call the get property function
         System.Object val = view.GetType ().GetProperty (propertyName).GetAccessors () [0].Invoke (view, null);
@@ -377,15 +402,15 @@ namespace Dali
     private void SetPropertyValue ( IntPtr controlPtr, string propertyName, IntPtr propertyValuePtr)
     {
       // Get the C# control that maps to the C++ control
-      Dali.CustomView view;
 
       //Console.WriteLine ("SetPropertyValue   refObjectPtr = {0:X}", controlPtr);
 
       Property.Value propValue = new Property.Value (propertyValuePtr, false);
 
-      if ( _controlMap.TryGetValue ( controlPtr, out view) )
+      WeakReference viewReference;
+      if ( _controlMap.TryGetValue ( controlPtr, out viewReference) )
       {
-
+        View view = viewReference.Target as View;
         System.Reflection.PropertyInfo propertyInfo = view.GetType().GetProperty(propertyName);
 
         // We know the property name, we know it's type, we just need to convert from a DALi property value to native C# type