/// <summary> /// Remove this particular regex/subscriber pair (UNTESTED AND API /// MAY CHANGE). If regex is null, all subscriptions for 'sub' are /// cancelled. If subscriber is null, any previous subscriptions /// matching the regular expression will be cancelled. If both /// 'sub' and 'regex' are null, all subscriptions will be /// cancelled. /// </summary> /// <param name="regex">regular expression determining the channels to unsubscribe</param> /// <param name="sub">unsubscribing object</param> public void Unsubscribe(string regex, LCMSubscriber sub) { if (this.closed) { throw new SystemException(); } Console.WriteLine("Unsubscribing: {0}", regex); lock (this) { foreach (Provider p in providers) { p.Unsubscribe(regex); } } // TODO: need providers to unsubscribe? // TODO: providers don't seem to use anything beyond first channel lock (subscriptions) { // Find and remove subscriber from list foreach (SubscriptionRecord sr in subscriptions.ToArray()) { if ((sub == null || sr.lcsub == sub) && (regex == null || sr.regex.Equals(regex))) { subscriptions.Remove(sr); } } // Find and remove subscriber from map List <SubscriptionRecord> srecs; foreach (string channel in subscriptionsMap.Keys) { if (subscriptionsMap.TryGetValue(channel, out srecs)) { foreach (SubscriptionRecord sr in srecs.ToArray()) { if ((sub == null || sr.lcsub == sub) && (regex == null || sr.regex.Equals(regex))) { srecs.Remove(sr); } } } } } }
/// <summary> /// Subscribe to all channels whose name matches the regular /// expression. Note that to subscribe to all channels, you must /// specify ".*", not "*". /// </summary> /// <param name="regex">regular expression determining the channels to subscribe</param> /// <param name="sub">subscribing object providing callback</param> public void Subscribe(string regex, LCMSubscriber sub) { if (this.closed) { throw new SystemException(); } SubscriptionRecord srec = new SubscriptionRecord(); srec.regex = regex; srec.pat = new Regex(regex); srec.lcsub = sub; lock (this) { foreach (Provider p in providers) { p.Subscribe(regex); } } lock (subscriptions) { if (!subscriptions.Exists(s => s.regex == srec.regex && s.lcsub == srec.lcsub)) { subscriptions.Add(srec); List <SubscriptionRecord> subs; Console.WriteLine("Subscribing: {0}", srec); foreach (string channel in subscriptionsMap.Keys) { if (srec.pat.IsMatch(channel)) { if (subscriptionsMap.TryGetValue(channel, out subs)) { subs.Add(srec); } } } } } }
/// <summary> /// A convenience function that subscribes to all LCM channels. /// </summary> /// <param name="sub">subscribing object providing callback</param> public void SubscribeAll(LCMSubscriber sub) { Subscribe(".*", sub); }
/// <summary> /// Remove this particular regex/subscriber pair (UNTESTED AND API /// MAY CHANGE). If regex is null, all subscriptions for 'sub' are /// cancelled. If subscriber is null, any previous subscriptions /// matching the regular expression will be cancelled. If both /// 'sub' and 'regex' are null, all subscriptions will be /// cancelled. /// </summary> /// <param name="regex">regular expression determining the channels to unsubscribe</param> /// <param name="sub">unsubscribing object</param> public void Unsubscribe(string regex, LCMSubscriber sub) { if (this.closed) { throw new SystemException(); } lock (this) { foreach (Provider p in providers) { p.Unsubscribe(regex); } } // TODO: need providers to unsubscribe? // TODO: providers don't seem to use anything beyond first channel lock (subscriptions) { // Find and remove subscriber from list foreach (SubscriptionRecord sr in subscriptions.ToArray()) { if ((sub == null || sr.lcsub == sub) && (regex == null || sr.regex.Equals(regex))) { subscriptions.Remove(sr); } } // Find and remove subscriber from map List<SubscriptionRecord> srecs; foreach (string channel in subscriptionsMap.Keys) { if (subscriptionsMap.TryGetValue(channel, out srecs)) { foreach (SubscriptionRecord sr in srecs.ToArray()) { if ((sub == null || sr.lcsub == sub) && (regex == null || sr.regex.Equals(regex))) { srecs.Remove(sr); } } } } } }
/// <summary> /// Subscribe to all channels whose name matches the regular /// expression. Note that to subscribe to all channels, you must /// specify ".*", not "*". /// </summary> /// <param name="regex">regular expression determining the channels to subscribe</param> /// <param name="sub">subscribing object providing callback</param> public void Subscribe(string regex, LCMSubscriber sub) { if (this.closed) { throw new SystemException(); } SubscriptionRecord srec = new SubscriptionRecord(); srec.regex = regex; srec.pat = new Regex(regex); srec.lcsub = sub; lock (this) { foreach (Provider p in providers) { p.Subscribe(regex); } } lock (subscriptions) { subscriptions.Add(srec); List<SubscriptionRecord> subs; foreach (string channel in subscriptionsMap.Keys) { if (srec.pat.IsMatch(channel)) { if (subscriptionsMap.TryGetValue(channel, out subs)) { subs.Add(srec); } } } } }