[dali_2.3.23] Merge branch 'devel/master'
[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         mTouchEventProcessor.ProcessTouchEvent(touchEvent);
154
155         mGestureEventProcessor.ProcessTouchEvent(mScene, touchEvent);
156         break;
157       }
158
159       case Event::Hover:
160       {
161         mHoverEventProcessor.ProcessHoverEvent(static_cast<const Integration::HoverEvent&>(*event));
162         break;
163       }
164
165       case Event::Key:
166       {
167         mKeyEventProcessor.ProcessKeyEvent(static_cast<const Integration::KeyEvent&>(*event));
168         break;
169       }
170
171       case Event::Wheel:
172       {
173         mWheelEventProcessor.ProcessWheelEvent(static_cast<const Integration::WheelEvent&>(*event));
174         break;
175       }
176     }
177     // Call virtual destructor explictly; since delete will not be called after placement new
178     event->~Event();
179   }
180
181   queueToProcess->Reset();
182 }
183
184 void EventProcessor::SendInterruptedEvents(Dali::Internal::Actor *actor)
185 {
186     //TODO: Other event types should also be added if needed
187     mHoverEventProcessor.SendInterruptedHoverEvent(actor);
188 }
189
190 } // namespace Internal
191
192 } // namespace Dali