Remove object pointer from SceneGraph::PropertyNotification
[platform/core/uifw/dali-core.git] / dali / internal / event / common / property-notification-impl.cpp
index 57c5239..2d87787 100644 (file)
-//
-// 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) 2022 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>
 
 // INTERNAL INCLUDES
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/math/vector2.h>
-#include <dali/public-api/math/radian.h>
 #include <dali/internal/event/actors/actor-impl.h>
+#include <dali/internal/event/common/object-impl.h>
 #include <dali/internal/event/common/property-notification-manager.h>
-#include <dali/internal/event/common/proxy-object.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;
+#include <dali/internal/update/common/scene-graph-property-notification.h>
+#include <dali/internal/update/manager/update-manager.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/math/radian.h>
+#include <dali/public-api/math/vector2.h>
 
 using Dali::Internal::SceneGraph::UpdateManager;
 
 namespace Dali
 {
-
 namespace Internal
 {
-
-PropertyNotificationPtr PropertyNotification::New(Property& target,
-                                                  int componentIndex,
+PropertyNotificationPtr PropertyNotification::New(Property&                      target,
+                                                  int                            componentIndex,
                                                   const Dali::PropertyCondition& condition)
 {
   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
 
   UpdateManager& updateManager = tls.GetUpdateManager();
 
-  PropertyNotificationManager& propertyNotificationManager = Stage::GetCurrent()->GetPropertyNotificationManager();
-
-  PropertyNotificationPtr propertyNotification = new PropertyNotification(updateManager,
+  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,
+PropertyNotification::PropertyNotification(UpdateManager&                 updateManager,
+                                           PropertyNotificationManager&   propertyNotificationManager,
+                                           Property&                      target,
+                                           int                            componentIndex,
                                            const Dali::PropertyCondition& condition)
 : mUpdateManager(updateManager),
-  mPropertyNotification(NULL),
+  mPropertyNotification(nullptr),
   mPropertyNotificationManager(propertyNotificationManager),
-  mProxyPropertyIndex(target.propertyIndex),
+  mObjectPropertyIndex(target.propertyIndex),
   mPropertyType(Property::NONE),
   mComponentIndex(componentIndex),
   mCondition(condition),
-  mNotifyMode(Dali::PropertyNotification::NotifyOnTrue),
-  mNotifyResult(false)
+  mNotifyMode(Dali::PropertyNotification::NOTIFY_ON_TRUE),
+  mNotifyResult(false),
+  mCompare(false)
 {
-  // Set condition arguments (as simple vector of floats)
-  PropertyCondition::ArgumentContainer arguments = GetImplementation(condition).arguments;
-  PropertyCondition::ArgumentConstIter iter = arguments.begin();
+  const Internal::PropertyCondition& conditionImpl = GetImplementation(condition);
 
-  while( iter != arguments.end() )
+  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) );
-  if ( mProxy )
+  // Observe target object and create/destroy notification scene object accordingly.
+  mObject = dynamic_cast<Object*>(&GetImplementation(target.object));
+  if(mObject)
   {
-    mPropertyType = mProxy->GetPropertyType(mProxyPropertyIndex);
+    mPropertyType = mObject->GetPropertyType(mObjectPropertyIndex);
 
-    int internalComponentIndex = mProxy->GetPropertyComponentIndex(mProxyPropertyIndex);
-    if( internalComponentIndex != Property::INVALID_COMPONENT_INDEX )
+    int internalComponentIndex = mObject->GetPropertyComponentIndex(mObjectPropertyIndex);
+    if(internalComponentIndex != Property::INVALID_COMPONENT_INDEX)
     {
       // override the one passed in
       mComponentIndex = internalComponentIndex;
     }
     if(mComponentIndex != Property::INVALID_COMPONENT_INDEX)
     {
-      Property::Type type = mProxy->GetPropertyType(mProxyPropertyIndex);
-      if( type == Property::VECTOR2
-          || type == Property::VECTOR3
-          || type == Property::VECTOR4 )
+      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
-    const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
-    if (object)
+    // To cover swapping components, previous and current components should be compared.
+    if(mObject->GetPropertyType(mObjectPropertyIndex) == Property::VECTOR3)
     {
-      CreateSceneObject();
+      mCompare = true;
+      for(int i = 0; i < 3; ++i)
+      {
+        mRawConditionArgs.PushBack(0.0f);
+      }
     }
+
+    // all objects always have scene object
+    CreateSceneObject();
   }
 
   // Connect to the property notification manager
-  mPropertyNotificationManager.PropertyNotificationCreated( *this );
+  mPropertyNotificationManager.PropertyNotificationCreated(*this);
 }
 
 PropertyNotification::~PropertyNotification()
@@ -128,14 +122,14 @@ PropertyNotification::~PropertyNotification()
   Disable();
 
   // Guard to disallow use of PropertyNotificationManager after Core has been destroyed
-  if ( Stage::IsInstalled() )
+  if(Stage::IsInstalled())
   {
     // Disconnect from the property notification manager
-    mPropertyNotificationManager.PropertyNotificationDestroyed( *this );
+    mPropertyNotificationManager.PropertyNotificationDestroyed(*this);
   }
 }
 
-Dali::PropertyNotifySignalV2& PropertyNotification::NotifySignal()
+Dali::PropertyNotifySignalType& PropertyNotification::NotifySignal()
 {
   return mNotifySignal;
 }
@@ -144,7 +138,7 @@ void PropertyNotification::EmitSignalNotify()
 {
   Dali::PropertyNotification source(this);
 
-  mNotifySignal.Emit( source );
+  mNotifySignal.Emit(source);
 }
 
 void PropertyNotification::Enable()
@@ -155,14 +149,14 @@ void PropertyNotification::Enable()
 void PropertyNotification::Disable()
 {
   // Guard to allow handle destruction after Core has been destroyed
-  if ( Stage::IsInstalled() )
+  if(Stage::IsInstalled())
   {
     // Stop scene-graph from monitoring the target's properties.
     DestroySceneObject();
   }
 }
 
-void PropertyNotification::SetNotifyResult( bool result )
+void PropertyNotification::SetNotifyResult(bool result)
 {
   mNotifyResult = result;
 }
@@ -174,22 +168,22 @@ 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 )
+void PropertyNotification::SetNotifyMode(NotifyMode mode)
 {
   mNotifyMode = mode;
-  if( mPropertyNotification )
+  if(mPropertyNotification)
   {
-    PropertyNotificationSetNotifyModeMessage( mUpdateManager, mPropertyNotification, mode );
+    PropertyNotificationSetNotifyModeMessage(mUpdateManager, mPropertyNotification, mode);
   }
 }
 
@@ -203,37 +197,39 @@ bool PropertyNotification::GetNotifyResult() const
   return mNotifyResult;
 }
 
-bool PropertyNotification::CompareSceneObject( const SceneGraph::PropertyNotification* sceneObject )
+bool PropertyNotification::CompareSceneObject(const SceneGraph::PropertyNotification* sceneObject)
 {
   return sceneObject && sceneObject == mPropertyNotification;
 }
 
 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)
+  {
+    const PropertyInputImpl* property = mObject->GetSceneObjectInputProperty(mObjectPropertyIndex);
+
+    // Create a new PropertyNotification, keep a const pointer to it
+    mPropertyNotification = SceneGraph::PropertyNotification::New(property,
+                                                                  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;
+    RemovePropertyNotificationMessage(mUpdateManager, *mPropertyNotification);
+    mPropertyNotification = nullptr;
   }
 }