Skip to content

Commit

Permalink
Add example code on how to react to changes with the dynamic interface
Browse files Browse the repository at this point in the history
References #18
  • Loading branch information
andreashuber-lawo committed Mar 17, 2016
1 parent 0d403e7 commit 867cf5e
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,37 @@
<codeEntityReference qualifyHint="true">P:Lawo.EmberPlusSharp.Model.IParameter.Value</codeEntityReference>
(or one of its strongly typed variants) is modified locally.
</para>
<para>
In a generic application like e.g. a viewer it would be straightforward to subscribe to
<codeEntityReference>E:System.ComponentModel.INotifyPropertyChanged.PropertyChanged</codeEntityReference>. In
the code below however, for demonstration purposes we're going to subscribe to event of a specific parameter.
As mentioned earlier, the dynamic interface is not very well suited for tasks that make assumptions about the
contents of the database:
</para>
<code source="..\Lawo.EmberPlusSharpTest\Model\TutorialTest.cs" region="Dynamic React to Changes" language="c#"/>
<para>Specifically, the code above has the following problems:</para>
<list class="bullet">
<listItem>
<para>
No attempt is made to handle exceptions that might result from incorrect assumptions. Such exceptions
could be thrown when an expected element is not present (e.g. the parameter is named
<codeInline>Pos</codeInline> rather than <codeInline>Position</codeInline>), the actual element has a
different type (e.g. <codeInline>Position</codeInline> is of type
<codeEntityReference>T:Lawo.EmberPlusSharp.Model.INode</codeEntityReference> rather than
<codeEntityReference>T:Lawo.EmberPlusSharp.Model.IParameter</codeEntityReference>) or
<codeInline>Position</codeInline> is really a <codeInline>double</codeInline> rather than a
<codeInline>long</codeInline>. Robust code would have to handle these exceptions which would make the
process even more tedious than it already is.
</para>
</listItem>
<listItem>
<para>
The interface offers no way of getting an element by name. The code above has to use
<application>LINQ</application> to search for the desired elements, which is cumbersome and inefficient.
</para>
</listItem>
</list>
<para>We will see later how the static interface is a much better fit for this scenario.</para>
</content>
</section>
<section address="CollectionChanges">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,17 @@
<para>
As you might expect, modifying a value is as easy as setting the
<codeEntityReference qualifyHint="true">P:Lawo.EmberPlusSharp.Model.IParameter.Value</codeEntityReference>
property. In a generic application like e.g. a viewer it would be straightforward to do so. In the code below
however, for demonstration purposes we're going to set two specific parameters. As mentioned earlier, the
dynamic interface is not very well suited for tasks that make assumptions about the contents of the database:
property. However, as we've already seen on <link xlink:href="7cdb703a-14dd-42d3-8ea2-28a9b8af6663"/>, getting
to specific elements is rather cumbersome:
</para>
<code source="..\Lawo.EmberPlusSharpTest\Model\TutorialTest.cs" region="Dynamic Modify" language="c#"/>
<para>Specifically, the code above has the following problems:</para>
<list class="bullet">
<listItem>
<para>
No attempt is made to handle exceptions that might result from incorrect assumptions. Such exceptions
could be thrown when an expected element is not present (e.g. the parameter is named
<codeInline>dBValue</codeInline> rather than <codeInline>dB Value</codeInline>), the actual element has a
different type (e.g. <codeInline>Position</codeInline> is of type
<codeEntityReference>T:Lawo.EmberPlusSharp.Model.INode</codeEntityReference> rather than
<codeEntityReference>T:Lawo.EmberPlusSharp.Model.IParameter</codeEntityReference>) or
<codeInline>dB Value</codeInline> is really a <codeInline>long</codeInline> rather than a
<codeInline>double</codeInline>. Robust code would have to handle these exceptions which would make the
process even more tedious than it already is.
</para>
</listItem>
<listItem>
<para>
The interface offers no way of getting an element by name. The code above has to use
<application>LINQ</application> to search for the desired elements, which is cumbersome and inefficient.
</para>
</listItem>
</list>
<para>We will see later how the static interface is a much better fit for this scenario.</para>
<alert class="note">
<para>
As soon as a parameter is modified locally, provider changes are no longer applied to the parameter until
the
As soon as a parameter is modified locally, provider changes are no longer applied to the parameter until the
<codeEntityReference qualifyHint="true">P:Lawo.EmberPlusSharp.Model.Consumer`1.AutoSendInterval</codeEntityReference>
has elapsed or
<codeEntityReference qualifyHint="true">M:Lawo.EmberPlusSharp.Model.Consumer`1.SendAsync</codeEntityReference> is
called.
<codeEntityReference qualifyHint="true">M:Lawo.EmberPlusSharp.Model.Consumer`1.SendAsync</codeEntityReference>
is called.
</para>
</alert>
<para>Proceed to <link xlink:href="df1c42d3-bc00-4786-88d6-2372b281043a"/>.</para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<codeEntityReference qualifyHint="true">E:System.ComponentModel.INotifyPropertyChanged.PropertyChanged</codeEntityReference>.
We can use this event as follows:
</para>
<code source="..\Lawo.EmberPlusSharpTest\Model\TutorialTest.cs" region="React to Changes" language="c#"/>
<code source="..\Lawo.EmberPlusSharpTest\Model\TutorialTest.cs" region="Static React to Changes" language="c#"/>
<para>
We can test this by running the above program and then modfiying a value of the parameter in
<application>Tiny Ember+</application>.
Expand Down
36 changes: 33 additions & 3 deletions Lawo.EmberPlusSharpTest/Model/TutorialTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,36 @@ public void DynamicIterateTest()
#endregion
}

/// <summary>Demonstrates how to react to changes with the dynamic interface.</summary>
[TestMethod]
[TestCategory("Manual")]
public void DynamicReactToChangesTest()
{
#region Dynamic React to Changes
AsyncPump.Run(
async () =>
{
using (var client = await ConnectAsync("localhost", 9000))
using (var consumer = await Consumer<MyRoot>.CreateAsync(client))
{
INode root = consumer.Root;

// Navigate to the parameter we're interested in.
var sapphire = (INode)root.Children.Where(c => c.Identifier == "Sapphire").First();
var sources = (INode)sapphire.Children.Where(c => c.Identifier == "Sources").First();
var fpgm1 = (INode)sources.Children.Where(c => c.Identifier == "FPGM 1").First();
var fader = (INode)fpgm1.Children.Where(c => c.Identifier == "Fader").First();
var positionParameter = fader.Children.Where(c => c.Identifier == "Position").First();

var valueChanged = new TaskCompletionSource<string>();
positionParameter.PropertyChanged += (s, e) => valueChanged.SetResult(((IElement)s).GetPath());
Console.WriteLine("Waiting for the parameter to change...");
Console.WriteLine("A value of the element with the path {0} has been changed.", await valueChanged.Task);
}
});
#endregion
}

/// <summary>Modifies parameters in the dynamic local database.</summary>
[TestMethod]
[TestCategory("Manual")]
Expand Down Expand Up @@ -127,12 +157,12 @@ public void StaticIterateTest()
#endregion
}

/// <summary>Demonstrates how to react to changes.</summary>
/// <summary>Demonstrates how to react to changes with the static interface.</summary>
[TestMethod]
[TestCategory("Manual")]
public void ReactToChangesTest()
public void StaticReactToChangesTest()
{
#region React to Changes
#region Static React to Changes
AsyncPump.Run(
async () =>
{
Expand Down

0 comments on commit 867cf5e

Please sign in to comment.