License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / controls / style-change-processor.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 #include "style-change-processor.h"
19
20 #include <boost/thread/tss.hpp>
21
22 #include "dali-toolkit/public-api/controls/control.h"
23 #include "dali-toolkit/public-api/controls/control-impl.h"
24
25 namespace Dali
26 {
27
28 namespace Toolkit
29 {
30
31 namespace Internal
32 {
33
34 namespace
35 {
36 boost::thread_specific_ptr<StyleChangeProcessor> gThreadLocalStyleChangeProcessor;
37 } // unnamed namespace
38
39 StyleChangeProcessor::~StyleChangeProcessor()
40 {
41 }
42
43 void StyleChangeProcessor::Register( ControlImpl* control )
44 {
45   // Only create a style change processor if we have not created one in the local thread storage.
46   if (!gThreadLocalStyleChangeProcessor.get())
47   {
48     gThreadLocalStyleChangeProcessor.reset(new StyleChangeProcessor);
49   }
50
51   gThreadLocalStyleChangeProcessor->Reference();
52
53   std::vector<ControlImpl*>& controls( gThreadLocalStyleChangeProcessor->mControls );
54
55   // Store the Control raw pointer to allow traverse all off stage controls.
56   DALI_ASSERT_ALWAYS( ( std::find( controls.begin(), controls.end(), control ) == controls.end() ) && "StyleChangeProcessor::Register. The control has been registered twice." );
57
58   controls.push_back( control );
59 }
60
61 void StyleChangeProcessor::Unregister( ControlImpl* control )
62 {
63   if (gThreadLocalStyleChangeProcessor.get())
64   {
65     std::vector<ControlImpl*>& controls( gThreadLocalStyleChangeProcessor->mControls );
66
67     // Removes the control from the vector as is not needed to notify it about style changes.
68     std::vector<ControlImpl*>::iterator it = std::find( controls.begin(), controls.end(), control );
69     std::vector<ControlImpl*>::iterator endIt = controls.end();
70     DALI_ASSERT_ALWAYS( ( it != endIt ) && "StyleChangeProcessor::UnRegister. The control has not been registered in the StyleChangeProcessor." );
71
72     *it = *(endIt - 1);
73     controls.erase( endIt - 1 );
74
75     gThreadLocalStyleChangeProcessor->Unreference();
76   }
77 }
78
79 void StyleChangeProcessor::Reference()
80 {
81   ++mCount;
82 }
83
84 void StyleChangeProcessor::Unreference()
85 {
86   if (--mCount == 0)
87   {
88     // If our count is 0, then we should reset the local storage which will call our destructor as well.
89     gThreadLocalStyleChangeProcessor.reset();
90   }
91 }
92
93 StyleChangeProcessor::StyleChangeProcessor()
94 : mCount(0)
95 {
96   if ( Adaptor::IsAvailable() )
97   {
98     StyleMonitor::Get().StyleChangeSignal().Connect(this, &StyleChangeProcessor::StyleChanged);
99   }
100 }
101
102 void StyleChangeProcessor::StyleChanged(Dali::StyleMonitor styleMonitor, StyleChange styleChange)
103 {
104   // Traverse all registered controls.
105   std::vector<ControlImpl*>& controls( gThreadLocalStyleChangeProcessor->mControls );
106
107   for( std::vector<ControlImpl*>::iterator it = controls.begin(), endIt = controls.end(); it != endIt; ++it )
108   {
109     // Create a valid handle.
110     IntrusivePtr<ControlImpl> implementation( *it );
111
112     if (implementation)
113     {
114       implementation->OnStyleChange( styleChange );
115     }
116   }
117 }
118
119 } // namespace Internal
120
121 } // namespace Toolkit
122
123 } // namespace Dali