Monday 29 June 2015

Efficient and defensive code snippets

It has been said that dequehead's INPC bindable property code snippets are handy, but they produce ugly code. As a seasoned STL user, that saddens him.

Here is an example of offending code:

private float _ChickensPerFox;
public float ChickensPerFox { get { return this._ChickensPerFox; } set { this.SetProperty(ref this._ChickensPerFox, value); } }
Using the snippet the required keystrokes are b p [tab] [tab] "float" [tab] "ChickensPerFox" [tab]. Pretty cheap; normally you'd have to enter the backing field and property names seperately, remembering to capitalise only the property. Even so, some say it is too ugly to live with.

But is it really ugly? Actually I think not. If you are going to use a property instead of a field it is probably because you don't want to use the field even when it is in scope. The leading underscore puts it after the property in auto-complete, whereas a lower-case first letter (the usual convention) makes the field the 'default' choice for auto-complete. Dangerous.

The original inspiration came from Microsoft's C++ Standard Template Library implementation and its almost impenetrable codebase which makes extensive use of this clause on page 20-ish of the working draft specification:

    (3.1) — Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
When I say "extensive" and "impenetrable", I mean it. Check this out
template<class _InIt1,
 class _InIt2,
 class _Pr> inline
_SCL_INSECURE_DEPRECATE
 pair<_InIt1, _InIt2>
  _Mismatch2(_InIt1 _First1, _InIt1 _Last1,
   _InIt2 _First2, _Pr _Pred, false_type)
 { // return [_First1, _Last1)/[_First2, ...) mismatch, unchecked input
 return (_Mismatch(_First1, _Last1,
  _First2, _Pred));
 }
So I feel reasonably comfortable if people have to deal with some private fields that look like _ChickensPerFox, and I am very comfortable that they are less likely to use them by accident.

While he is at it, dequehead decides to share some more snippets

Here's a similar one, but it adds a handler for change notifications. Comes out like this:

private float _HeadsPerChicken;
public float HeadsPerChicken
{
    get { return this._HeadsPerChicken; }
    set
    {
        if (this.SetProperty(ref this._HeadsPerChicken, value))
        {
            System.Diagnostics.Debug.WriteLine("Chickens have {1} heads", value);
        }
    }
}
There is a corresponding pair for Dependency Properties:
public String ChickenName { get { return (String)GetValue(ChickenNameProperty); } set { SetValue(ChickenNameProperty, value); } }
public static readonly DependencyProperty ChickenNameProperty = DependencyProperty.Register("ChickenName", typeof(String), typeof(MainPage), new PropertyMetadata(default(String)));
public String FoxName { get { return (String)GetValue(FoxNameProperty); } set { SetValue(FoxNameProperty, value); } }
public static readonly DependencyProperty FoxNameProperty = DependencyProperty.Register("FoxName", typeof(String), typeof(MainPage), new PropertyMetadata(default(String), (s, e) =>
{
    var d = s as MainPage;
    var new_value = (String)e.NewValue;

    d.Background = new SolidColorBrush(Windows.UI.Colors.Red);
}));

And lastly an observable collection snippet, which comes out like this:

private readonly ObservableCollection<ChickenModel> _ChickenModels = new ObservableCollection<ChickenModel>();
public ObservableCollection<ChickenModel> ChickenModels { get { return _ChickenModels; } }

The snippets are all on GitHub. There are loads of other MVVM snippets in dequehead's arsenal, it's worth asking. If he has what you need he'll tidy it up an post it.

Saturday 27 June 2015

Windows 10 on an RPi? Yes, really. It Just Works.

Windows. On a thirty quid RPi. Come on...

The target hardware, Raspberry Pi 2 from here, with composite output captured thought iGrabber interface (August VGB200, from here):

Interestingly, there is no Windows GUI, you just get this static screen, the only useful function of which seems to be to display the device's IP. The penny is starting to drop...

A very simple UWP app, first running on the desktop as normal...

...then on the RPi. All you do is set the target to ARM, and make the same remote debugger settings as you would for a tablet:

Remote debugging the app on the RPi. The remote debugger is pre-installed on the device, It Just Works.


Well, it's not quite what he would call 'Windows' - there are no windows - but dequehead is seriously impressed. There is some fun to be had here, JFDI.

Friday 19 June 2015

There are no Behaviours in Blend 2015 RC. No prob, you can add them. They don't seem to work, but actually they do.

One (, possibly the only,) major disappointment dequehead found in the new Blend was the lack of behaviours. For him they are pretty much the whole point about using Blend.

Well, one of the whole points, as least. It turns out that you can reference the Blend 2013 Interactivity DLLs from Blend 2015 - I just copied the managed Behaviours SDK folder over from a machine with VS 2013 installed an placed it here:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\

so I could add a reference in a UWP project to this DLL:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\BehaviorsXamlSDKManaged\12.0\References\CommonConfiguration\Neutral\Microsoft.Xaml.Interactivity.dll

The behaviours show up (albeit with ugly names) and you can drag them on to controls as you would expect.

But, you can not drop an Action onto a Trigger, and if you type it in the XAML manually the IDE squiggles it with "Cannot add content to object of type EventTriggerBehavior" (or whatever behaviour you are trying to use). This is accompanied by Designer Death and is entirely inconvenient, but the important thing is that if you run it it works. I repeat, Behaviors (how every you spell it) do work.

Presumably the issues are just bugs in RC which will be fixed for RTM. but dequehead found the issues too annoying to deal with while learning the new Adaptive UI techniques (which really tie in well with Behaviours), so for now he hacked up some custom Triggers and Actions (using IBehavior and IAction from the Interactivity DLL), which don't exhibit the problem (in particular he used a single IAction, instead of an ActionCollection, and a corresponding [ContentProperty(Name = "Action")], this seemed to stop the designer issues for some reason). He will of course attach the code here in due course.

Real-life Android dev in Visual Studio.

Today was a great day for dequehead. After several years of battling with the Android NDK and Eclipse, he has finally got a realistic Android build system working in Visual Studio 2015 RC.

C++ debugging works without any effort and is reasonably fast. Emulators work, as does deployment to a device. There is a nice NativeActivity shell and OpenGL is all set up ready to rock.

The blurb says that iOS builds can be made to work the same way, although obviously the compilation and execution has to happen on OSX (VS ships with a remote debugger and build server thingy, which presumably runs the Xcode build chain). I will blog about that when I try it out.

Very impressive work by the VS people.

Friday 12 June 2015

Compiled binding. Yeah, but converters don't seem to work.

Compiled binding is a nice idea, but dequehead has up to now avoided looking at it because of the fear of nasty behind-the-scenes stuff ('magic') messing with what is already a somewhat mystical subject. But now it is now.

It turns out there is no magic, and nothing to worry about. Except that it doesn't work properly, yet (more on that in a sec).

When you replace a {Binding} with an {x:Bind}, what happens is that the BlahPage.g.cs file gets even more generated code, this time to handle all the operations that are required for the page to be able to perform all the data binding operations that the XAML declares. That point is a bit subtle. Suppose you have a two-way bound TextBox called Fullname on a page. That needs to update is backing store, so an Update_Fullname method is generated for it, like so:

private void Update_Fullname(global::System.String obj, int phase)
{
    if (phase == NOT_PHASED || phase == DATA_CHANGED || phase == 0)
    {
        XamlBindingSetters.Set_Windows_UI_Xaml_Controls_TextBox_Text(this.obj2, (global::System.String)((global::Windows.UI.Xaml.Data.IValueConverter)global::Windows.UI.Xaml.Application.Current.Resources["camelConv"]).Convert(obj, typeof(global::System.String), null, null), null);
    }
}

This nasty looking thing does the same job that an old-style binding would do, except that everything (nearly..) about it is known to the compiler, so there is no need for run-time reflection, hence it is apparantly more efficient. I'd guess much more efficient, but I've not seen any numbers.

Clearly there must be an issue or I would have gone home by now. Yes, there seems to be. As far as I can see it all works fine until you try to use a converter (as in the example above). As you can see the code is looking for an IValueConverter instance called "camelConv" in the app resource dictionary. Well, I can tell you it aint there. I have looked. If you run code like this you get a "WinRT information: Cannot find a resource with the given key." at run-time.

A simple repro example. Lets say you have a UWP app with a single TextBox containing dequehead's name. Here's the code-behind:

public sealed partial class MainPage : Page
{
    public string Fullname { get; set; } = "dequehead"; // dq: nice, init?

    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = this;
    }
}
and the XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <local:CamelConverter x:Key="camelConv"/>
        <Style TargetType="TextBox">
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
    </Grid.Resources>
    <TextBox x:Name="textBox" Text="{Binding Fullname, Mode=TwoWay, Converter={StaticResource camelConv}}"/>
</Grid>
You can see the reference to camelConv in Grid.Resources, and here is its definition:
public class CamelConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var cc = Encoding.UTF8.GetBytes(value as string);
        cc[0] = (Byte)Char.ToUpper((Char)cc[0]); // hack dq
        cc[5] = (Byte)Char.ToUpper((Char)cc[5]);
        return Encoding.UTF8.GetString(cc, 0, cc.Length);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException(); // dq: we'll let this throw for now
    }
}
It just capitalises the 'd' and 'h'. If you paste all that into a fresh UWP project and run it you will see exactly what you might expect - the dequehead in the backing store is displayed as DequeHead in the TextBox. I love converters.

Now let's change it to use compiled binding. The data context is already the MainPage code-behind, so all we need to do is change Binding to x:Bind:

<TextBox x:Name="textBox" Text="{x:Bind Fullname, Mode=TwoWay, Converter={StaticResource camelConv}}"/>
As predicted, barf. So, it appears that converters are broken in compiled binding. What to do?

Well, I wanted a workaround that kept, as far as possible, all the MVVM patterns intact. So I kept the converter instantiation in the XAML, but I decided to do the actual conversion in the view model for now. There are other valid approaches.

First, we need to make the converter visible in code by changing x:Key to x:Name. I like names to start with an upper-case letter (and keys start with a lower-case letter), so I did that as well.

<local:CamelConverter x:Name="CamelConv"/>
Then the auto-property has to be opened up, and the getter does the conversion using the converter, which is now a public property on the page. (Remind me to blog about snippets and the weird backing property name.)
private string _Fullname = "dequehead";
public string Fullname
{
    get { return this.CamelConv.Convert(this._Fullname, typeof(String), null, null) as string; }
    set { this._Fullname = value; }
}
Last we remove the converter from the binding:
<TextBox x:Name="textBox" Text="{x:Bind Fullname, Mode=TwoWay}"/>
If you run that, it will work. You'll also see that the generated update method does not have the dictionary lookup that was causing the problem:
private void Update_Fullname(global::System.String obj, int phase)
{
    if (phase == NOT_PHASED || phase == DATA_CHANGED || phase == 0)
    {
        XamlBindingSetters.Set_Windows_UI_Xaml_Controls_TextBox_Text(this.obj3, obj, null);
    }
}
It is a shame that there is not really an easy global search-and-replace that can convert from this hack to proper converter use when the bug is fixed, if anyone has any ideas please leave a comment.

When wrestling with this issue, dequehead found plenty of quotes like "x:Bind just drops straight in...blah blah...and converters work as before...", but no actual examples of converters used in conjunction with x:Bind. The extensive Windows 10 samples don't appear to have one. If anyone has seen a working example dequehead would like to hear about it. Asidedly, he thinks that the NOT_PHASED constant in the generated code above is worth a blog, at some point.

Tuesday 2 June 2015

WTF is a Type B Confined Space?

While dequehead was joining the front of the queue this morning he noticed this fine warningsemble on an otherwise uninteresting pair of doors:

So let's break it down and see what we can see.

So what is SF6 then? Oh, right. Well that's clear enough. What else do we have...

This one is great. Not a particularly tough looking padlock. But if you do... you might die. Got it. What else?

Gosh, look at this monster. Its all about these warning signs. This is a complex subject, worthy of further study. The interesting thing, to dequehead, is that in his research around the subject he never did find a definition of a Type B Confined Space.