Browse Source

love.touch.getTouches now returns the list of ids in a stable order, instead of being effectively randomly ordered.

The least recently pressed (longest-pressed) active touch id is first in the list, etc.
Alex Szpakowski 9 years ago
parent
commit
b794ffa84a

+ 4 - 9
src/modules/touch/Touch.h

@@ -55,19 +55,14 @@ public:
 	virtual ModuleType getModuleType() const { return M_TOUCH; }
 
 	/**
-	 * Gets a list of the IDs of all currently active touches.
+	 * Gets all currently active touches.
 	 **/
-	virtual std::vector<int64> getTouches() const = 0;
+	virtual const std::vector<TouchInfo> &getTouches() const = 0;
 
 	/**
-	 * Gets the position in pixels of a specific touch, using its ID.
+	 * Gets a specific touch, using its ID.
 	 **/
-	virtual void getPosition(int64 id, double &x, double &y) const = 0;
-
-	/**
-	 * Gets the pressure of a specific touch, using its ID.
-	 **/
-	virtual double getPressure(int64 id) const = 0;
+	virtual const TouchInfo &getTouch(int64 id) const = 0;
 
 }; // Touch
 

+ 28 - 25
src/modules/touch/sdl/Touch.cpp

@@ -23,6 +23,9 @@
 #include "common/Exception.h"
 #include "Touch.h"
 
+// C++
+#include <algorithm>
+
 namespace love
 {
 namespace touch
@@ -30,34 +33,20 @@ namespace touch
 namespace sdl
 {
 
-std::vector<int64> Touch::getTouches() const
-{
-	std::vector<int64> ids;
-	ids.reserve(touches.size());
-
-	for (const auto &touch : touches)
-		ids.push_back(touch.first);
-
-	return ids;
-}
-
-void Touch::getPosition(int64 id, double &x, double &y) const
+const std::vector<Touch::TouchInfo> &Touch::getTouches() const
 {
-	const auto it = touches.find(id);
-	if (it == touches.end())
-		throw love::Exception("Invalid active touch ID: %d", id);
-
-	x = it->second.x;
-	y = it->second.y;
+	return touches;
 }
 
-double Touch::getPressure(int64 id) const
+const Touch::TouchInfo &Touch::getTouch(int64 id) const
 {
-	const auto it = touches.find(id);
-	if (it == touches.end())
-		throw love::Exception("Invalid active touch ID: %d", id);
+	for (const auto &touch : touches)
+	{
+		if (touch.id == id)
+			return touch;
+	}
 
-	return it->second.pressure;
+	throw love::Exception("Invalid active touch ID: %d", id);
 }
 
 const char *Touch::getName() const
@@ -67,14 +56,28 @@ const char *Touch::getName() const
 
 void Touch::onEvent(Uint32 eventtype, const TouchInfo &info)
 {
+	auto compare = [&](const TouchInfo &touch) -> bool
+	{
+		return touch.id == info.id;
+	};
+
 	switch (eventtype)
 	{
 	case SDL_FINGERDOWN:
+		touches.erase(std::remove_if(touches.begin(), touches.end(), compare), touches.end());
+		touches.push_back(info);
+		break;
 	case SDL_FINGERMOTION:
-		touches[info.id] = info;
+	{
+		for (TouchInfo &touch : touches)
+		{
+			if (touch.id == info.id)
+				touch = info;
+		}
 		break;
+	}
 	case SDL_FINGERUP:
-		touches.erase(info.id);
+		touches.erase(std::remove_if(touches.begin(), touches.end(), compare), touches.end());
 		break;
 	default:
 		break;

+ 4 - 8
src/modules/touch/sdl/Touch.h

@@ -24,9 +24,6 @@
 // LOVE
 #include "touch/Touch.h"
 
-// C++
-#include <map>
-
 // SDL
 #include <SDL_events.h>
 
@@ -43,9 +40,8 @@ public:
 
 	virtual ~Touch() {}
 
-	std::vector<int64> getTouches() const override;
-	void getPosition(int64 id, double &x, double &y) const override;
-	double getPressure(int64 id) const override;
+	const std::vector<TouchInfo> &getTouches() const override;
+	const TouchInfo &getTouch(int64 id) const override;
 
 	// Implements Module.
 	const char *getName() const override;
@@ -59,8 +55,8 @@ public:
 
 private:
 
-	// All current touches, indexed by their IDs.
-	std::map<int64, TouchInfo> touches;
+	// All current touches.
+	std::vector<TouchInfo> touches;
 
 }; // Touch
 

+ 13 - 12
src/modules/touch/wrap_Touch.cpp

@@ -42,18 +42,18 @@ int64 luax_checktouchid(lua_State *L, int idx)
 
 int w_getTouches(lua_State *L)
 {
-	std::vector<int64> ids = instance()->getTouches();
+	const std::vector<Touch::TouchInfo> &touches = instance()->getTouches();
 
-	lua_createtable(L, (int) ids.size(), 0);
+	lua_createtable(L, (int) touches.size(), 0);
 
-	for (size_t i = 0; i < ids.size(); i++)
+	for (size_t i = 0; i < touches.size(); i++)
 	{
 		// This is a bit hackish and we lose the higher 32 bits of the id on
 		// 32-bit systems, but SDL only ever gives id's that at most use as many
 		// bits as can fit in a pointer (for now.)
 		// We use lightuserdata instead of a lua_Number (double) because doubles
 		// can't represent all possible id values on 64-bit systems.
-		lua_pushlightuserdata(L, (void *) (intptr_t) ids[i]);
+		lua_pushlightuserdata(L, (void *) (intptr_t) touches[i].id);
 		lua_rawseti(L, -2, (int) i + 1);
 	}
 
@@ -64,12 +64,11 @@ int w_getPosition(lua_State *L)
 {
 	int64 id = luax_checktouchid(L, 1);
 
-	double x = 0;
-	double y = 0;
-	luax_catchexcept(L, [&]() { instance()->getPosition(id, x, y); });
+	Touch::TouchInfo touch = {};
+	luax_catchexcept(L, [&]() { touch = instance()->getTouch(id); });
 
-	lua_pushnumber(L, x);
-	lua_pushnumber(L, y);
+	lua_pushnumber(L, touch.x);
+	lua_pushnumber(L, touch.y);
 
 	return 2;
 }
@@ -77,9 +76,11 @@ int w_getPosition(lua_State *L)
 int w_getPressure(lua_State *L)
 {
 	int64 id = luax_checktouchid(L, 1);
-	double pressure = 0.0;
-	luax_catchexcept(L, [&](){ pressure = instance()->getPressure(id); });
-	lua_pushnumber(L, pressure);
+
+	Touch::TouchInfo touch = {};
+	luax_catchexcept(L, [&](){ touch = instance()->getTouch(id); });
+
+	lua_pushnumber(L, touch.pressure);
 	return 1;
 }