public ModelUpdateSource(IObservable <EventMessage> messages) { var updating = new BehaviorSubject <bool>(true); mSetIsUpdating = updating.OnNext; mMessages = messages.Publish(); mMessageGroups = mMessages .GateBySequenceNumber(updating, GetMessageSequenceNumber) .GroupBy(msg => msg.EventCase) .Publish(); Modules = GetMessages(ModuleLoaded, msg => msg.ModuleLoaded) .Select(msg => new NewModuleUpdate(msg.ModuleID, msg.Path, msg.AssemblyName)); // Sequence: // - MethodInstrumentationStart // - MethodCallInstrumented (repeated for each call) // - MethodInstrumentationDone // This code extracts these sequences and bundles them into a single method event // containing the method info and all the calls. var whenCallInstrumented = GetMessages(MethodCallInstrumented, msg => msg.MethodCallInstrumented) .Publish().ConnectForEver(); var whenMethodInstrumentationDone = GetMessages(MethodInstrumentationDone, msg => msg.MethodInstrumentationDone.InstrumentedMethodId) .Publish().ConnectForEver(); InstrumentedMethods = GetMessages(MethodInstrumentationStart, msg => msg.MethodInstrumentationStart) .SelectMany(msg => whenCallInstrumented .Where(c => c.InstrumentedMethodId == msg.InstrumentedMethodId) .TakeUntil(whenMethodInstrumentationDone.Where(id => id == msg.InstrumentedMethodId)) .ToList() .Select(calls => new NewInstrumentedMethod( msg.InstrumentedMethodId, msg.ModuleId, msg.FunctionToken, msg.OwningTypeName, msg.Name, calls.Select(c => new NewInstrumentedCall(c.InstrumentationPointId, c.CalledMethodName, c.InstructionOffset))))); ObservableInstances = GetMessages(ObservableCreated, msg => msg.ObservableCreated) .Select(msg => new NewObservableInstance(msg.CreatedEvent.ToModel(), msg.InstrumentationPointId)); ObservableInstanceLinks = GetMessages(ObservablesLinked, msg => msg.ObservablesLinked) .Select(msg => new NewObservableInstanceLink(msg.InputObservableId, msg.OutputObservableId)); CreatedSubscriptions = GetMessages(Subscribe, msg => msg.Subscribe) .Select(msg => new NewSubscription(msg.Event.ToModel(), msg.ObservableId)); DisposedSubscriptions = GetMessages(Unsubscribe, msg => msg.Unsubscribe) .Select(msg => new DisposedSubscription(msg.Event.ToModel(), msg.SubscriptionId)); var onNextEvents = GetMessages(OnNext, msg => msg.OnNext) .Select(msg => new NewStreamEvent(msg.SubscriptionId, StreamEvent.EventKind.OnNext, msg.Event.ToModel(), GetPayloadInfo(msg.Value))); var onCompletedEvents = GetMessages(OnCompleted, msg => msg.OnCompleted) .Select(msg => new NewStreamEvent(msg.SubscriptionId, StreamEvent.EventKind.OnCompleted, msg.Event.ToModel(), null)); var onErrorEvents = GetMessages(OnError, msg => msg.OnError) .Select(msg => new NewStreamEvent(msg.SubscriptionId, StreamEvent.EventKind.OnError, msg.Event.ToModel(), GetPayloadInfo(msg.ExceptionValue))); StreamEvents = new[] { onNextEvents, onCompletedEvents, onErrorEvents }.Merge(); Types = GetMessages(EventMessage.EventOneofCase.Type, msg => msg.Type) .Select(msg => new NewTypeInfo(msg.TypeId, msg.TypeName, msg.PropertyNames)); ObjectPropertiesInfos = GetMessages(ObjectProperties, msg => msg.ObjectProperties) .Select(CreateObjectPropertiesInfo); ClientEvents = GetMessages(EventMessage.EventOneofCase.ClientEvent, msg => msg.ClientEvent) .Select(msg => new Model.ClientEvent(msg.Event.ToModel(), msg.Description)); }