Emscripten workarounds and llvm syntax fixes
[platform/core/uifw/dali-core.git] / dali / internal / event / events / event-processor.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/event/events/event-processor.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/integration-api/debug.h>
22 #include <dali/integration-api/events/event.h>
23 #include <dali/integration-api/events/gesture-event.h>
24 #include <dali/integration-api/events/key-event-integ.h>
25 #include <dali/integration-api/events/mouse-wheel-event-integ.h>
26 #include <dali/integration-api/events/touch-event-integ.h>
27 #include <dali/integration-api/events/pinch-gesture-event.h>
28 #include <dali/integration-api/events/pan-gesture-event.h>
29 #include <dali/integration-api/events/tap-gesture-event.h>
30 #include <dali/integration-api/events/long-press-gesture-event.h>
31 #include <dali/internal/event/events/gesture-event-processor.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/event/common/notification-manager.h>
34
35 using Dali::Integration::Event;
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 namespace // unnamed namespace
44 {
45
46 static const std::size_t MAX_MESSAGE_SIZE = std::max( sizeof(Integration::TouchEvent),
47                                                       std::max( sizeof(Integration::KeyEvent),
48                                                                 std::max( sizeof(Integration::MouseWheelEvent), sizeof(Integration::GestureEvent) ) ) );
49
50 static const std::size_t INITIAL_MIN_CAPICITY = 4;
51
52 static const std::size_t INITIAL_BUFFER_SIZE = MAX_MESSAGE_SIZE * INITIAL_MIN_CAPICITY;
53
54 } // unnamed namespace
55
56 EventProcessor::EventProcessor(Stage& stage, NotificationManager& /* notificationManager */, GestureEventProcessor& gestureEventProcessor)
57 : mTouchEventProcessor(stage),
58   mGestureEventProcessor(gestureEventProcessor),
59   mKeyEventProcessor(stage),
60   mMouseWheelEventProcessor(stage),
61   mEventQueue0( INITIAL_BUFFER_SIZE ),
62   mEventQueue1( INITIAL_BUFFER_SIZE ),
63   mCurrentEventQueue( &mEventQueue0 )
64 {
65 }
66
67 EventProcessor::~EventProcessor()
68 {
69   for( MessageBuffer::Iterator iter = mEventQueue0.Begin(); iter.IsValid(); iter.Next() )
70   {
71     // Call virtual destructor explictly; since delete will not be called after placement new
72     Event* event = reinterpret_cast< Event* >( iter.Get() );
73     event->~Event();
74   }
75
76   for( MessageBuffer::Iterator iter = mEventQueue1.Begin(); iter.IsValid(); iter.Next() )
77   {
78     // Call virtual destructor explictly; since delete will not be called after placement new
79     Event* event = reinterpret_cast< Event* >( iter.Get() );
80     event->~Event();
81   }
82 }
83
84 void EventProcessor::QueueEvent( const Event& event )
85 {
86   switch( event.type )
87   {
88     case Event::Touch:
89     {
90       typedef Integration::TouchEvent DerivedType;
91
92       // Reserve some memory inside the message queue
93       unsigned int* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
94
95       // Construct message in the message queue memory; note that delete should not be called on the return value
96       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
97
98       break;
99     }
100
101     case Event::Key:
102     {
103       typedef Integration::KeyEvent DerivedType;
104
105       // Reserve some memory inside the message queue
106       unsigned int* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
107
108       // Construct message in the message queue memory; note that delete should not be called on the return value
109       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
110
111       break;
112     }
113
114     case Event::MouseWheel:
115     {
116       typedef Integration::MouseWheelEvent DerivedType;
117
118       // Reserve some memory inside the message queue
119       unsigned int* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
120
121       // Construct message in the message queue memory; note that delete should not be called on the return value
122       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
123
124       break;
125     }
126
127     case Event::Notification:
128     {
129       // TODO - Remove this deprecated event
130       break;
131     }
132
133     case Event::Gesture:
134     {
135       QueueGestureEvent( static_cast<const Integration::GestureEvent&>(event) );
136       break;
137     }
138
139     default:
140     {
141       DALI_ASSERT_ALWAYS( false && "Invalid event sent from Integration\n" );
142       break;
143     }
144   }
145 }
146
147 void EventProcessor::QueueGestureEvent(const Integration::GestureEvent& event)
148 {
149   switch( event.gestureType )
150   {
151     case Gesture::Pinch:
152     {
153       typedef Integration::PinchGestureEvent DerivedType;
154
155       // Reserve some memory inside the message queue
156       unsigned int* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
157
158       // Construct message in the message queue memory; note that delete should not be called on the return value
159       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
160
161       break;
162     }
163
164     case Gesture::Pan:
165     {
166       typedef Integration::PanGestureEvent DerivedType;
167
168       // Reserve some memory inside the message queue
169       unsigned int* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
170
171       // Construct message in the message queue memory; note that delete should not be called on the return value
172       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
173
174       break;
175     }
176
177     case Gesture::Tap:
178     {
179       typedef Integration::TapGestureEvent DerivedType;
180
181       // Reserve some memory inside the message queue
182       unsigned int* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
183
184       // Construct message in the message queue memory; note that delete should not be called on the return value
185       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
186
187       break;
188     }
189
190     case Gesture::LongPress:
191     {
192       typedef Integration::LongPressGestureEvent DerivedType;
193
194       // Reserve some memory inside the message queue
195       unsigned int* slot = mCurrentEventQueue->ReserveMessageSlot( sizeof( DerivedType ) );
196
197       // Construct message in the message queue memory; note that delete should not be called on the return value
198       new (slot) DerivedType( static_cast<const DerivedType&>(event) );
199
200       break;
201     }
202
203     default:
204     {
205       DALI_ASSERT_ALWAYS( false && "Invalid event sent from Integration\n" );
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::Key:
231       {
232         mKeyEventProcessor.ProcessKeyEvent( static_cast<const Integration::KeyEvent&>(*event) );
233         break;
234       }
235
236       case Event::MouseWheel:
237       {
238         mMouseWheelEventProcessor.ProcessMouseWheelEvent( static_cast<const Integration::MouseWheelEvent&>(*event) );
239         break;
240       }
241
242       case Event::Gesture:
243       {
244         mGestureEventProcessor.ProcessGestureEvent( static_cast<const Integration::GestureEvent&>(*event) );
245         break;
246       }
247
248       default:
249       {
250         DALI_ASSERT_ALWAYS( false && "Invalid event sent from Integration\n" );
251         break;
252       }
253
254       // Call virtual destructor explictly; since delete will not be called after placement new
255       event->~Event();
256     }
257   }
258
259   queueToProcess->Reset();
260 }
261
262 } // namespace Internal
263
264 } // namespace Dali