34361e5cf0b1684e69a34a0cf9f5a5982a2865e8
[platform/core/uifw/dali-core.git] / dali / internal / event / events / event-processor.cpp
1 /*
2  * Copyright (c) 2021 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/hover-event-integ.h>
25 #include <dali/integration-api/events/key-event-integ.h>
26 #include <dali/integration-api/events/touch-event-integ.h>
27 #include <dali/integration-api/events/wheel-event-integ.h>
28 #include <dali/internal/common/core-impl.h>
29 #include <dali/internal/event/common/notification-manager.h>
30 #include <dali/internal/event/events/gesture-event-processor.h>
31
32 using Dali::Integration::Event;
33
34 namespace Dali
35 {
36 namespace Internal
37 {
38 namespace // unnamed namespace
39 {
40 static const std::size_t MAX_MESSAGE_SIZE = std::max(sizeof(Integration::TouchEvent),
41                                                      std::max(sizeof(Integration::KeyEvent), sizeof(Integration::WheelEvent)));
42
43 static const std::size_t INITIAL_MIN_CAPACITY = 4;
44
45 static const std::size_t INITIAL_BUFFER_SIZE = MAX_MESSAGE_SIZE * INITIAL_MIN_CAPACITY;
46
47 } // unnamed namespace
48
49 EventProcessor::EventProcessor(Scene& scene, GestureEventProcessor& gestureEventProcessor)
50 : mScene(scene),
51   mTouchEventProcessor(scene),
52   mHoverEventProcessor(scene),
53   mGestureEventProcessor(gestureEventProcessor),
54   mKeyEventProcessor(scene),
55   mWheelEventProcessor(scene),
56   mEventQueue0(INITIAL_BUFFER_SIZE),
57   mEventQueue1(INITIAL_BUFFER_SIZE),
58   mCurrentEventQueue(&mEventQueue0)
59 {
60 }
61
62 EventProcessor::~EventProcessor()
63 {
64   for(MessageBuffer::Iterator iter = mEventQueue0.Begin(); iter.IsValid(); iter.Next())
65   {
66     // Call virtual destructor explictly; since delete will not be called after placement new
67     Event* event = reinterpret_cast<Event*>(iter.Get());
68     event->~Event();
69   }
70
71   for(MessageBuffer::Iterator iter = mEventQueue1.Begin(); iter.IsValid(); iter.Next())
72   {
73     // Call virtual destructor explictly; since delete will not be called after placement new
74     Event* event = reinterpret_cast<Event*>(iter.Get());
75     event->~Event();
76   }
77 }
78
79 void EventProcessor::QueueEvent(const Event& event)
80 {
81   switch(event.type)
82   {
83     case Event::Touch:
84     {
85       typedef Integration::TouchEvent DerivedType;
86
87       // Reserve some memory inside the message queue
88       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot(sizeof(DerivedType));
89
90       // Construct message in the message queue memory; note that delete should not be called on the return value
91       new(slot) DerivedType(static_cast<const DerivedType&>(event));
92
93       break;
94     }
95
96     case Event::Hover:
97     {
98       using DerivedType = Integration::HoverEvent;
99
100       // Reserve some memory inside the message queue
101       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot(sizeof(DerivedType));
102
103       // Construct message in the message queue memory; note that delete should not be called on the return value
104       new(slot) DerivedType(static_cast<const DerivedType&>(event));
105
106       break;
107     }
108
109     case Event::Key:
110     {
111       using DerivedType = Integration::KeyEvent;
112
113       // Reserve some memory inside the message queue
114       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot(sizeof(DerivedType));
115
116       // Construct message in the message queue memory; note that delete should not be called on the return value
117       new(slot) DerivedType(static_cast<const DerivedType&>(event));
118
119       break;
120     }
121
122     case Event::Wheel:
123     {
124       using DerivedType = Integration::WheelEvent;
125
126       // Reserve some memory inside the message queue
127       uint32_t* slot = mCurrentEventQueue->ReserveMessageSlot(sizeof(DerivedType));
128
129       // Construct message in the message queue memory; note that delete should not be called on the return value
130       new(slot) DerivedType(static_cast<const DerivedType&>(event));
131
132       break;
133     }
134   }
135 }
136
137 void EventProcessor::ProcessEvents()
138 {
139   MessageBuffer* queueToProcess = mCurrentEventQueue;
140
141   // Switch current queue; events can be added safely while iterating through the other queue.
142   mCurrentEventQueue = (&mEventQueue0 == mCurrentEventQueue) ? &mEventQueue1 : &mEventQueue0;
143
144   for(MessageBuffer::Iterator iter = queueToProcess->Begin(); iter.IsValid(); iter.Next())
145   {
146     Event* event = reinterpret_cast<Event*>(iter.Get());
147
148     switch(event->type)
149     {
150       case Event::Touch:
151       {
152         Integration::TouchEvent& touchEvent = static_cast<Integration::TouchEvent&>(*event);
153         const bool               consumed   = mTouchEventProcessor.ProcessTouchEvent(touchEvent);
154
155         // If touch is consumed, then gestures should be cancelled
156         // Do this by sending an interrupted event to the GestureEventProcessor
157         if(consumed)
158         {
159           Integration::Point& point = touchEvent.GetPoint(0);
160           point.SetState(PointState::INTERRUPTED);
161         }
162
163         mGestureEventProcessor.ProcessTouchEvent(mScene, touchEvent);
164         break;
165       }
166
167       case Event::Hover:
168       {
169         mHoverEventProcessor.ProcessHoverEvent(static_cast<const Integration::HoverEvent&>(*event));
170         break;
171       }
172
173       case Event::Key:
174       {
175         mKeyEventProcessor.ProcessKeyEvent(static_cast<const Integration::KeyEvent&>(*event));
176         break;
177       }
178
179       case Event::Wheel:
180       {
181         mWheelEventProcessor.ProcessWheelEvent(static_cast<const Integration::WheelEvent&>(*event));
182         break;
183       }
184     }
185     // Call virtual destructor explictly; since delete will not be called after placement new
186     event->~Event();
187   }
188
189   queueToProcess->Reset();
190 }
191
192 } // namespace Internal
193
194 } // namespace Dali