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