Merge branch 'devel/master' into tizen
[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( Scene& scene, GestureEventProcessor& gestureEventProcessor )
59 : mScene( scene ),
60   mTouchEventProcessor( scene ),
61   mHoverEventProcessor( scene ),
62   mGestureEventProcessor( gestureEventProcessor ),
63   mKeyEventProcessor( scene ),
64   mWheelEventProcessor( scene ),
65   mEventQueue0( INITIAL_BUFFER_SIZE ),
66   mEventQueue1( INITIAL_BUFFER_SIZE ),
67   mCurrentEventQueue( &mEventQueue0 )
68 {
69 }
70
71 EventProcessor::~EventProcessor()
72 {
73   for( MessageBuffer::Iterator iter = mEventQueue0.Begin(); iter.IsValid(); iter.Next() )
74   {
75     // Call virtual destructor explictly; since delete will not be called after placement new
76     Event* event = reinterpret_cast< Event* >( iter.Get() );
77     event->~Event();
78   }
79
80   for( MessageBuffer::Iterator iter = mEventQueue1.Begin(); iter.IsValid(); iter.Next() )
81   {
82     // Call virtual destructor explictly; since delete will not be called after placement new
83     Event* event = reinterpret_cast< Event* >( iter.Get() );
84     event->~Event();
85   }
86 }
87
88 void EventProcessor::QueueEvent( const Event& event )
89 {
90   switch( event.type )
91   {
92     case Event::Touch:
93     {
94       typedef Integration::TouchEvent DerivedType;
95
96       // Reserve some memory inside the message queue
97       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
98
99       // Construct message in the message queue memory; note that delete should not be called on the return value
100       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
101
102       break;
103     }
104
105     case Event::Hover:
106     {
107       typedef Integration::HoverEvent DerivedType;
108
109       // Reserve some memory inside the message queue
110       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
111
112       // Construct message in the message queue memory; note that delete should not be called on the return value
113       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
114
115       break;
116     }
117
118     case Event::Key:
119     {
120       typedef Integration::KeyEvent DerivedType;
121
122       // Reserve some memory inside the message queue
123       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
124
125       // Construct message in the message queue memory; note that delete should not be called on the return value
126       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
127
128       break;
129     }
130
131     case Event::Wheel:
132     {
133       typedef Integration::WheelEvent DerivedType;
134
135       // Reserve some memory inside the message queue
136       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
137
138       // Construct message in the message queue memory; note that delete should not be called on the return value
139       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
140
141       break;
142     }
143
144     case Event::Gesture:
145     {
146       QueueGestureEvent( static_cast<const Integration::GestureEvent&>(event) );
147       break;
148     }
149
150   }
151 }
152
153 void EventProcessor::QueueGestureEvent(const Integration::GestureEvent& event)
154 {
155   switch( event.gestureType )
156   {
157     case Gesture::Pinch:
158     {
159       typedef Integration::PinchGestureEvent DerivedType;
160
161       // Reserve some memory inside the message queue
162       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
163
164       // Construct message in the message queue memory; note that delete should not be called on the return value
165       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
166
167       break;
168     }
169
170     case Gesture::Pan:
171     {
172       typedef Integration::PanGestureEvent DerivedType;
173
174       // Reserve some memory inside the message queue
175       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
176
177       // Construct message in the message queue memory; note that delete should not be called on the return value
178       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
179
180       break;
181     }
182
183     case Gesture::Tap:
184     {
185       typedef Integration::TapGestureEvent DerivedType;
186
187       // Reserve some memory inside the message queue
188       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
189
190       // Construct message in the message queue memory; note that delete should not be called on the return value
191       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
192
193       break;
194     }
195
196     case Gesture::LongPress:
197     {
198       typedef Integration::LongPressGestureEvent DerivedType;
199
200       // Reserve some memory inside the message queue
201       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
202
203       // Construct message in the message queue memory; note that delete should not be called on the return value
204       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
205
206       break;
207     }
208   }
209 }
210
211 void EventProcessor::ProcessEvents()
212 {
213   MessageBuffer* queueToProcess = mCurrentEventQueue;
214
215   // Switch current queue; events can be added safely while iterating through the other queue.
216   mCurrentEventQueue = ( &mEventQueue0 == mCurrentEventQueue ) ? &mEventQueue1 : &mEventQueue0;
217
218   for( MessageBuffer::Iterator iter = queueToProcess->Begin(); iter.IsValid(); iter.Next() )
219   {
220     Event* event = reinterpret_cast< Event* >( iter.Get() );
221
222     switch( event->type )
223     {
224       case Event::Touch:
225       {
226         mTouchEventProcessor.ProcessTouchEvent( static_cast<const Integration::TouchEvent&>(*event) );
227         break;
228       }
229
230       case Event::Hover:
231       {
232         mHoverEventProcessor.ProcessHoverEvent( static_cast<const Integration::HoverEvent&>(*event) );
233         break;
234       }
235
236       case Event::Key:
237       {
238         mKeyEventProcessor.ProcessKeyEvent( static_cast<const Integration::KeyEvent&>(*event) );
239         break;
240       }
241
242       case Event::Wheel:
243       {
244         mWheelEventProcessor.ProcessWheelEvent( static_cast<const Integration::WheelEvent&>(*event) );
245         break;
246       }
247
248       case Event::Gesture:
249       {
250         mGestureEventProcessor.ProcessGestureEvent( mScene, static_cast<const Integration::GestureEvent&>(*event) );
251         break;
252       }
253
254     }
255     // Call virtual destructor explictly; since delete will not be called after placement new
256     event->~Event();
257   }
258
259   queueToProcess->Reset();
260 }
261
262 } // namespace Internal
263
264 } // namespace Dali