void TryMatchPatterns(OscParser parser, byte *bufferPtr, int addressLength) { // to support OSC address patterns, we test unmatched addresses against regular expressions // To do that, we need it as a regular string. We may be able to mutate a previous string, // instead of always allocating a new one if (!m_ByteLengthToStringBuffer.TryGetValue(addressLength, out var stringBuffer)) { stringBuffer = Encoding.ASCII.GetString(bufferPtr, addressLength); m_ByteLengthToStringBuffer[addressLength] = stringBuffer; } else { // If we've previously received a message of the same byte length, we can re-use it OverwriteAsciiString(stringBuffer, bufferPtr); } if (AddressSpace.TryMatchPatternHandler(stringBuffer, m_PatternMatchedMethods)) { var bufferCopy = string.Copy(stringBuffer); AddressSpace.AddressToMethod.Add(bufferCopy, m_PatternMatchedMethods); foreach (var matchedMethod in m_PatternMatchedMethods) { matchedMethod.ValueRead(parser.MessageValues); m_MainThreadQueue[m_MainThreadCount++] = matchedMethod.MainThreadQueued; } } }
void HandleMonitorCallbacks(byte *bufferPtr, int addressLength, OscParser parser) { // handle monitor callbacks var monitorAddressStr = new BlobString(bufferPtr, addressLength); foreach (var callback in m_MonitorCallbacks) { callback(monitorAddressStr, parser.MessageValues); } }
public bool RemoveAddressMethod(string address) { if (string.IsNullOrEmpty(address)) { return(false); } switch (OscParser.GetAddressType(address)) { case AddressType.Address: return(AddressToMethod.RemoveAddress(address)); default: return(false); } }
public bool TryAddMethod(string address, OscActionPair onReceived) { if (string.IsNullOrEmpty(address) || onReceived == null) { return(false); } switch (OscParser.GetAddressType(address)) { case AddressType.Address: AddressToMethod.Add(address, onReceived); return(true); case AddressType.Pattern: int index; // if a method has already been registered for this pattern, add the new delegate if (PatternStringToIndex.TryGetValue(address, out index)) { PatternMethods[index] += onReceived; return(true); } if (FreedPatternIndices.Count > 0) { index = FreedPatternIndices.Dequeue(); } else { index = PatternCount; if (index >= Patterns.Length) { var newSize = Patterns.Length * 2; Array.Resize(ref Patterns, newSize); Array.Resize(ref PatternMethods, newSize); } } Patterns[index] = new Regex(address); PatternMethods[index] = onReceived; PatternStringToIndex[address] = index; PatternCount++; return(true); default: return(false); } }
/// <summary> /// Try to match an address against all known address patterns, /// and add a handler for the address if a pattern is matched /// </summary> /// <param name="address">The address to match</param> /// <param name="allMatchedMethods"></param> /// <returns>True if a match was found, false otherwise</returns> public bool TryMatchPatternHandler(string address, List <OscActionPair> allMatchedMethods) { if (!OscParser.AddressIsValid(address)) { return(false); } allMatchedMethods.Clear(); bool any = false; for (var i = 0; i < PatternCount; i++) { if (Patterns[i].IsMatch(address)) { var handler = PatternMethods[i]; AddressToMethod.Add(address, handler); any = true; } } return(any); }
public OscServer(int port, int bufferSize = 4096) { if (PortToServer.ContainsKey(port)) { Debug.LogError($"port {port} is already in use, cannot start a new OSC Server on it"); return; } k_SingleCallbackToPair.Clear(); AddressSpace = new OscAddressSpace(); m_ReadBuffer = new byte[bufferSize]; m_BufferHandle = GCHandle.Alloc(m_ReadBuffer, GCHandleType.Pinned); m_BufferPtr = (byte *)m_BufferHandle.AddrOfPinnedObject(); Parser = new OscParser(m_ReadBuffer); Port = port; m_Socket = new OscSocket(port) { Server = this }; Start(); }
public bool RemoveMethod(string address, OscActionPair onReceived) { if (string.IsNullOrEmpty(address) || onReceived == null) { return(false); } switch (OscParser.GetAddressType(address)) { case AddressType.Address: return(AddressToMethod.Remove(address, onReceived)); case AddressType.Pattern: if (!PatternStringToIndex.TryGetValue(address, out var patternIndex)) { return(false); } var method = PatternMethods[patternIndex].ValueRead; if (method.GetInvocationList().Length == 1) { Patterns[patternIndex] = null; PatternMethods[patternIndex] = null; } else { PatternMethods[patternIndex] -= onReceived; } PatternCount--; FreedPatternIndices.Enqueue(patternIndex); return(PatternStringToIndex.Remove(address)); default: return(false); } }
public OscServer(int port, int bufferSize = 4096) { if (PortToServer.ContainsKey(port)) { Debug.LogError($"port {port} is already in use, cannot start a new OSC Server on it"); return; } k_SingleCallbackToPair.Clear(); AddressSpace = new OscAddressSpace(); m_ReadBuffer = new byte[bufferSize]; m_BufferHandle = GCHandle.Alloc(m_ReadBuffer, GCHandleType.Pinned); m_BufferPtr = (byte *)m_BufferHandle.AddrOfPinnedObject(); Parser = new OscParser(m_ReadBuffer); Port = port; m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) { ReceiveTimeout = int.MaxValue }; m_Thread = new Thread(Serve); Start(); }