c2-utopia/lib/OSC/examples/PatternMatching/PatternMatching.ino

92 lines
4.1 KiB
Arduino
Raw Normal View History

/*
The library has four methods for doing pattern matching on address.
'match' and 'fullMatch' are specific to OSCMessages while route and dispatch work on both messages and bundles.
OSCMessage:
match - matches the message's address pattern against an address. returns the number of characters matched from the address passed in.
fullMatch - returns true if the pattern was a complete match against the address
OSCMessage && OSCBundle:
route - calls a function with the matched OSCMessage(s) and the number of matched characters in the address as the parameters
dispatch - calls a function with each OSCMessage which was fully matched by the pattern
///////////////////////////////////////////////////////////////////////////////////////////////////
OSC Regular expression pattern matching rules from http://opensoundcontrol.org/spec-1_0
1. '?' in the OSC Address Pattern matches any single character
2. '*' in the OSC Address Pattern matches any sequence of zero or more characters
3. A string of characters in square brackets (e.g., "[string]") in the OSC Address Pattern matches any character in the string.
Inside square brackets, the minus sign (-) and exclamation point (!) have special meanings:
two characters separated by a minus sign indicates the range of characters between the given two in ASCII collating sequence.
An exclamation point at the beginning of a bracketed string negates the sense of the list, meaning that the list matches any character not in the list.
4. A comma-separated list of strings enclosed in curly braces (e.g., "{foo,bar}") in the OSC Address Pattern matches any of the strings in the list.
5. Any other character in an OSC Address Pattern can match only the same character.
///////////////////////////////////////////////////////////////////////////////////////////////////
*/
#include <OSCBundle.h>
void setup() {
Serial.begin(38400);
}
void loop(){
//a heavily patterned message address
OSCMessage msg0("/{input,output}/[0-2]/[!ab]/*");
//match will traverse as far as it can in the pattern
//it returns the number of characters matched from the pattern
int patternOffset = msg0.match("/input/1");
if (patternOffset>0){
//string multiple 'match' methods together using the pattern offset parameter to continue matching where it left off
//use 'fullMatch' to test if the entire pattern was matched.
if(msg0.fullMatch("/c/anything", patternOffset)){
Serial.println("Match: '/input/1/c/anything' against the pattern '/{input,output}/[0-2]/[abc]/*'");
}
}
//write over the other message address
OSCMessage msg1("/partialMatch");
//match will return 0 if it did not reach the end or a '/'
if(!msg1.match("/partial")){
Serial.println("No Match: '/partial' against the pattern '/partialMatch'");
}
OSCMessage msg2("/output/[0-2]");
//'route' is uses 'match' to allow for partial matches
//it invokes the callback with the matched message and the pattern offset as parameters to the callback
msg2.route("/output", routeOutput);
//'dispatch' uses 'fullMatch' so it does not allow for partial matches
//invokes the callback with only one argument which is the matched message
msg2.dispatch("/output/1", routeOutputOne);
delay(1000);
}
//called after matching '/output'
//the matched message and the number of matched characters as the parameters
void routeOutput(OSCMessage &msg, int patternOffset){
Serial.println("Match: '/output'");
//string multiple 'route' methods together using the pattern offset parameter.
msg.route("/0", routeZero, patternOffset);
}
//called after matching '/0'
void routeZero(OSCMessage &msg, int addressOffset){
Serial.println("Match: '/output/0'");
}
//called after matching '/output/1'
void routeOutputOne(OSCMessage &msg){
Serial.println("Match: '/output/1'");
}
//
// TROUBLESHOOTING:
// Because of a bug in the Arduino IDE, it sometimes thinks that the '*' in combination with '/' is the opening or closing of a multiline comment
// This can be fixed by escaping the '/' with '\' or using the octal value of '*' which is '\052'
// for example:
// "/*" == "/\052" == "\/*"
//