[dali_1.3.47] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / events / event-processor.cpp
1 /*
2  * Copyright (c) 2018 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/events/event-processor.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/events/event.h>
24 #include <dali/integration-api/events/gesture-event.h>
25 #include <dali/integration-api/events/key-event-integ.h>
26 #include <dali/integration-api/events/wheel-event-integ.h>
27 #include <dali/integration-api/events/touch-event-integ.h>
28 #include <dali/integration-api/events/hover-event-integ.h>
29 #include <dali/integration-api/events/pinch-gesture-event.h>
30 #include <dali/integration-api/events/pan-gesture-event.h>
31 #include <dali/integration-api/events/tap-gesture-event.h>
32 #include <dali/integration-api/events/long-press-gesture-event.h>
33 #include <dali/internal/event/events/gesture-event-processor.h>
34 #include <dali/internal/common/core-impl.h>
35 #include <dali/internal/event/common/notification-manager.h>
36
37 using Dali::Integration::Event;
38
39 namespace Dali
40 {
41
42 namespace Internal
43 {
44
45 namespace // unnamed namespace
46 {
47
48 static const std::size_t MAX_MESSAGE_SIZE = std::max( sizeof(Integration::TouchEvent),
49                                                       std::max( sizeof(Integration::KeyEvent),
50                                                                 std::max( sizeof(Integration::WheelEvent), sizeof(Integration::GestureEvent) ) ) );
51
52 static const std::size_t INITIAL_MIN_CAPACITY = 4;
53
54 static const std::size_t INITIAL_BUFFER_SIZE = MAX_MESSAGE_SIZE * INITIAL_MIN_CAPACITY;
55
56 } // unnamed namespace
57
58 EventProcessor::EventProcessor(Stage& stage, NotificationManager& /* notificationManager */, GestureEventProcessor& gestureEventProcessor)
59 : mTouchEventProcessor(stage),
60   mHoverEventProcessor(stage),
61   mGestureEventProcessor(gestureEventProcessor),
62   mKeyEventProcessor(stage),
63   mWheelEventProcessor(stage),
64   mEventQueue0( INITIAL_BUFFER_SIZE ),
65   mEventQueue1( INITIAL_BUFFER_SIZE ),
66   mCurrentEventQueue( &mEventQueue0 )
67 {
68 }
69
70 EventProcessor::~EventProcessor()
71 {
72   for( MessageBuffer::Iterator iter = mEventQueue0.Begin(); iter.IsValid(); iter.Next() )
73   {
74     // Call virtual destructor explictly; since delete will not be called after placement new
75     Event* event = reinterpret_cast< Event* >( iter.Get() );
76     event->~Event();
77   }
78
79   for( MessageBuffer::Iterator iter = mEventQueue1.Begin(); iter.IsValid(); iter.Next() )
80   {
81     // Call virtual destructor explictly; since delete will not be called after placement new
82     Event* event = reinterpret_cast< Event* >( iter.Get() );
83     event->~Event();
84   }
85 }
86
87 void EventProcessor::QueueEvent( const Event& event )
88 {
89   switch( event.type )
90   {
91     case Event::Touch:
92     {
93       typedef Integration::TouchEvent DerivedType;
94
95       // Reserve some memory inside the message queue
96       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
97
98       // Construct message in the message queue memory; note that delete should not be called on the return value
99       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
100
101       break;
102     }
103
104     case Event::Hover:
105     {
106       typedef Integration::HoverEvent DerivedType;
107
108       // Reserve some memory inside the message queue
109       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
110
111       // Construct message in the message queue memory; note that delete should not be called on the return value
112       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
113
114       break;
115     }
116
117     case Event::Key:
118     {
119       typedef Integration::KeyEvent DerivedType;
120
121       // Reserve some memory inside the message queue
122       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
123
124       // Construct message in the message queue memory; note that delete should not be called on the return value
125       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
126
127       break;
128     }
129
130     case Event::Wheel:
131     {
132       typedef Integration::WheelEvent DerivedType;
133
134       // Reserve some memory inside the message queue
135       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
136
137       // Construct message in the message queue memory; note that delete should not be called on the return value
138       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
139
140       break;
141     }
142
143     case Event::Gesture:
144     {
145       QueueGestureEvent( static_cast<const Integration::GestureEvent&>(event) );
146       break;
147     }
148
149   }
150 }
151
152 void EventProcessor::QueueGestureEvent(const Integration::GestureEvent& event)
153 {
154   switch( event.gestureType )
155   {
156     case Gesture::Pinch:
157     {
158       typedef Integration::PinchGestureEvent DerivedType;
159
160       // Reserve some memory inside the message queue
161       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
162
163       // Construct message in the message queue memory; note that delete should not be called on the return value
164       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
165
166       break;
167     }
168
169     case Gesture::Pan:
170     {
171       typedef Integration::PanGestureEvent DerivedType;
172
173       // Reserve some memory inside the message queue
174       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
175
176       // Construct message in the message queue memory; note that delete should not be called on the return value
177       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
178
179       break;
180     }
181
182     case Gesture::Tap:
183     {
184       typedef Integration::TapGestureEvent DerivedType;
185
186       // Reserve some memory inside the message queue
187       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
188
189       // Construct message in the message queue memory; note that delete should not be called on the return value
190       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
191
192       break;
193     }
194
195     case Gesture::LongPress:
196     {
197       typedef Integration::LongPressGestureEvent DerivedType;
198
199       // Reserve some memory inside the message queue
200       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
201
202       // Construct message in the message queue memory; note that delete should not be called on the return value
203       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
204
205       break;
206     }
207   }
208 }
209
210 void EventProcessor::ProcessEvents()
211 {
212   MessageBuffer* queueToProcess = mCurrentEventQueue;
213
214   // Switch current queue; events can be added safely while iterating through the other queue.
215   mCurrentEventQueue = (&mEventQueue0 == mCurrentEventQueue) ? &mEventQueue1 : &mEventQueue0;
216
217   for( MessageBuffer::Iterator iter = queueToProcess->Begin(); iter.IsValid(); iter.Next() )
218   {
219     Event* event = reinterpret_cast< Event* >( iter.Get() );
220
221     switch( event->type )
222     {
223       case Event::Touch:
224       {
225         mTouchEventProcessor.ProcessTouchEvent( static_cast<const Integration::TouchEvent&>(*event) );
226         break;
227       }
228
229       case Event::Hover:
230       {
231         mHoverEventProcessor.ProcessHoverEvent( static_cast<const Integration::HoverEvent&>(*event) );
232         break;
233       }
234
235       case Event::Key:
236       {
237         mKeyEventProcessor.ProcessKeyEvent( static_cast<const Integration::KeyEvent&>(*event) );
238         break;
239       }
240
241       case Event::Wheel:
242       {
243         mWheelEventProcessor.ProcessWheelEvent( static_cast<const Integration::WheelEvent&>(*event) );
244         break;
245       }
246
247       case Event::Gesture:
248       {
249         mGestureEventProcessor.ProcessGestureEvent( static_cast<const Integration::GestureEvent&>(*event) );
250         break;
251       }
252
253     }
254     // Call virtual destructor explictly; since delete will not be called after placement new
255     event->~Event();
256   }
257
258   queueToProcess->Reset();
259 }
260
261 } // namespace Internal
262
263 } // namespace Dali