diff --git a/Lawo.EmberPlusSharp/Model/Consumer.cs b/Lawo.EmberPlusSharp/Model/Consumer.cs index e531927d..326ee270 100644 --- a/Lawo.EmberPlusSharp/Model/Consumer.cs +++ b/Lawo.EmberPlusSharp/Model/Consumer.cs @@ -365,7 +365,14 @@ private async Task SendRequestAsync() // Of course, in the latter case the assumption is that the provider will at some point send an // answer to our previous getDirectory request. If it doesn't, the timeout will take care of things. MemoryStream stream; - WriteRequest(this.root, out stream); + + if (!WriteRequest(this.root, out stream)) + { + // If no answer is expected from the provider due to the request, we need to update the request + // state again to see whether there's still something missing. + rootRequestState = this.root.UpdateRequestState(false); + } + await this.client.SendMessageAsync(this.emberDataMessage, stream.ToArray()); } @@ -410,13 +417,13 @@ private void ApplyChange(MessageReceivedEventArgs args) } } - private static void WriteRequest(TRoot root, out MemoryStream stream) + private static bool WriteRequest(TRoot root, out MemoryStream stream) { // TODO: Reuse MemoryStream and EmberWriter for all outgoing messages. using (stream = new MemoryStream()) using (var writer = new EmberWriter(stream)) { - root.WriteRequest(writer); + return root.WriteRequest(writer); } } diff --git a/Lawo.EmberPlusSharp/Model/Element.cs b/Lawo.EmberPlusSharp/Model/Element.cs index b78d0a4e..13184ceb 100644 --- a/Lawo.EmberPlusSharp/Model/Element.cs +++ b/Lawo.EmberPlusSharp/Model/Element.cs @@ -249,11 +249,14 @@ internal virtual RequestState UpdateRequestState(bool throwForMissingRequiredChi /// Writes the payload of a message that contains an appropriate requests for all elements that require /// one. + /// true if a provider response is expected due to the request; otherwise false. + /// /// Recursively visits all children with a state equal to , writes /// a getDirectory command for nodes that do not yet have children or a subscribe command for stream parameters /// and changes their state accordingly. - internal virtual void WriteRequest(EmberWriter writer) + internal virtual bool WriteRequest(EmberWriter writer) { + return false; } internal abstract void WriteChanges(EmberWriter writer, IInvocationCollection invocationCollection); diff --git a/Lawo.EmberPlusSharp/Model/NodeBase.cs b/Lawo.EmberPlusSharp/Model/NodeBase.cs index f7c1d99b..729d3624 100644 --- a/Lawo.EmberPlusSharp/Model/NodeBase.cs +++ b/Lawo.EmberPlusSharp/Model/NodeBase.cs @@ -61,18 +61,24 @@ internal void ReadChild(EmberReader reader, ElementType actualType) this.ReadChild(reader, actualType, reader.AssertAndReadContentsAsInt32()); } - internal void WriteCommandCollection(EmberWriter writer) + internal bool WriteCommandCollection(EmberWriter writer) { if (this.children.Count == 0) { this.WriteCommandCollection(writer, GlowCommandNumber.GetDirectory, RequestState.RequestSent); + return true; } else { + var result = false; + foreach (var child in this.children.Values) { - child.WriteRequest(writer); + // We want to avoid short-circuit logic, which is why we use | rather than ||. + result |= child.WriteRequest(writer); } + + return result; } } @@ -206,7 +212,7 @@ internal sealed override RequestState UpdateRequestState(bool throwForMissingReq return this.RequestState; } - internal override void WriteRequest(EmberWriter writer) + internal override bool WriteRequest(EmberWriter writer) { if (this.RequestState.Equals(RequestState.None)) { @@ -221,13 +227,19 @@ internal override void WriteRequest(EmberWriter writer) GlowQualifiedNode.Children.OuterId, GlowElementCollection.InnerNumber); } - this.WriteCommandCollection(writer); + var result = this.WriteCommandCollection(writer); if (isEmpty) { writer.WriteEndContainer(); writer.WriteEndContainer(); } + + return result; + } + else + { + return false; } } diff --git a/Lawo.EmberPlusSharp/Model/Root.cs b/Lawo.EmberPlusSharp/Model/Root.cs index 9cb79a5a..c2e4563d 100644 --- a/Lawo.EmberPlusSharp/Model/Root.cs +++ b/Lawo.EmberPlusSharp/Model/Root.cs @@ -126,11 +126,12 @@ internal sealed override bool ReadChildrenCore(EmberReader reader) } [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", Justification = "Method is not public, CA bug?")] - internal sealed override void WriteRequest(EmberWriter writer) + internal sealed override bool WriteRequest(EmberWriter writer) { writer.WriteStartApplicationDefinedType(GlowGlobal.Root.OuterId, GlowRootElementCollection.InnerNumber); - this.WriteCommandCollection(writer); + var result = this.WriteCommandCollection(writer); writer.WriteEndContainer(); + return result; } [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", Justification = "Method is not public, CA bug?")]