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 29ece3a..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
   ///
@@ -98,7 +98,7 @@ namespace Dali
   ///
   ///  static Spin()
   ///  {
-  ///     ViewRegistry.Instance.RegisterControl("Spin", CreateInstance, typeof(Spin) );
+  ///     ViewRegistry.Instance.Register(CreateInstance, typeof(Spin) );
   ///  }
   ///
   ///  The control should also provide a CreateInstance function, which gets passed to the ViewRegistry
@@ -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
@@ -293,17 +318,17 @@ namespace Dali
     /// {
     ///   ViewRegistry registers control type with DALi type registery
     ///   also uses introspection to find any properties that need to be registered with type registry
-    ///   ViewRegistry.Instance.Register("Spin", CreateInstance, typeof(Spin) );
+    ///   ViewRegistry.Instance.Register(CreateInstance, typeof(Spin) );
     /// }
     ///
     /// </summary>
-    public void Register(string viewName, Func< CustomView > createFunction, System.Type viewType )
+    public void Register(Func< CustomView > createFunction, System.Type viewType )
     {
       // add the mapping between the view name and it's create function
-      _constructorMap.Add (viewName, createFunction);
+      _constructorMap.Add (viewType.Name, createFunction);
 
       // Call into DALi C++ to register the control with the type registry
-      TypeRegistration.RegisterControl( viewName, _createCallback );
+      TypeRegistration.RegisterControl( viewType.Name, _createCallback );
 
       // Cycle through each property in the class
       foreach (System.Reflection.PropertyInfo propertyInfo in viewType.GetProperties())
@@ -324,14 +349,14 @@ namespace Dali
               ScriptableProperty scriptableProp = attr as ScriptableProperty;
 
               // we get the start property index, based on the type and it's heirachy, e.g. DateView (70,000)-> Spin (60,000) -> View (50,000)
-              int propertyIndex =  _propertyRangeManager.GetPropertyIndex( viewName, viewType, scriptableProp.type );
+              int propertyIndex =  _propertyRangeManager.GetPropertyIndex( viewType.Name, viewType, scriptableProp.type );
 
               // get the enum for the property type... E.g. registering a string property returns Dali.PropertyType.String
               Dali.Property.Type propertyType = GetDaliPropertyType( propertyInfo.PropertyType.Name );
 
               // Example   RegisterProperty("spin","maxValue", 50001, FLOAT, set, get );
               // Native call to register the property
-              TypeRegistration.RegisterProperty (viewName, propertyInfo.Name , propertyIndex, propertyType, _setPropertyCallback, _getPropertyCallback);
+              TypeRegistration.RegisterProperty (viewType.Name, propertyInfo.Name , propertyIndex, propertyType, _setPropertyCallback, _getPropertyCallback);
             }
           }
           // Console.WriteLine ("property name = " + propertyInfo.Name);
@@ -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