2
0
Эх сурвалжийг харах

Moved the SDL touch ID -> Urho touch ID logic from UI to Input, so that querying Input/TouchState should give you a touch index that will always be consistent (between TouchDown and TouchUp events) and start from 1.

hdunderscore 11 жил өмнө
parent
commit
b49e0c2a5d

+ 67 - 3
Source/Engine/Input/Input.cpp

@@ -61,6 +61,8 @@ const StringHash VAR_BUTTON_MOUSE_BUTTON_BINDING("VAR_BUTTON_MOUSE_BUTTON_BINDIN
 const StringHash VAR_LAST_KEYSYM("VAR_LAST_KEYSYM");
 const StringHash VAR_LAST_KEYSYM("VAR_LAST_KEYSYM");
 const StringHash VAR_SCREEN_JOYSTICK_ID("VAR_SCREEN_JOYSTICK_ID");
 const StringHash VAR_SCREEN_JOYSTICK_ID("VAR_SCREEN_JOYSTICK_ID");
 
 
+const unsigned TOUCHID_MAX = 32;
+
 /// Convert SDL keycode if necessary.
 /// Convert SDL keycode if necessary.
 int ConvertSDLKeyCode(int keySym, int scanCode)
 int ConvertSDLKeyCode(int keySym, int scanCode)
 {
 {
@@ -114,6 +116,9 @@ Input::Input(Context* context) :
     suppressNextMouseMove_(false),
     suppressNextMouseMove_(false),
     initialized_(false)
     initialized_(false)
 {
 {
+    for (int i = 0; i < TOUCHID_MAX; i++)
+        availableTouchIDs_.Push(i);
+
     SubscribeToEvent(E_SCREENMODE, HANDLER(Input, HandleScreenMode));
     SubscribeToEvent(E_SCREENMODE, HANDLER(Input, HandleScreenMode));
 
 
     // Try to initialize right now, but skip if screen mode is not yet set
     // Try to initialize right now, but skip if screen mode is not yet set
@@ -928,6 +933,62 @@ void Input::ResetTouches()
     touches_.Clear();
     touches_.Clear();
 }
 }
 
 
+unsigned Input::GetTouchIndexFromID(int touchID)
+{
+    HashMap<int, int>::ConstIterator i = touchIDMap_.Find(touchID);
+    if (i != touchIDMap_.End())
+    {
+        return i->second_;
+    }
+
+    int index = PopTouchIndex();
+    touchIDMap_[touchID] = index;
+    return index;
+}
+
+unsigned Input::PopTouchIndex()
+{
+    if (availableTouchIDs_.Empty())
+        return 0;
+
+    unsigned index = availableTouchIDs_.Front();
+    availableTouchIDs_.PopFront();
+    return index;
+}
+
+void Input::PushTouchIndex(int touchID)
+{
+    HashMap<int, int>::ConstIterator ci = touchIDMap_.Find(touchID);
+    if (ci == touchIDMap_.End())
+        return;
+
+    int index = touchIDMap_[touchID];
+    touchIDMap_.Erase(touchID);
+
+    // Sorted insertion
+    bool inserted = false;
+    for (List<int>::Iterator i = availableTouchIDs_.Begin(); i != availableTouchIDs_.End(); ++i)
+    {
+        if (*i == index)
+        {
+            // This condition can occur when TOUCHID_MAX is reached.
+            inserted = true;
+            break;
+        }
+
+        if (*i > index)
+        {
+            availableTouchIDs_.Insert(i, index);
+            inserted = true;
+            break;
+        }
+    }
+
+    // If empty, or the lowest value then insert at end.
+    if (!inserted)
+        availableTouchIDs_.Push(index);
+}
+
 void Input::SendInputFocusEvent()
 void Input::SendInputFocusEvent()
 {
 {
     using namespace InputFocus;
     using namespace InputFocus;
@@ -1172,7 +1233,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
     case SDL_FINGERDOWN:
     case SDL_FINGERDOWN:
         if (evt.tfinger.touchId != SDL_TOUCH_MOUSEID)
         if (evt.tfinger.touchId != SDL_TOUCH_MOUSEID)
         {
         {
-            int touchID = evt.tfinger.fingerId & 0x7ffffff;
+            int touchID = GetTouchIndexFromID(evt.tfinger.fingerId & 0x7ffffff);
             TouchState& state = touches_[touchID];
             TouchState& state = touches_[touchID];
             state.touchID_ = touchID;
             state.touchID_ = touchID;
             state.lastPosition_ = state.position_ = IntVector2((int)(evt.tfinger.x * graphics_->GetWidth()),
             state.lastPosition_ = state.position_ = IntVector2((int)(evt.tfinger.x * graphics_->GetWidth()),
@@ -1194,7 +1255,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
     case SDL_FINGERUP:
     case SDL_FINGERUP:
         if (evt.tfinger.touchId != SDL_TOUCH_MOUSEID)
         if (evt.tfinger.touchId != SDL_TOUCH_MOUSEID)
         {
         {
-            int touchID = evt.tfinger.fingerId & 0x7ffffff;
+            int touchID = GetTouchIndexFromID(evt.tfinger.fingerId & 0x7ffffff);
             TouchState& state = touches_[touchID];
             TouchState& state = touches_[touchID];
 
 
             using namespace TouchEnd;
             using namespace TouchEnd;
@@ -1207,6 +1268,9 @@ void Input::HandleSDLEvent(void* sdlEvent)
             eventData[P_Y] = state.position_.y_;
             eventData[P_Y] = state.position_.y_;
             SendEvent(E_TOUCHEND, eventData);
             SendEvent(E_TOUCHEND, eventData);
 
 
+            // Add touch index back to list of available touch Ids
+            PushTouchIndex(touchID);
+
             touches_.Erase(touchID);
             touches_.Erase(touchID);
         }
         }
         break;
         break;
@@ -1214,7 +1278,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
     case SDL_FINGERMOTION:
     case SDL_FINGERMOTION:
         if (evt.tfinger.touchId != SDL_TOUCH_MOUSEID)
         if (evt.tfinger.touchId != SDL_TOUCH_MOUSEID)
         {
         {
-            int touchID = evt.tfinger.fingerId & 0x7ffffff;
+            int touchID = GetTouchIndexFromID(evt.tfinger.fingerId & 0x7ffffff);
             // We don't want this event to create a new touches_ event if it doesn't exist (touchEmulation)
             // We don't want this event to create a new touches_ event if it doesn't exist (touchEmulation)
             if (touchEmulation_ && !touches_.Contains(touchID))
             if (touchEmulation_ && !touches_.Contains(touchID))
                 break;
                 break;

+ 11 - 0
Source/Engine/Input/Input.h

@@ -26,6 +26,7 @@
 #include "InputEvents.h"
 #include "InputEvents.h"
 #include "Mutex.h"
 #include "Mutex.h"
 #include "Object.h"
 #include "Object.h"
+#include "List.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
@@ -243,6 +244,12 @@ private:
     void ResetState();
     void ResetState();
     /// Clear touch states and send touch end events.
     /// Clear touch states and send touch end events.
     void ResetTouches();
     void ResetTouches();
+    /// Get the index of a touch based on the touch ID.
+    unsigned GetTouchIndexFromID(int touchID);
+    /// Used internally to return and remove the next available touch index.
+    unsigned PopTouchIndex();
+    /// Push a touch index back into the list of available when finished with it.
+    void PushTouchIndex(int touchID);
     /// Send an input focus or window minimization change event.
     /// Send an input focus or window minimization change event.
     void SendInputFocusEvent();
     void SendInputFocusEvent();
     /// Handle a mouse button change.
     /// Handle a mouse button change.
@@ -274,6 +281,10 @@ private:
     HashSet<int> scancodePress_;
     HashSet<int> scancodePress_;
     /// Active finger touches.
     /// Active finger touches.
     HashMap<int, TouchState> touches_;
     HashMap<int, TouchState> touches_;
+    /// List that maps between event touch IDs and normalised touch IDs
+    List<int> availableTouchIDs_;
+    /// Mapping of touch indicies
+    HashMap<int, int> touchIDMap_;
     /// String for text input.
     /// String for text input.
     String textInput_;
     String textInput_;
     /// Opened joysticks.
     /// Opened joysticks.

+ 3 - 67
Source/Engine/UI/UI.cpp

@@ -69,8 +69,6 @@ const StringHash VAR_ORIGINAL_PARENT("OriginalParent");
 const StringHash VAR_ORIGINAL_CHILD_INDEX("OriginalChildIndex");
 const StringHash VAR_ORIGINAL_CHILD_INDEX("OriginalChildIndex");
 const StringHash VAR_PARENT_CHANGED("ParentChanged");
 const StringHash VAR_PARENT_CHANGED("ParentChanged");
 
 
-const unsigned TOUCHID_MAX = 32;
-
 const float DEFAULT_DOUBLECLICK_INTERVAL = 0.5f;
 const float DEFAULT_DOUBLECLICK_INTERVAL = 0.5f;
 const float DEFAULT_DRAGBEGIN_INTERVAL = 0.5f;
 const float DEFAULT_DRAGBEGIN_INTERVAL = 0.5f;
 const float DEFAULT_TOOLTIP_DELAY = 0.5f;
 const float DEFAULT_TOOLTIP_DELAY = 0.5f;
@@ -113,9 +111,6 @@ UI::UI(Context* context) :
     rootElement_->SetTraversalMode(TM_DEPTH_FIRST);
     rootElement_->SetTraversalMode(TM_DEPTH_FIRST);
     rootModalElement_->SetTraversalMode(TM_DEPTH_FIRST);
     rootModalElement_->SetTraversalMode(TM_DEPTH_FIRST);
 
 
-    for (int i = 0; i < TOUCHID_MAX; i++)
-        availableTouchIDs_.Push(i);
-
     // Register UI library object factories
     // Register UI library object factories
     RegisterUILibrary(context_);
     RegisterUILibrary(context_);
 
 
@@ -1486,7 +1481,7 @@ void UI::HandleTouchBegin(StringHash eventType, VariantMap& eventData)
     IntVector2 pos(eventData[P_X].GetInt(), eventData[P_Y].GetInt());
     IntVector2 pos(eventData[P_X].GetInt(), eventData[P_Y].GetInt());
     usingTouchInput_ = true;
     usingTouchInput_ = true;
 
 
-    int touchId = TOUCHID_MASK(GetTouchIndexFromID(eventData[P_TOUCHID].GetInt()));
+    int touchId = TOUCHID_MASK(eventData[P_TOUCHID].GetInt());
     WeakPtr<UIElement> element(GetElementAt(pos));
     WeakPtr<UIElement> element(GetElementAt(pos));
 
 
     if (element)
     if (element)
@@ -1506,10 +1501,7 @@ void UI::HandleTouchEnd(StringHash eventType, VariantMap& eventData)
 
 
     // Get the touch index
     // Get the touch index
     int eventTouchId = eventData[P_TOUCHID].GetInt();
     int eventTouchId = eventData[P_TOUCHID].GetInt();
-    int touchId = TOUCHID_MASK(GetTouchIndexFromID(eventTouchId));
-
-    // Add touch index back to list of available touch Ids
-    PushTouchIndex(eventTouchId);
+    int touchId = TOUCHID_MASK(eventTouchId);
 
 
     // Transmit hover end to the position where the finger was lifted
     // Transmit hover end to the position where the finger was lifted
     WeakPtr<UIElement> element(GetElementAt(pos));
     WeakPtr<UIElement> element(GetElementAt(pos));
@@ -1538,7 +1530,7 @@ void UI::HandleTouchMove(StringHash eventType, VariantMap& eventData)
     IntVector2 deltaPos(eventData[P_DX].GetInt(), eventData[P_DY].GetInt());
     IntVector2 deltaPos(eventData[P_DX].GetInt(), eventData[P_DY].GetInt());
     usingTouchInput_ = true;
     usingTouchInput_ = true;
 
 
-    int touchId = TOUCHID_MASK(GetTouchIndexFromID(eventData[P_TOUCHID].GetInt()));
+    int touchId = TOUCHID_MASK(eventData[P_TOUCHID].GetInt());
 
 
     ProcessMove(pos, deltaPos, touchId, 0, 0, true);
     ProcessMove(pos, deltaPos, touchId, 0, 0, true);
 }
 }
@@ -1747,62 +1739,6 @@ IntVector2 UI::SumTouchPositions(UI::DragData* dragData, const IntVector2& oldSe
     return sendPos;
     return sendPos;
 }
 }
 
 
-unsigned UI::GetTouchIndexFromID(int touchID)
-{
-    HashMap<int, int>::ConstIterator i = touchIDMap_.Find(touchID);
-    if (i != touchIDMap_.End())
-    {
-        return i->second_;
-    }
-
-    int index = PopTouchIndex();
-    touchIDMap_[touchID] = index;
-    return index;
-}
-
-unsigned UI::PopTouchIndex()
-{
-    if (availableTouchIDs_.Empty())
-        return 0;
-
-    unsigned index = availableTouchIDs_.Front();
-    availableTouchIDs_.PopFront();
-    return index;
-}
-
-void UI::PushTouchIndex(int touchID)
-{
-    HashMap<int, int>::ConstIterator ci = touchIDMap_.Find(touchID);
-    if (ci == touchIDMap_.End())
-        return;
-
-    int index = touchIDMap_[touchID];
-    touchIDMap_.Erase(touchID);
-
-    // Sorted insertion
-    bool inserted = false;
-    for (List<int>::Iterator i = availableTouchIDs_.Begin(); i != availableTouchIDs_.End(); ++i)
-    {
-        if (*i == index)
-        {
-            // This condition can occur when TOUCHID_MAX is reached.
-            inserted = true;
-            break;
-        }
-
-        if (*i > index)
-        {
-            availableTouchIDs_.Insert(i, index);
-            inserted = true;
-            break;
-        }
-    }
-
-    // If empty, or the lowest value then insert at end.
-    if (!inserted)
-        availableTouchIDs_.Push(index);
-}
-
 void RegisterUILibrary(Context* context)
 void RegisterUILibrary(Context* context)
 {
 {
     Font::RegisterObject(context);
     Font::RegisterObject(context);

+ 0 - 11
Source/Engine/UI/UI.h

@@ -25,7 +25,6 @@
 #include "Object.h"
 #include "Object.h"
 #include "Cursor.h"
 #include "Cursor.h"
 #include "UIBatch.h"
 #include "UIBatch.h"
-#include "List.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
@@ -230,12 +229,6 @@ private:
     void ProcessDragCancel();
     void ProcessDragCancel();
     /// Sum touch positions and return the begin position ready to send.
     /// Sum touch positions and return the begin position ready to send.
     IntVector2 SumTouchPositions(UI::DragData* dragData, const IntVector2& oldSendPos);
     IntVector2 SumTouchPositions(UI::DragData* dragData, const IntVector2& oldSendPos);
-    /// Get the index of a touch based on the touch ID.
-    unsigned GetTouchIndexFromID(int touchID);
-    /// Used internally to return and remove the next available touch index.
-    unsigned PopTouchIndex();
-    /// Push a touch index back into the list of available when finished with it.
-    void PushTouchIndex(int touchID);
 
 
     /// Graphics subsystem.
     /// Graphics subsystem.
     WeakPtr<Graphics> graphics_;
     WeakPtr<Graphics> graphics_;
@@ -311,10 +304,6 @@ private:
     HashMap<WeakPtr<UIElement>, int> touchDragElements_;
     HashMap<WeakPtr<UIElement>, int> touchDragElements_;
     /// Confirmed drag elements cache.
     /// Confirmed drag elements cache.
     Vector<UIElement*> dragElementsConfirmed_;
     Vector<UIElement*> dragElementsConfirmed_;
-    /// List that maps between event touch IDs and normalised touch IDs
-    List<int> availableTouchIDs_;
-    /// Mapping of touch indicies
-    HashMap<int, int> touchIDMap_;
 };
 };
 
 
 /// Register UI library objects.
 /// Register UI library objects.