2 * Copyright (c) 2023 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 #include <dali/internal/event/common/property-notification-impl.h>
22 #include <dali/internal/event/actors/actor-impl.h>
23 #include <dali/internal/event/common/object-impl.h>
24 #include <dali/internal/event/common/property-notification-manager.h>
25 #include <dali/internal/event/common/thread-local-storage.h>
26 #include <dali/internal/update/common/scene-graph-property-notification.h>
27 #include <dali/internal/update/manager/update-manager.h>
28 #include <dali/public-api/actors/actor.h>
29 #include <dali/public-api/common/dali-common.h>
30 #include <dali/public-api/math/radian.h>
31 #include <dali/public-api/math/vector2.h>
33 using Dali::Internal::SceneGraph::UpdateManager;
39 PropertyNotificationPtr PropertyNotification::New(Property& target,
41 const Dali::PropertyCondition& condition)
43 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
45 UpdateManager& updateManager = tls.GetUpdateManager();
47 PropertyNotificationManager& propertyNotificationManager = tls.GetPropertyNotificationManager();
48 PropertyNotificationPtr propertyNotification = new PropertyNotification(updateManager,
49 propertyNotificationManager,
53 return propertyNotification;
56 PropertyNotification::PropertyNotification(UpdateManager& updateManager,
57 PropertyNotificationManager& propertyNotificationManager,
60 const Dali::PropertyCondition& condition)
61 : mUpdateManager(updateManager),
62 mPropertyNotification(nullptr),
63 mPropertyNotificationManager(propertyNotificationManager),
64 mObjectPropertyIndex(target.propertyIndex),
65 mPropertyType(Property::NONE),
66 mComponentIndex(componentIndex),
67 mCondition(condition),
68 mNotifyMode(Dali::PropertyNotification::NOTIFY_ON_TRUE),
72 const Internal::PropertyCondition& conditionImpl = GetImplementation(condition);
74 Dali::Vector<float>::SizeType count = conditionImpl.arguments.Count();
75 for(Dali::Vector<float>::SizeType index = 0; index < count; ++index)
77 mRawConditionArgs.PushBack(conditionImpl.arguments[index]);
80 // Observe target object and create/destroy notification scene object accordingly.
81 mObject = dynamic_cast<Object*>(&GetImplementation(target.object));
84 mPropertyType = mObject->GetPropertyType(mObjectPropertyIndex);
86 int internalComponentIndex = mObject->GetPropertyComponentIndex(mObjectPropertyIndex);
87 if(internalComponentIndex != Property::INVALID_COMPONENT_INDEX)
89 // override the one passed in
90 mComponentIndex = internalComponentIndex;
92 if(mComponentIndex != Property::INVALID_COMPONENT_INDEX)
94 Property::Type type = mObject->GetPropertyType(mObjectPropertyIndex);
95 if(type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4)
97 mPropertyType = Property::FLOAT;
101 // To cover swapping components, previous and current components should be compared.
102 if(mObject->GetPropertyType(mObjectPropertyIndex) == Property::VECTOR3)
105 for(int i = 0; i < 3; ++i)
107 mRawConditionArgs.PushBack(0.0f);
111 // all objects always have scene object
115 // Connect to the property notification manager
116 mPropertyNotificationManager.PropertyNotificationCreated(*this);
119 PropertyNotification::~PropertyNotification()
123 // Guard to disallow use of PropertyNotificationManager after Core has been destroyed
124 if(!EventThreadServices::IsShuttingDown())
126 // Disconnect from the property notification manager
127 mPropertyNotificationManager.PropertyNotificationDestroyed(*this);
131 Dali::PropertyNotifySignalType& PropertyNotification::NotifySignal()
133 return mNotifySignal;
136 void PropertyNotification::EmitSignalNotify()
138 Dali::PropertyNotification source(this);
140 mNotifySignal.Emit(source);
143 void PropertyNotification::Enable()
148 void PropertyNotification::Disable()
150 // Guard to allow handle destruction after Core has been destroyed
151 if(!EventThreadServices::IsShuttingDown())
153 // Stop scene-graph from monitoring the target's properties.
154 DestroySceneObject();
158 void PropertyNotification::SetNotifyResult(bool result)
160 mNotifyResult = result;
163 const Dali::PropertyCondition& PropertyNotification::GetCondition() const
168 Dali::Handle PropertyNotification::GetTarget() const
170 Dali::Handle handle(mObject);
175 Property::Index PropertyNotification::GetTargetProperty() const
177 return mObjectPropertyIndex;
180 void PropertyNotification::SetNotifyMode(NotifyMode mode)
183 if(mPropertyNotification)
185 PropertyNotificationSetNotifyModeMessage(mUpdateManager, mPropertyNotification, mode);
189 PropertyNotification::NotifyMode PropertyNotification::GetNotifyMode()
194 bool PropertyNotification::GetNotifyResult() const
196 return mNotifyResult;
199 bool PropertyNotification::CompareSceneObject(const SceneGraph::PropertyNotification* sceneObject)
201 return sceneObject && sceneObject == mPropertyNotification;
204 void PropertyNotification::CreateSceneObject()
206 // this method can be called from constructor and on stage connection
207 if(!mPropertyNotification)
209 const PropertyInputImpl* property = mObject->GetSceneObjectInputProperty(mObjectPropertyIndex);
211 // Create a new PropertyNotification, keep a const pointer to it
212 mPropertyNotification = SceneGraph::PropertyNotification::New(property,
213 mObjectPropertyIndex,
216 GetImplementation(mCondition).type,
220 OwnerPointer<SceneGraph::PropertyNotification> transferOwnership(const_cast<SceneGraph::PropertyNotification*>(mPropertyNotification));
221 AddPropertyNotificationMessage(mUpdateManager, transferOwnership);
225 void PropertyNotification::DestroySceneObject()
227 if(mPropertyNotification != nullptr)
229 DALI_ASSERT_ALWAYS(EventThreadServices::IsCoreRunning());
231 // Remove PropertyNotification using a message to the update manager
232 RemovePropertyNotificationMessage(mUpdateManager, *mPropertyNotification);
233 mPropertyNotification = nullptr;
237 } // namespace Internal