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