/// <summary>Dispatch <paramref name="events"/></summary> /// <param name="events"></param> public void DispatchEvents(ref StructList12 <IEvent> events) { // Errors StructList4 <Exception> errors = new StructList4 <Exception>(); for (int i = 0; i < events.Count; i++) { IEvent e = events[i]; try { e?.Observer?.Observer?.OnNext(e); } catch (Exception error) { if (errorHandler != null) { errorHandler(this, e, error); } else { errors.Add(error); } } } if (errors.Count > 0) { throw new AggregateException(errors.ToArray()); } }
/// <summary>Dispatch <paramref name="events"/></summary> /// <param name="events"></param> public void DispatchEvents(IEnumerable <IEvent> events) { // Errors StructList4 <Exception> errors = new StructList4 <Exception>(); if (events != null) { foreach (IEvent e in events) { try { e?.Observer?.Observer?.OnNext(e); } catch (Exception error) { if (errorHandler != null) { errorHandler(this, e, error); } else { errors.Add(error); } } } } if (errors.Count > 0) { throw new AggregateException(errors.ToArray()); } }
/// <summary>Union of <paramref name="o1"/> and <paramref name="o2"/>.</summary> public IOption Union(IOption o1, IOption o2) { StructList4 <IToken> tokens = new StructList4 <IToken>(); if (o1 is IToken t1) { foreach (IToken t in t1.ListTokens(true)) { tokens.AddIfNew(t); } } if (o2 is IToken t2) { foreach (IToken t in t2.ListTokens(true)) { tokens.AddIfNew(t); } } if (tokens.Count == 0) { return(TokenList.NoTokens); } if (tokens.Count == 1) { return(tokens[0]); } return(new TokenList(tokens.ToArray())); }
/// <summary>Dispose called by finalizer or consumer (on Dispose())</summary> protected virtual void Dispose(bool disposing) { if (disposing) { // Cancel source CancelSrc.Dispose(); // Array of observer handles var handles = observers.Array; // Errors StructList4 <Exception> errors = new StructList4 <Exception>(); foreach (var handle in handles) { try { handle.observer.OnCompleted(); } catch (Exception e) { // Add observer exception as error event, but don't dispatch it. Events.TryAdd(new OperationErrorEvent(null, e)); // Capture errors.Add(e); } } if (errors.Count > 0) { throw new AggregateException(errors.ToArray()); } } }
/// <summary> /// Concatenates three tokens non-recursively. /// Tokens may be null valued. /// </summary> /// <param name="t1">(optional) Token</param> /// <param name="t2">(optional) Token</param> /// <param name="t3">(optional) Token</param> /// <returns>null, t1, t2, or concatenated token</returns> public static IToken Concat(this IToken t1, IToken t2, IToken t3) { StructList4 <IToken> tokens = new StructList4 <IToken>(); if (t1 != null) { if (t1 is ITokenEnumerable enumr) { foreach (IToken t in enumr) { tokens.AddIfNew(t); } } else { tokens.AddIfNew(t1); } } if (t2 != null) { if (t2 is ITokenEnumerable enumr) { foreach (IToken t in enumr) { tokens.AddIfNew(t); } } else { tokens.AddIfNew(t2); } } if (t3 != null) { if (t3 is ITokenEnumerable enumr) { foreach (IToken t in enumr) { tokens.AddIfNew(t); } } else { tokens.AddIfNew(t3); } } if (tokens.Count == 0) { return(null); } if (tokens.Count == 1) { return(tokens[0]); } return(new TokenList(tokens.ToArray())); }
/// <summary> /// If <paramref name="tokenContainer"/> is a single token, then enumerates it. /// If <paramref name="tokenContainer"/> is token collection, then enumerates all contained tokens. /// If <paramref name="recurse"/> is true, then enumerates tree of collections. /// </summary> /// <param name="tokenContainer"></param> /// <param name="recurse"></param> /// <returns>enumerable of tokens</returns> public static IEnumerable <IToken> ListTokens(this IOption tokenContainer, bool recurse = true) { // Is a token if (tokenContainer is IToken token) { // Enumerable if (tokenContainer is ITokenEnumerable enumr) { // Return enumerable as is if (!recurse) { return(enumr); } // Put into queue StructList4 <IToken> queue = new StructList4 <IToken>(); foreach (IToken t in enumr) { queue.Add(t); } StructListSorter <StructList4 <IToken>, IToken> .Reverse(ref queue); StructList4 <IToken> result = new StructList4 <IToken>(); while (queue.Count > 0) { int ix = queue.Count - 1; IToken t = queue[ix]; queue.RemoveAt(ix); if (t is ITokenEnumerable enumr_) { foreach (IToken tt in enumr_) { queue.Add(tt); } } else { result.Add(t); } } return(result.ToArray()); } // Single token else { return new IToken[] { token } }; } else { // No tokens return(no_tokens); } }
/// <summary> /// Create a token that reads <paramref name="tokens"/> into array of tokens. /// Removes null values. /// </summary> /// <param name="tokens"></param> public TokenList(IEnumerable <IToken> tokens) { StructList4 <IToken> list = new StructList4 <IToken>(); foreach (var t in tokens) { if (t != null) { list.Add(t); } } this.tokens = list.ToArray(); }
/// <summary>Forward events to observers.</summary> /// <param name="events">IEnumerable or <see cref="IEvent"/></param> protected void processEvents(object events) { // Errors StructList4 <Exception> errors = new StructList4 <Exception>(); if (events is IEnumerable <IEvent> eventsEnumr) { foreach (IEvent e in eventsEnumr) { try { e?.Observer?.Observer?.OnNext(e); } catch (Exception error) { if (errorHandler != null) { errorHandler(this, e, error); } else { errors.Add(error); } } } if (errors.Count > 0) { throw new AggregateException(errors.ToArray()); } } else if (events is IEvent @event) { try { @event.Observer?.Observer?.OnNext(@event); } catch (Exception error) when(errorHandler != null) { errorHandler(this, @event, error); } } }
/// <summary>Flatten to simpler instance.</summary> public IOption Flatten(IOption o) { StructList4 <IToken> tokens = new StructList4 <IToken>(); if (o is IToken t_) { foreach (IToken t in t_.ListTokens(true)) { tokens.AddIfNew(t); } } if (tokens.Count == 0) { return(TokenList.NoTokens); } if (tokens.Count == 1) { return(tokens[0]); } return(new TokenList(tokens.ToArray())); }