License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / event / common / property-notification-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/common/property-notification-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/public-api/math/vector2.h>
24 #include <dali/public-api/math/radian.h>
25 #include <dali/internal/event/actors/actor-impl.h>
26 #include <dali/internal/event/common/property-notification-manager.h>
27 #include <dali/internal/event/common/proxy-object.h>
28 #include <dali/internal/event/common/stage-impl.h>
29 #include <dali/internal/update/manager/update-manager.h>
30 #include <dali/internal/update/common/scene-graph-property-notification.h>
31 #include <dali/internal/event/common/thread-local-storage.h>
32
33 using namespace std;
34
35 using Dali::Internal::SceneGraph::UpdateManager;
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 PropertyNotificationPtr PropertyNotification::New(Property& target,
44                                                   int componentIndex,
45                                                   const Dali::PropertyCondition& condition)
46 {
47   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
48
49   UpdateManager& updateManager = tls.GetUpdateManager();
50
51   PropertyNotificationManager& propertyNotificationManager = Stage::GetCurrent()->GetPropertyNotificationManager();
52
53   PropertyNotificationPtr propertyNotification = new PropertyNotification(updateManager,
54                                                                           propertyNotificationManager,
55                                                                           target,
56                                                                           componentIndex,
57                                                                           condition);
58
59   return propertyNotification;
60 }
61
62 PropertyNotification::PropertyNotification(UpdateManager& updateManager,
63                                            PropertyNotificationManager& propertyNotificationManager,
64                                            Property& target,
65                                            int componentIndex,
66                                            const Dali::PropertyCondition& condition)
67 : mUpdateManager(updateManager),
68   mPropertyNotification(NULL),
69   mPropertyNotificationManager(propertyNotificationManager),
70   mProxyPropertyIndex(target.propertyIndex),
71   mPropertyType(Property::NONE),
72   mComponentIndex(componentIndex),
73   mCondition(condition),
74   mNotifyMode(Dali::PropertyNotification::NotifyOnTrue),
75   mNotifyResult(false)
76 {
77   // Set condition arguments (as simple vector of floats)
78   PropertyCondition::ArgumentContainer arguments = GetImplementation(condition).arguments;
79   PropertyCondition::ArgumentConstIter iter = arguments.begin();
80
81   while( iter != arguments.end() )
82   {
83     const Property::Value& value = *iter;
84     float floatValue;
85     value.Get(floatValue);
86
87     mRawConditionArgs.PushBack( floatValue );
88     ++iter;
89   }
90
91   // Observe target proxy and create/destroy notification scene object accordingly.
92   mProxy = dynamic_cast<ProxyObject*>( &GetImplementation(target.object) );
93   if ( mProxy )
94   {
95     mPropertyType = mProxy->GetPropertyType(mProxyPropertyIndex);
96
97     int internalComponentIndex = mProxy->GetPropertyComponentIndex(mProxyPropertyIndex);
98     if( internalComponentIndex != Property::INVALID_COMPONENT_INDEX )
99     {
100       // override the one passed in
101       mComponentIndex = internalComponentIndex;
102     }
103     if(mComponentIndex != Property::INVALID_COMPONENT_INDEX)
104     {
105       Property::Type type = mProxy->GetPropertyType(mProxyPropertyIndex);
106       if( type == Property::VECTOR2
107           || type == Property::VECTOR3
108           || type == Property::VECTOR4 )
109       {
110         mPropertyType = Property::FLOAT;
111       }
112     }
113
114     // Check if target scene-object already present, and if so create our notification
115     // scene-object
116     const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
117     if (object)
118     {
119       CreateSceneObject();
120     }
121   }
122
123   // Connect to the property notification manager
124   mPropertyNotificationManager.PropertyNotificationCreated( *this );
125 }
126
127 PropertyNotification::~PropertyNotification()
128 {
129   Disable();
130
131   // Guard to disallow use of PropertyNotificationManager after Core has been destroyed
132   if ( Stage::IsInstalled() )
133   {
134     // Disconnect from the property notification manager
135     mPropertyNotificationManager.PropertyNotificationDestroyed( *this );
136   }
137 }
138
139 Dali::PropertyNotifySignalV2& PropertyNotification::NotifySignal()
140 {
141   return mNotifySignal;
142 }
143
144 void PropertyNotification::EmitSignalNotify()
145 {
146   Dali::PropertyNotification source(this);
147
148   mNotifySignal.Emit( source );
149 }
150
151 void PropertyNotification::Enable()
152 {
153   CreateSceneObject();
154 }
155
156 void PropertyNotification::Disable()
157 {
158   // Guard to allow handle destruction after Core has been destroyed
159   if ( Stage::IsInstalled() )
160   {
161     // Stop scene-graph from monitoring the target's properties.
162     DestroySceneObject();
163   }
164 }
165
166 void PropertyNotification::SetNotifyResult( bool result )
167 {
168   mNotifyResult = result;
169 }
170
171 const Dali::PropertyCondition& PropertyNotification::GetCondition() const
172 {
173   return mCondition;
174 }
175
176 Dali::Handle PropertyNotification::GetTarget() const
177 {
178   Dali::Handle handle(mProxy);
179
180   return handle;
181 }
182
183 Property::Index PropertyNotification::GetTargetProperty() const
184 {
185   return mProxyPropertyIndex;
186 }
187
188 void PropertyNotification::SetNotifyMode( NotifyMode mode )
189 {
190   mNotifyMode = mode;
191   if( mPropertyNotification )
192   {
193     PropertyNotificationSetNotifyModeMessage( mUpdateManager, mPropertyNotification, mode );
194   }
195 }
196
197 PropertyNotification::NotifyMode PropertyNotification::GetNotifyMode()
198 {
199   return mNotifyMode;
200 }
201
202 bool PropertyNotification::GetNotifyResult() const
203 {
204   return mNotifyResult;
205 }
206
207 bool PropertyNotification::CompareSceneObject( const SceneGraph::PropertyNotification* sceneObject )
208 {
209   return sceneObject && sceneObject == mPropertyNotification;
210 }
211
212 void PropertyNotification::CreateSceneObject()
213 {
214   DALI_ASSERT_DEBUG( mPropertyNotification == NULL );
215
216   // Create a new PropertyNotification, temporarily owned
217   SceneGraph::PropertyNotification* propertyNotification = SceneGraph::PropertyNotification::New( *mProxy,
218                                                                                                   mProxyPropertyIndex,
219                                                                                                   mPropertyType,
220                                                                                                   mComponentIndex,
221                                                                                                   GetImplementation(mCondition).type,
222                                                                                                   mRawConditionArgs,
223                                                                                                   mNotifyMode );
224   // Keep a const pointer to the PropertyNotification.
225   mPropertyNotification = propertyNotification;
226
227   // Transfer scene object ownership to the update manager through a message
228   AddPropertyNotificationMessage( mUpdateManager, propertyNotification );
229 }
230
231 void PropertyNotification::DestroySceneObject()
232 {
233   if ( mPropertyNotification != NULL )
234   {
235     // Remove PropertyNotification using a message to the update manager
236     RemovePropertyNotificationMessage( mUpdateManager, *mPropertyNotification );
237     mPropertyNotification = NULL;
238   }
239 }
240
241 } // namespace Internal
242
243 } // namespace Dali