[dali_2.3.23] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / windows / callback-manager-win.cpp
1 /*\r
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  *\r
16  */\r
17 \r
18 // CLASS HEADER\r
19 #include <dali/internal/system/windows/callback-manager-win.h>\r
20 \r
21 // EXTERNAL INCLUDES\r
22 #include <Windows.h>\r
23 \r
24 // Need to undef the following constants as they are defined in one of the headers in Windows.h but used in DALi (via debug.h)\r
25 #undef TRANSPARENT // Used in constants.h\r
26 #undef CopyMemory  // Used in dali-vector.h\r
27 \r
28 #include <dali/integration-api/debug.h>\r
29 \r
30 // INTERNAL INCLUDES\r
31 #include <dali/internal/window-system/windows/platform-implement-win.h>\r
32 \r
33 namespace Dali\r
34 {\r
35 namespace Internal\r
36 {\r
37 namespace Adaptor\r
38 {\r
39 /**\r
40  * Structure contains the callback function and control options\r
41  */\r
42 struct WindowsCallbackData\r
43 {\r
44   /**\r
45    * Constructor\r
46    */\r
47   WindowsCallbackData(CallbackBase* callback, bool hasReturnValue)\r
48   : mCallback(callback),\r
49     mHasReturnValue(hasReturnValue)\r
50   {\r
51   }\r
52   /**\r
53    * Destructor\r
54    */\r
55   ~WindowsCallbackData()\r
56   {\r
57     delete mCallback;\r
58   }\r
59 \r
60   CallbackBase* mCallback;       ///< call back\r
61   bool          mHasReturnValue; ///< true if the callback function has a return value.\r
62 };\r
63 \r
64 WinCallbackManager::WinCallbackManager()\r
65 : mRunning(false)\r
66 {\r
67   mSelfCallback = MakeCallback(this, &WinCallbackManager::ProcessIdleFromFramework);\r
68 }\r
69 \r
70 WinCallbackManager::~WinCallbackManager()\r
71 {\r
72   delete mSelfCallback;\r
73 }\r
74 \r
75 void WinCallbackManager::Start()\r
76 {\r
77   DALI_ASSERT_DEBUG(mRunning == false);\r
78   mRunning = true;\r
79 }\r
80 \r
81 void WinCallbackManager::Stop()\r
82 {\r
83   // make sure we're not called twice\r
84   DALI_ASSERT_DEBUG(mRunning == true);\r
85 \r
86   ClearIdleCallbacks();\r
87 \r
88   mRunning = false;\r
89 }\r
90 \r
91 bool WinCallbackManager::AddIdleCallback(CallbackBase* callback, bool hasReturnValue)\r
92 {\r
93   if(!mRunning)\r
94   {\r
95     return false;\r
96   }\r
97 \r
98   WindowsCallbackData* callbackData = new WindowsCallbackData(callback, hasReturnValue);\r
99 \r
100   mCallbackContainer.push_back(callbackData);\r
101 \r
102   if(!mSelfCallbackRegistered)\r
103   {\r
104     // Post only one times.\r
105     mSelfCallbackRegistered = true;\r
106     WindowsPlatform::PostWinThreadMessage(WIN_CALLBACK_EVENT, reinterpret_cast<uint64_t>(mSelfCallback), 0);\r
107   }\r
108 \r
109   return true;\r
110 }\r
111 \r
112 void WinCallbackManager::RemoveIdleCallback(CallbackBase* callback)\r
113 {\r
114   for(auto iter = mCallbackContainer.begin(), endIter = mCallbackContainer.end(); iter != endIter; ++iter)\r
115   {\r
116     auto* callbackData = *iter;\r
117 \r
118     if(callbackData->mCallback == callback)\r
119     {\r
120       // delete our data\r
121       delete callbackData;\r
122 \r
123       // Set stored value as nullptr. It will be removed from container after ProcessIdle()\r
124       (*iter) = nullptr;\r
125 \r
126       return;\r
127     }\r
128   }\r
129 }\r
130 \r
131 bool WinCallbackManager::ProcessIdle()\r
132 {\r
133   mSelfCallbackRegistered = false;\r
134 \r
135   const bool idleProcessed = !mCallbackContainer.empty();\r
136 \r
137   for(auto iter = mCallbackContainer.begin(); iter != mCallbackContainer.end();)\r
138   {\r
139     auto* callbackData = *iter;\r
140     bool  removed      = true;\r
141     if(callbackData)\r
142     {\r
143       if(callbackData->mHasReturnValue)\r
144       {\r
145         const bool retValue = Dali::CallbackBase::ExecuteReturn<bool>(*(callbackData->mCallback));\r
146 \r
147         // Do not remove callback if return value is true.\r
148         removed = !retValue;\r
149       }\r
150       else\r
151       {\r
152         Dali::CallbackBase::Execute(*(callbackData->mCallback));\r
153       }\r
154     }\r
155 \r
156     if(removed)\r
157     {\r
158       delete (*iter);\r
159       iter = mCallbackContainer.erase(iter);\r
160     }\r
161     else\r
162     {\r
163       ++iter;\r
164     }\r
165   }\r
166 \r
167   // Re-register WIN_CALLBACK_EVENT when some idle callback remained.\r
168   if(!mCallbackContainer.empty())\r
169   {\r
170     if(!mSelfCallbackRegistered)\r
171     {\r
172       // Post only one times.\r
173       mSelfCallbackRegistered = true;\r
174       WindowsPlatform::PostWinThreadMessage(WIN_CALLBACK_EVENT, reinterpret_cast<uint64_t>(mSelfCallback), 0);\r
175     }\r
176   }\r
177 \r
178   return idleProcessed;\r
179 }\r
180 \r
181 void WinCallbackManager::ClearIdleCallbacks()\r
182 {\r
183   for(auto iter = mCallbackContainer.begin(), endIter = mCallbackContainer.end(); iter != endIter; ++iter)\r
184   {\r
185     auto* callbackData = *iter;\r
186     delete callbackData;\r
187   }\r
188   mCallbackContainer.clear();\r
189 }\r
190 \r
191 bool WinCallbackManager::AddIdleEntererCallback(CallbackBase* callback)\r
192 {\r
193   return AddIdleCallback(callback, true);\r
194 }\r
195 \r
196 void WinCallbackManager::RemoveIdleEntererCallback(CallbackBase* callback)\r
197 {\r
198   RemoveIdleCallback(callback);\r
199 }\r
200 \r
201 void WinCallbackManager::ProcessIdleFromFramework()\r
202 {\r
203   ProcessIdle();\r
204 }\r
205 \r
206 } // namespace Adaptor\r
207 \r
208 } // namespace Internal\r
209 \r
210 } // namespace Dali\r