From 2843b9d3ce7726dc347db789660128f6258db425 Mon Sep 17 00:00:00 2001 From: Rico Tiongson Date: Thu, 7 Feb 2019 13:14:53 +0800 Subject: [PATCH 1/2] Optimize Regex patterns (#39) * Remove unused device and stamp from swipe_impl * Use constants for regex patterns * Compile regex outside of buffer function to avoid runtime hiccup * Catch dash symbol before event, remove trimming --- src/comfortable-swipe.cpp | 142 ++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 60 deletions(-) diff --git a/src/comfortable-swipe.cpp b/src/comfortable-swipe.cpp index 4c08ce1..e7643d4 100644 --- a/src/comfortable-swipe.cpp +++ b/src/comfortable-swipe.cpp @@ -56,10 +56,9 @@ extern "C" { /* FORWARD DECLARATIONS */ namespace util { - string join(cstr, string[], int); - string build_gesture_begin(); - string build_gesture_update(); - string build_gesture_end(); + extern const char* GESTURE_SWIPE_BEGIN_REGEX_PATTERN; + extern const char* GESTURE_SWIPE_UPDATE_REGEX_PATTERN; + extern const char* GESTURE_SWIPE_END_REGEX_PATTERN; map read_config_file(const char*); } @@ -90,7 +89,7 @@ int main(int argc, char** args) { } struct swipe_gesture { - string device, stamp, fingers; + string fingers; string dx, dy, udx, udy; xdo_t* xdo; virtual void on_update() = 0; @@ -207,14 +206,17 @@ namespace service { } namespace service { + + // process regex at compile time + const regex gesture_begin(util::GESTURE_SWIPE_BEGIN_REGEX_PATTERN); + const regex gesture_update(util::GESTURE_SWIPE_UPDATE_REGEX_PATTERN); + const regex gesture_end(util::GESTURE_SWIPE_END_REGEX_PATTERN); + // parses output from libinput debug-events void buffer() { // check first if $user ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); - const regex gesture_begin(util::build_gesture_begin()); - const regex gesture_update(util::build_gesture_update()); - const regex gesture_end(util::build_gesture_end()); string sentence; // read config file auto config = util::read_config_file(conf_filename().data()); @@ -234,25 +236,19 @@ namespace service { auto data = sentence.data(); cmatch matches; if (regex_match(data, matches, gesture_begin)) { - swipe.device = matches[1]; - swipe.stamp = matches[2]; - swipe.fingers = matches[3]; + swipe.fingers = matches[1]; swipe.on_begin(); } else if (regex_match(data, matches, gesture_end)) { - swipe.device = matches[1]; - swipe.stamp = matches[2]; - swipe.fingers = matches[3]; + swipe.fingers = matches[1]; swipe.on_end(); } else if (regex_match(data, matches, gesture_update)) { - swipe.device = matches[1]; - swipe.stamp = matches[2]; - swipe.fingers = matches[3]; - swipe.dx = matches[4]; - swipe.dy = matches[5]; - swipe.udx = matches[6]; - swipe.udy = matches[7]; + swipe.fingers = matches[1]; + swipe.dx = matches[2]; + swipe.dy = matches[3]; + swipe.udx = matches[4]; + swipe.udy = matches[5]; swipe.on_update(); } } @@ -337,50 +333,76 @@ namespace service { namespace util { - string number_regex() { - return "-?\\d+(?:\\.\\d+)"; - } - string join(cstr delim, string arr[], int n) { - string ans = arr[0]; - for (int i = 1; i < n; ++i) { - ans += delim; - ans += arr[i]; - } - return ans; - } + /** + * Regex pattern for the libinput entry for start of swipe. + * Extracts one match for the number of fingers used during the swipe. + * + * eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3 + * ^ + * fingers + */ + const char* GESTURE_SWIPE_BEGIN_REGEX_PATTERN = + "^" // start of string + "[ -]event\\d+" // event + "\\s+GESTURE_SWIPE_BEGIN" // gesture + "\\s+\\S+" // timestamp + "\\s+(\\d+)" // fingers + "$" // end of string + ; - string build_gesture_begin() { - string device = "\\s*(\\S+)\\s*"; - string gesture = "\\s*GESTURE_SWIPE_BEGIN\\s*"; - string seconds = "\\s*(\\S+)\\s*"; - string fingers = "\\s*(\\d+)\\s*"; - string arr[] = {device, gesture, seconds, fingers}; - return join("\\s+", arr, 4); - } + /** + * Regex pattern for the libinput entry for the end of swipe. + * Extracts one match for the number of fingers used during the swipe. + * + * eg. event15 GESTURE_SWIPE_END +35.03s 3 + * ^ + * fingers + */ + const char* GESTURE_SWIPE_END_REGEX_PATTERN = + "^" // start of string + "[ -]event\\d+" // event + "\\s+GESTURE_SWIPE_END" // gesture + "\\s+\\S+" // timestamp + "\\s+(\\d+)" // fingers + "$" // end of string + ; - string build_gesture_update() { - string device = "\\s*(\\S+)\\s*"; - string gesture = "\\s*GESTURE_SWIPE_UPDATE\\s*"; - string seconds = "\\s*(\\S+)\\s*"; - string fingers = "\\s*(\\d+)\\s*"; - string num_1 = "\\s*(" + number_regex() + ")\\s*"; - string num_2 = num_1; - string num_div = num_1 + "/" + num_2; - string num_accel = "\\s*\\(\\s*" + num_div + "\\s*unaccelerated\\s*\\)\\s*"; - string arr[] = {device, gesture, seconds, fingers, num_div, num_accel}; - return join("\\s+", arr, 6); - } + // matches signed decimal numbers (eg. "6.02" "-1.1") + #define CF_NUMBER_REGEX "-?\\d+(?:\\.\\d+)" - string build_gesture_end() { - string device = "\\s*(\\S+)\\s*"; - string gesture = "\\s*GESTURE_SWIPE_END\\s*"; - string seconds = "\\s*(\\S+)\\s*"; - string fingers = "\\s*(\\d+)\\s*"; - string arr[] = {device, gesture, seconds, fingers}; - return join("\\s+", arr, 4); - } + // matches and extracts a space-prefixed signed fraction (eg. "-3.00/ 5.12") + #define CF_NUMBER_DIVISION "\\s*(" CF_NUMBER_REGEX ")/\\s*(" CF_NUMBER_REGEX ")" + + /** + * Regex pattern for the libinput entry for during a swipe. + * Extracts number of fingers used and the speed (normal and accelerated) of the swipe. + * + * eg. event15 GESTURE_SWIPE_UPDATE +34.70s 3 -0.12/ 4.99 (-0.33/13.50 unaccelerated) + * ^ ^ ^ ^ ^ + * fingers dx dy udx udy + */ + const char* GESTURE_SWIPE_UPDATE_REGEX_PATTERN = + "^" // start of string + "[ -]event\\d+" // event + "\\s+GESTURE_SWIPE_UPDATE" // gesture + "\\s+\\S+" // timestamp + "\\s+(\\d+)" // fingers + "\\s+" CF_NUMBER_DIVISION // speed (dx/dy) + "\\s+\\(" CF_NUMBER_DIVISION "\\s+unaccelerated\\)" // unaccelerated speed (udx/udy) + "$" // end of string + ; + + // delete macros + #undef CF_NUMBER_DIVISION + #undef CF_NUMBER_EXTRACT + #undef CF_NUMBER_REGEX + /** + * A utility method for reading the config file. + * + * @param filename (const char*) the path of the config file. + */ map read_config_file(const char* filename) { map conf; ifstream fin(filename); From 328ae08ee1e732e1346275765d18572673541ca5 Mon Sep 17 00:00:00 2001 From: Rico Tiongson Date: Thu, 7 Feb 2019 17:39:32 +0800 Subject: [PATCH 2/2] Add `git` to install instructions in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b4bfa32..fc211a4 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures ## Installation -1. Install libinput and g++ +1. Install git, libinput, and g++ ```bash - sudo apt-get install libinput-tools libxdo-dev g++ + sudo apt-get install git libinput-tools libxdo-dev g++ ``` 2. Clone this repository