use modern construct 'nullptr' instead of 'NULL' or '0'
[platform/core/uifw/dali-core.git] / dali / internal / event / common / property-notification-impl.cpp
index 49f6b7b..15515b0 100644 (file)
@@ -1,18 +1,19 @@
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.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://floralicense.org/license/
-//
-// 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.
-//
+/*
+ * Copyright (c) 2018 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.
+ *
+ */
 
 // CLASS HEADER
 #include <dali/internal/event/common/property-notification-impl.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/radian.h>
+#include <dali/public-api/actors/actor.h>
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/internal/event/common/property-notification-manager.h>
-#include <dali/internal/event/common/proxy-object.h>
+#include <dali/internal/event/common/object-impl.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/update/manager/update-manager.h>
 #include <dali/internal/update/common/scene-graph-property-notification.h>
 #include <dali/internal/event/common/thread-local-storage.h>
 
-using namespace std;
-
 using Dali::Internal::SceneGraph::UpdateManager;
 
 namespace Dali
@@ -47,79 +47,78 @@ PropertyNotificationPtr PropertyNotification::New(Property& target,
 
   UpdateManager& updateManager = tls.GetUpdateManager();
 
-  PropertyNotificationManager& propertyNotificationManager = Stage::GetCurrent()->GetPropertyNotificationManager();
-
+  PropertyNotificationManager& propertyNotificationManager = tls.GetPropertyNotificationManager();
   PropertyNotificationPtr propertyNotification = new PropertyNotification(updateManager,
                                                                           propertyNotificationManager,
                                                                           target,
                                                                           componentIndex,
                                                                           condition);
-
   return propertyNotification;
 }
 
-PropertyNotification::PropertyNotification(UpdateManager& updateManager,
-                                           PropertyNotificationManager& propertyNotificationManager,
-                                           Property& target,
-                                           int componentIndex,
-                                           const Dali::PropertyCondition& condition)
-: mUpdateManager(updateManager),
-  mPropertyNotification(NULL),
-  mPropertyNotificationManager(propertyNotificationManager),
-  mProxyPropertyIndex(target.propertyIndex),
-  mPropertyType(Property::NONE),
-  mComponentIndex(componentIndex),
-  mCondition(condition),
-  mNotifyMode(Dali::PropertyNotification::NotifyOnTrue),
-  mNotifyResult(false)
-{
-  // Set condition arguments (as simple vector of floats)
-  PropertyCondition::ArgumentContainer arguments = GetImplementation(condition).arguments;
-  PropertyCondition::ArgumentConstIter iter = arguments.begin();
-
-  while( iter != arguments.end() )
+PropertyNotification::PropertyNotification( UpdateManager& updateManager,
+                                            PropertyNotificationManager& propertyNotificationManager,
+                                            Property& target,
+                                            int componentIndex,
+                                            const Dali::PropertyCondition& condition )
+: mUpdateManager( updateManager ),
+  mPropertyNotification( nullptr ),
+  mPropertyNotificationManager( propertyNotificationManager ),
+  mObjectPropertyIndex( target.propertyIndex ),
+  mPropertyType( Property::NONE ),
+  mComponentIndex( componentIndex ),
+  mCondition( condition ),
+  mNotifyMode( Dali::PropertyNotification::NOTIFY_ON_TRUE ),
+  mNotifyResult( false ),
+  mCompare( false )
+{
+  const Internal::PropertyCondition& conditionImpl = GetImplementation( condition );
+
+  Dali::Vector<float>::SizeType count = conditionImpl.arguments.Count();
+  for( Dali::Vector<float>::SizeType index = 0; index < count; ++index )
   {
-    const Property::Value& value = *iter;
-    float floatValue;
-    value.Get(floatValue);
-
-    mRawConditionArgs.PushBack( floatValue );
-    ++iter;
+    mRawConditionArgs.PushBack( conditionImpl.arguments[ index ] );
   }
 
-  // Observe target proxy and create/destroy notification scene object accordingly.
-  mProxy = dynamic_cast<ProxyObject*>( &GetImplementation(target.object) );
-  mPropertyType = mProxy->GetPropertyType(mProxyPropertyIndex);
-
-  int internalComponentIndex = mProxy->GetPropertyComponentIndex(mProxyPropertyIndex);
-  if( internalComponentIndex != INVALID_PROPERTY_COMPONENT_INDEX )
+  // Observe target object and create/destroy notification scene object accordingly.
+  mObject = dynamic_cast<Object*>( &GetImplementation(target.object) );
+  if ( mObject )
   {
-    // override the one passed in
-    mComponentIndex = internalComponentIndex;
-  }
-  if(mComponentIndex != INVALID_PROPERTY_COMPONENT_INDEX)
-  {
-    Property::Type type = mProxy->GetPropertyType(mProxyPropertyIndex);
-    if( type == Property::VECTOR2
-        || type == Property::VECTOR3
-        || type == Property::VECTOR4 )
+    mPropertyType = mObject->GetPropertyType(mObjectPropertyIndex);
+
+    int internalComponentIndex = mObject->GetPropertyComponentIndex(mObjectPropertyIndex);
+    if( internalComponentIndex != Property::INVALID_COMPONENT_INDEX )
     {
-      mPropertyType = Property::FLOAT;
+      // override the one passed in
+      mComponentIndex = internalComponentIndex;
+    }
+    if(mComponentIndex != Property::INVALID_COMPONENT_INDEX)
+    {
+      Property::Type type = mObject->GetPropertyType(mObjectPropertyIndex);
+      if( type == Property::VECTOR2
+          || type == Property::VECTOR3
+          || type == Property::VECTOR4 )
+      {
+        mPropertyType = Property::FLOAT;
+      }
     }
-  }
 
-  // Check if target scene-object already present, and if so create our notification
-  // scene-object
-  if ( mProxy )
+  // In Size Property case, swapping components occurs sometimes.
+  // To cover swapping components, previous and current components should be compared.
+  if( mObjectPropertyIndex == Dali::Actor::Property::SIZE
+      && mObject->GetPropertyType(mObjectPropertyIndex) == Property::VECTOR3 )
   {
-    const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
-
-    if (object)
+    mCompare = true;
+    for( int i = 0; i < 3; ++i )
     {
-      CreateSceneObject();
+      mRawConditionArgs.PushBack( 0.0f );
     }
   }
 
+    // all objects always have scene object
+    CreateSceneObject();
+  }
+
   // Connect to the property notification manager
   mPropertyNotificationManager.PropertyNotificationCreated( *this );
 }
@@ -136,7 +135,7 @@ PropertyNotification::~PropertyNotification()
   }
 }
 
-Dali::PropertyNotifySignalV2& PropertyNotification::NotifySignal()
+Dali::PropertyNotifySignalType& PropertyNotification::NotifySignal()
 {
   return mNotifySignal;
 }
@@ -175,20 +174,23 @@ const Dali::PropertyCondition& PropertyNotification::GetCondition() const
 
 Dali::Handle PropertyNotification::GetTarget() const
 {
-  Dali::Handle handle(mProxy);
+  Dali::Handle handle(mObject);
 
   return handle;
 }
 
 Property::Index PropertyNotification::GetTargetProperty() const
 {
-  return mProxyPropertyIndex;
+  return mObjectPropertyIndex;
 }
 
 void PropertyNotification::SetNotifyMode( NotifyMode mode )
 {
   mNotifyMode = mode;
-  PropertyNotificationSetNotifyModeMessage( mUpdateManager, mPropertyNotification, mode );
+  if( mPropertyNotification )
+  {
+    PropertyNotificationSetNotifyModeMessage( mUpdateManager, mPropertyNotification, mode );
+  }
 }
 
 PropertyNotification::NotifyMode PropertyNotification::GetNotifyMode()
@@ -208,30 +210,30 @@ bool PropertyNotification::CompareSceneObject( const SceneGraph::PropertyNotific
 
 void PropertyNotification::CreateSceneObject()
 {
-  DALI_ASSERT_DEBUG( mPropertyNotification == NULL );
-
-  // Create a new PropertyNotification, temporarily owned
-  SceneGraph::PropertyNotification* propertyNotification = SceneGraph::PropertyNotification::New( *mProxy,
-                                                                                                  mProxyPropertyIndex,
-                                                                                                  mPropertyType,
-                                                                                                  mComponentIndex,
-                                                                                                  GetImplementation(mCondition).type,
-                                                                                                  mRawConditionArgs,
-                                                                                                  mNotifyMode );
-  // Keep a const pointer to the PropertyNotification.
-  mPropertyNotification = propertyNotification;
-
-  // Transfer scene object ownership to the update manager through a message
-  AddPropertyNotificationMessage( mUpdateManager, propertyNotification );
+  // this method can be called from constructor and on stage connection
+  if( !mPropertyNotification )
+  {
+    // Create a new PropertyNotification, keep a const pointer to it
+    mPropertyNotification = SceneGraph::PropertyNotification::New( *mObject,
+                                                                   mObjectPropertyIndex,
+                                                                   mPropertyType,
+                                                                   mComponentIndex,
+                                                                   GetImplementation( mCondition ).type,
+                                                                   mRawConditionArgs,
+                                                                   mNotifyMode,
+                                                                   mCompare );
+    OwnerPointer< SceneGraph::PropertyNotification > transferOwnership( const_cast<SceneGraph::PropertyNotification*>( mPropertyNotification ) );
+    AddPropertyNotificationMessage( mUpdateManager, transferOwnership );
+  }
 }
 
 void PropertyNotification::DestroySceneObject()
 {
-  if ( mPropertyNotification != NULL )
+  if ( mPropertyNotification != nullptr )
   {
     // Remove PropertyNotification using a message to the update manager
     RemovePropertyNotificationMessage( mUpdateManager, *mPropertyNotification );
-    mPropertyNotification = NULL;
+    mPropertyNotification = nullptr;
   }
 }