1 // Copyright 2012 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef GESTURES_UTIL_H_
6 #define GESTURES_UTIL_H_
7
8 #include <list>
9 #include <map>
10 #include <set>
11 #include <vector>
12
13 #include <math.h>
14
15 #include "include/gestures.h"
16 #include "include/interpreter.h"
17
18 namespace gestures {
19
FloatEq(float a,float b)20 inline bool FloatEq(float a, float b) {
21 return fabsf(a - b) <= 1e-5;
22 }
23
DoubleEq(float a,float b)24 inline bool DoubleEq(float a, float b) {
25 return fabsf(a - b) <= 1e-8;
26 }
27
28 // Returns the square of the distance between the two contacts.
29 template<typename ContactTypeA, typename ContactTypeB>
DistSq(const ContactTypeA & finger_a,const ContactTypeB & finger_b)30 float DistSq(const ContactTypeA& finger_a, const ContactTypeB& finger_b) {
31 float dx = finger_a.position_x - finger_b.position_x;
32 float dy = finger_a.position_y - finger_b.position_y;
33 return dx * dx + dy * dy;
34 }
35 template<typename ContactType> // UnmergedContact or FingerState
DistSqXY(const ContactType & finger_a,float pos_x,float pos_y)36 float DistSqXY(const ContactType& finger_a, float pos_x, float pos_y) {
37 float dx = finger_a.position_x - pos_x;
38 float dy = finger_a.position_y - pos_y;
39 return dx * dx + dy * dy;
40 }
41
42 template<typename ContactType>
CompareX(const void * a_ptr,const void * b_ptr)43 int CompareX(const void* a_ptr, const void* b_ptr) {
44 const ContactType* a = *static_cast<const ContactType* const*>(a_ptr);
45 const ContactType* b = *static_cast<const ContactType* const*>(b_ptr);
46 return a->position_x < b->position_x ? -1 : a->position_x > b->position_x;
47 }
48
49 template<typename ContactType>
CompareY(const void * a_ptr,const void * b_ptr)50 int CompareY(const void* a_ptr, const void* b_ptr) {
51 const ContactType* a = *static_cast<const ContactType* const*>(a_ptr);
52 const ContactType* b = *static_cast<const ContactType* const*>(b_ptr);
53 return a->position_y < b->position_y ? -1 : a->position_y > b->position_y;
54 }
55
DegToRad(float degrees)56 inline float DegToRad(float degrees) {
57 return M_PI * degrees / 180.0;
58 }
59
60 template<typename Map, typename Key> static inline
MapContainsKey(const Map & the_map,const Key & the_key)61 bool MapContainsKey(const Map& the_map, const Key& the_key) {
62 return the_map.find(the_key) != the_map.end();
63 }
64
65 // Removes any ids from the map that are not finger ids in hs.
66 template<typename Data>
RemoveMissingIdsFromMap(std::map<short,Data> * the_map,const HardwareState & hs)67 void RemoveMissingIdsFromMap(std::map<short, Data>* the_map,
68 const HardwareState& hs) {
69 std::map<short, Data> removed;
70 for (const auto& [key, value] : *the_map) {
71 if (!hs.GetFingerState(key))
72 removed[key] = value;
73 }
74 for (const auto& [key, value] : removed)
75 the_map->erase(key);
76 }
77
78 // Removes any ids from the set that are not finger ids in hs.
79 static inline
RemoveMissingIdsFromSet(std::set<short> * the_set,const HardwareState & hs)80 void RemoveMissingIdsFromSet(std::set<short>* the_set,
81 const HardwareState& hs) {
82 std::vector<short> old_ids;
83 old_ids.reserve(the_set->size() + 1);
84 for (typename std::set<short>::const_iterator it = the_set->begin();
85 it != the_set->end(); ++it)
86 if (!hs.GetFingerState(*it))
87 old_ids.push_back(*it);
88 for (auto id : old_ids)
89 the_set->erase(id);
90 }
91
92 template<typename Set, typename Elt>
SetContainsValue(const Set & the_set,const Elt & elt)93 inline bool SetContainsValue(const Set& the_set,
94 const Elt& elt) {
95 return the_set.find(elt) != the_set.end();
96 }
97
98 template<typename Elem>
99 class List : public std::list<Elem> {
100 public:
at(int offset)101 Elem& at(int offset) {
102 // Traverse to the appropriate offset
103 if (offset < 0) {
104 // negative offset is from end to begin
105 for (auto iter = this->rbegin(); iter != this->rend(); ++iter) {
106 if (++offset == 0)
107 return *iter;
108 }
109 } else {
110 // positive offset is from begin to end
111 for (auto iter = this->begin(); iter != this->end(); ++iter) {
112 if (offset-- == 0)
113 return *iter;
114 }
115 }
116 // Invalid offset
117 abort();
118 }
119 };
120
121 } // namespace gestures
122
123 #endif // GESTURES_UTIL_H_
124