Changed indicator bg color.
[platform/framework/native/uifw.git] / src / ui / FUi_ModalLoopManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FUi_ModalLoopManager.cpp
20  * @brief               This is the implementation file for the _ModalLoopManager class.
21  */
22
23 #include <new>
24 #include <pthread.h>
25 #include <FBaseSysLog.h>
26 #include <FBaseRtTimer.h>
27 #include "FUi_ModalLoopManager.h"
28 #include "FUi_EcoreEvasMgr.h"
29
30 using namespace Tizen::Base::Runtime;
31 using namespace Tizen::Ui;
32
33 namespace Tizen { namespace Ui
34 {
35
36 _ModalLoopManager::_ModalLoopManager(void)
37         : __pTimerInfoList(null)
38         , __nestedMainLoop(0)
39         , __lastExitCode(-1)
40 {
41         __pTimerInfoList = new (std::nothrow) TimerInfoList;
42         SysAssert(__pTimerInfoList);
43         __pTimerInfoList->Construct();
44 }
45
46 _ModalLoopManager::~_ModalLoopManager(void)
47 {
48         if (__pTimerInfoList)
49         {
50                 _TimerInfo timerInfo;
51                 const int count = __pTimerInfoList->GetCount();
52                 for (int i = 0; i < count; i++)
53                 {
54                         timerInfo.pTimer = null;
55                         __pTimerInfoList->GetAt(i, timerInfo);
56                         if (timerInfo.pTimer)
57                         {
58                                 delete timerInfo.pTimer;
59                         }
60                 }
61                 __pTimerInfoList->RemoveAll();
62                 delete __pTimerInfoList;
63                 __pTimerInfoList = null;
64         }
65
66         if (__nestedMainLoop > 0)
67         {
68                 SysLog(NID_UI, "[ModalLoopManager] The count of nested main loops is: %d", __nestedMainLoop);
69         }
70 }
71
72 int
73 _ModalLoopManager::BeginMainLoop(void)
74 {
75         __lastExitCode = -1;
76         __nestedMainLoop++;
77         ::GetEcoreEvasMgr()->BeginMainLoop();
78
79         return __nestedMainLoop;
80 }
81
82 int
83 _ModalLoopManager::BeginMainLoop(unsigned long timeOut, int exitCode)
84 {
85         result r = E_SUCCESS;
86         Timer* pTimer = null;
87
88         if (timeOut > 0l)
89         {
90                 pTimer = new (std::nothrow) Timer;
91                 SysTryReturn(NID_UI, pTimer != null, -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to create Timer.");
92
93                 r = pTimer->Construct(*this);
94                 SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
95
96                 r = pTimer->Start(timeOut);
97                 SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
98
99                 _TimerInfo timerInfo;
100                 timerInfo.loopId = __nestedMainLoop + 1;
101                 timerInfo.pTimer = pTimer;
102                 timerInfo.exitCode = exitCode;
103                 timerInfo.expired = false;
104                 r = __pTimerInfoList->Add(timerInfo);
105                 SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
106         }
107
108         return BeginMainLoop();
109
110 CATCH:
111         delete pTimer;
112         return -1;
113 }
114
115 int
116 _ModalLoopManager::EndMainLoop(int exitCode, bool endAllLoops)
117 {
118         if (__nestedMainLoop == 0)
119         {
120                 return __nestedMainLoop;
121         }
122
123         __lastExitCode = exitCode;
124
125         _TimerInfo timerInfo;
126         int timerCount = 0;
127         int loopCount = endAllLoops ? __nestedMainLoop : 1;
128         while (loopCount--)
129         {
130                 timerCount = __pTimerInfoList->GetCount();
131                 if (timerCount > 0)
132                 {
133                         __pTimerInfoList->GetAt(timerCount - 1, timerInfo);
134                         if (timerInfo.loopId == __nestedMainLoop)
135                         {
136                                 timerInfo.pTimer->Cancel();
137                                 delete timerInfo.pTimer;
138                                 __pTimerInfoList->RemoveAt(timerCount - 1);
139                         }
140                 }
141                 timerCount = __pTimerInfoList->GetCount();
142                 if (timerCount > 0)
143                 {
144                         __pTimerInfoList->GetAt(timerCount - 1, timerInfo);
145                         if ((timerInfo.loopId == __nestedMainLoop - 1) && (timerInfo.expired == true))
146                         {
147                                 __lastExitCode = -2;
148                         }
149                 }
150                 ::GetEcoreEvasMgr()->EndMainLoop();
151                 __nestedMainLoop--;
152         }
153
154         return __nestedMainLoop;
155 }
156
157 int
158 _ModalLoopManager::GetLastExitCode(void)
159 {
160         return __lastExitCode;
161 }
162
163 void
164 _ModalLoopManager::OnTimerExpired(Timer& timer)
165 {
166         const int count = __pTimerInfoList->GetCount();
167         int pos = -1;
168         int i = count -1;
169         _TimerInfo timerInfo;
170
171         while (i >= 0)
172         {
173                 __pTimerInfoList->GetAt(i, timerInfo);
174
175                 if (timerInfo.pTimer == &timer)
176                 {
177                         pos = timerInfo.loopId;
178                         timerInfo.expired = true;
179                         __pTimerInfoList->SetAt(timerInfo, i);
180                         break;
181                 }
182                 i--;
183         }
184
185         if (pos == __nestedMainLoop)
186         {
187                 _ModalLoopManager::GetInstance()->EndMainLoop(timerInfo.exitCode, false);
188         }
189 }
190
191 _ModalLoopManager* _ModalLoopManager::__pInstance = null;
192
193 void
194 _ModalLoopManager::Initialize(void)
195 {
196   static _ModalLoopManager instance;
197   __pInstance = &instance;
198 }
199
200 _ModalLoopManager*
201 _ModalLoopManager::GetInstance(void)
202 {
203   static pthread_once_t once_block = PTHREAD_ONCE_INIT;
204
205   if (!__pInstance)
206   {
207     pthread_once(&once_block, Initialize);
208   }
209
210   return __pInstance;
211 }
212
213 _ModalLoopManager::_TimerInfo::_TimerInfo(void)
214         : loopId(-1)
215         , pTimer(null)
216         , exitCode(-1)
217         , expired(false)
218 {
219 }
220
221 _ModalLoopManager::_TimerInfo::~_TimerInfo(void)
222 {
223 }
224
225 bool
226 _ModalLoopManager::_TimerInfo::operator==(const _ModalLoopManager::_TimerInfo& rhs) const
227 {
228         return ((loopId == rhs.loopId) && (pTimer == rhs.pTimer) && (exitCode == rhs.exitCode) && (expired == rhs.expired));
229 }
230
231 bool _ModalLoopManager::_TimerInfo::operator!=(const _ModalLoopManager::_TimerInfo& rhs) const
232 {
233         return ((loopId != rhs.loopId) || (pTimer != rhs.pTimer) || (exitCode != rhs.exitCode) || (expired != rhs.expired));
234 }
235
236 _ModalLoopManager::_TimerInfo&
237 _ModalLoopManager::_TimerInfo::operator=(const _ModalLoopManager::_TimerInfo& rhs)
238 {
239         loopId = rhs.loopId;
240         pTimer = rhs.pTimer;
241         exitCode = rhs.exitCode;
242         expired = rhs.expired;
243
244         return *this;
245 }
246
247 }} // Tizen::Ui