Skip to content

net

LFSLib.NET 0.14b released

UPDATE: If you downloaded the files before 12pm PST, then you may have a binary with a bug. Please get the current one.

This is is a minor bugfix/clean-up release. There were two bugs that were the result of TCP connections. In addition, I took the opportunity to clean up some naming conventions and odds and ends. This should be a non-breaking upgrade, although a couple of members have been marked obsolete and will generate warnings until replaced with their successors.

Full details are in the release notes.

I've added a pure binary release of the lib, so you don't have to do digging through the output folders anymore, if all you want is a dll to reference. The binary release can be found here.

All links, docs, etc are at lfs.fullmotionracing.com

INotifyPropertyChanged and Cross-thread exceptions

I'm currently reading Adam Nathan's WPF Unleashed. It's a good read and has me ready for doing some serious WPF work. However, the things I have on my plate are a already Windows Forms and can't really take a late in the project UI architecture change, so my production use of WPF will have to wait a little longer. I originally thought WPF was horribly over-engineered, but going through Adam's book, the decisions that led to the sometimes odd APIs make sense. It's clear that toolability of Xaml, separation of logic and code and allowing the greatest amount of design without any code are what led to the cumbersome manual C# syntax. But once you mix in Expression Blend, you won't be doing any of those nasty things unless you're writing your own custom controls. Ok, this is a lovely tangent, but hardly the subject of this entry...

While reading I came across INotifyPropertyChanged. Since it's meant for binding in general, I thought this might be a perfect fit for a design issue I was having on a WinForms project. Basically, I have an object that manages a native process and can get manipulated via remoting. The UI in the program really just exists for status updates on this management object. The solution for keeping the UI in sync was either a timer that polled the object's properties or create an event for each property change, manually subscribe to them in the form and update the UI that way. However, INotifyPropertyChanged provided a simple methodology for tracking changes in all objects and let the implementing object be used for data-binding. I'm usually against code that uses strings to reference object members, like data-binding is wont to do, since it falls outside of compile-time checking and is liable to get out of sync in refactoring, but data-binding is convenient and so prevalent in .NET, that I decided to use it for this.

Implementing INotifyPropertyChanged on my object was dead simple and the syntax for binding my labels to property changes was even easier. Perfect, another process simplified. Or so I thought. What happened next is what I personally would describe as a bug or at least mis-feature in data binding, but at least according to the docs, it's by design.

INotifyPropertyChangeddoes not work for asynchronous operations

What happened was this: I made changes to my object via the remoting proxy and my client UI died with an InvalidOperationException(Cross-thread operation not valid...). On it's face this is straight forward: My object is on a background thread, being manipulated by remoting. My UI is on the UI thread, so tweaking the UI by the background thread is a no-no. This is confirmed by the MSDN documentation which says:

If your data source implements the INotifyPropertyChanged and you are performing asynchronous operations you should not make changes to the data source on a background thread. Instead, you should read the data on a background thread and merge the data into a list on the UI thread.

That to me is bad advice and a lazy way of saying that data binding doesn't do its due diligence on binding operations. Why? Well, the purpose of something like INotifyPropertyChanged is Separation of Concerns, decoupling the observer of the property data from the observable object. But what the above says is that the observed object is responsible for knowing how it might be observed.

The logical thing is that your INotifyPropertyChanged object neither knows nor should care that it's data may be used to update the UI on another thread. The party that's responsible for that bit of house-keeping is the one that does the actual updating of the UI controls, i.e. data-binding. Data-binding is intimately aware of the UI object it's tied to and it's the one that isactually updating the UI in response to an incoming event. It seems logical and practical that it would do the necessary check on Control.InvokeRequired and perform said invoke. Instead telling you that your object better live on the UI thread is just not very good advice, imho.

Where does that leave us?

Well, even if the business object wanted to invoke on the UI thread, it couldn't unless it was aware of the UI thread, and that once again violates the Separation of Concerns that should exist between business logic and UI. So that leaves us with two options: a) change the way binding works to the way described above or b) put a proxy between the binding and the INotifyPropertyChanged implementor.

Since you can assign a new BindingContext to a control, a) may be an option, and it's one I'm going to investigate next. However for the time being, going down the path of b) was simpler.

I hardcoded a proxy for my business object, had it implement INotifyPropertyChanged as well and created a factory that would take both the form and the proxied object to create a new proxy. The proxy then subscribed to the proxied PropertyChanged event and used its reference to the form to make sure it was invoked on the UI thread.

{
  [...]
  public int MyProperty
  {
    get { [...] }
  }
  [...]
}

public class MyBusinessObjectProxy : INotifyPropertyChanged
{
  Control bindingControl;
  MyBusinessObject bindingSource;

  private MyBusinessObjectProxy(Control bindingControl, MyBusinessObject bindingSource)
  {
    this.bindingControl = bindingControl;
    this.bindingSource = bindingSource;
    bindingSource.PropertyChanged += new PropertyChangedEventHandler(bindingSource_PropertyChanged);
  }

  void bindingSource_PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
    if (PropertyChanged != null)
    {
      if (bindingControl.InvokeRequired)
      {
        bindingControl.BeginInvoke(new PropertyChangedEventHandler(bindingSource_PropertyChanged), sender, e);
        return;
      }
      PropertyChanged(this, new PropertyChangedEventArgs(e.PropertyName));
    }
  }

  public int MyProperty
  {
    get { return bindingSource.MyProperty; }
  }

  #region INotifyPropertyChanged Members

  public event PropertyChangedEventHandler PropertyChanged;

  #endregion
}

That works beautifully, but since it's specific to my particular object that's a lot of hand-coding. This whole proxy/adapter scheme screams for a generic implementation. But now we need to intercept requests of properties we may not know exist. Back in the perl days (and most dynamic languages feature this as well) I would have just created an AUTOLOAD method that catches all calls to methods that don't exist. It didn't seem like this would exist in C#, since that violates the whole compile time checking of a static language like C#. But there is Reflection, so maybe I was wrong. However, after checking with Oren Eini, who clearly has a much greater understanding of how to do funky things with C#, it turns out that such a facility indeed does not exist.

Next up was creating a proxy object that could be cast to the original type and handle the binding calls that way. I built a prototype based on Castle's Dynamic Proxy, which proxied the properties just fine, but apparently the event subscription doesn't work, because the proxy's PropertyChanged event never acquired any subscribers. So until I can figure out what happens to events on Dynamic Proxy, I'm stuck with statically built proxies.

In the meantime, I guess I'm going to look at BindingContext to see if the problem can be solved generically at that end, while trying to figure out why Dynamic Proxy isn't working. Stay tuned.

LFSLib.NET 0.13b released

Now with full patch X goodness!

This version of LFSLib.NET takes advantage of all the new features of Live For Speed S2 0.5X (as well as the X2 test patch additions). The new version can be found here and the release notes are here. There is a new binary distro with a winforms Tester app, which is located here, but in general the tester app does not provide full coverage and will eventually be replaced with a better example and test harness. The highlights are:

  • TCP connections (more on that below)
  • Multiple InSim Connections at the same time
  • Custom Button system
  • Lots more tracking events

I've run it through its paces, but as InSim coverages is getting quite large now and I don't have an automated test suite, I cannot claim to have full test coverage. In general, if something doesn't work, assume it's LFSLib.NET, not LFS and let me know. Contact me via the email on the left, blog comments or posting about LFSLib.NET on the LFS programmer forums (which I monitor fairly consistently).

Moving the documentation to SandCastle has taken more time than I hoped. The new doc system is now a dynamic web application and provides a (IMHO) much improved interface thanks to Dave Sexton's excellent DocProject. This has required my moving of the docs off this server to a new host, so the docs and future information for LFSLib.NET from now on lives at lfs.fullmotionracing.com.

About TCP & UDP

A quick note about TCP and UDP in 0.13b. You can have up to 8 TCP connections, but you still can only have one UDP connection. When you configure the InSimHandler, set the UseTCP flag in the configuration. In general, you want to make sure that you do NOT set ReplyPort. Why? As soon as you set reply port, LFS will send RaceTrackNodelap (IS_NLP) and RaceTrackMultiCarInfo (IS_MCI) events via that port on UDP. LFSLib.NET handles that transparently, but since you've now crossed over into UDP land, you have now used up that one UDP connection that is available and things will get wonky if you connect another InSimHandler with the same settings, even though you thought you were just using TCP.

Simple OutSim & OutGauge samples

Version 0.13b is finished, just cleaning up the docs, and packaging everything (switching to sandcastle for docs kind of added a new complication). Should have that out tomorrow, I hope.

In the meantime, especially, since the Tester app I include is really just something to exercise the lib, not to learn coding from (i.e. worst winforms code patterns example), I thought i'd throw out some simple code examples until i build a proper test suite. Now, these samples, with their use of straight up static methods are also nothing to learn program design from -- they're just API illustration. These examples work with the current and new release, so they're not tied to 0.13b.

The tricky thing to note about both OutSim and OutGauge is that the cfg.txt values take precedence. I.e. you can get both sent via InSim, but not if they are already set in the configuration file. Generally, I suggest sticking to manually configuring these two and going through the dedicated handlers for both and keeping them separate from your InSim handler.

OutGauge

This little Console app, just subscribes to OutGauge being sent once a second and refreshes the terminal with the new values:

static void Main(string[] args)
{
  // Assumes the following settings in LFS cfg.txt:
  //    OutGauge Mode 1
  //    OutGauge Delay 100
  //    OutGauge IP 127.0.0.1
  //    OutGauge Port 26020
  //    OutGauge ID 1

  OutGaugeHandler outGauge = new OutGaugeHandler(26020);
  outGauge.Updated += new OutGaugeHandler.GaugeEvent(outGauge_Updated);
  Console.WriteLine("created handler");
  outGauge.Initialize();
  Console.WriteLine("initialized handlers");
  Console.WriteLine("Press RETURN to exit");
  Console.ReadLine();
  outGauge.Close();
}

static void outGauge_Updated(object sender, FullMotion.LiveForSpeed.OutGauge.Events.Gauge gauge)
{
  Console.Clear();
  Console.WriteLine("OutGauge -----------------------");
  Console.WriteLine("Time:     {0}", gauge.Time);
  Console.WriteLine("ID:       {0}", gauge.Id);
  Console.WriteLine("Car:      {0}", gauge.Car);
  Console.WriteLine("RPM:      {0}", gauge.RPM);
  Console.WriteLine("Speed:    {0}", gauge.Speed);
  Console.WriteLine("Message1: {0}", gauge.DisplayMessage1);
  Console.WriteLine("Message2: {0}", gauge.DisplayMessage2);
}

OutSim

The OutSim version is virtually the same for setup, just that the eventargs contain different data

static void Main(string[] args)
{
  // Assumes the following settings in LFS cfg.txt:
  //  OutSim Mode 1
  //  OutSim Delay 100
  //  OutSim IP 127.0.0.1
  //  OutSim Port 26010
  //  OutSim ID 1
  OutSimHandler outSim = new OutSimHandler(26010);
  outSim.Updated += new OutSimHandler.PhysicsEvent(outSim_Updated);
  Console.WriteLine("created handlers");
  outSim.Initialize();
  Console.WriteLine("initialized handlers");
  Console.WriteLine("Press RETURN to exit");
  Console.ReadLine();
  outSim.Close();
}

static void outSim_Updated(object sender, FullMotion.LiveForSpeed.OutSim.Events.PhysicsState physicsState)
{
  Console.Clear();
  Console.WriteLine("OutSim -----------------------");
  Console.WriteLine("Time:     {0}", physicsState.Time);
  Console.WriteLine("ID:       {0}", physicsState.Id);
  Console.WriteLine("X:        {0}", physicsState.PositionX);
  Console.WriteLine("Y:        {0}", physicsState.PositionY);
  Console.WriteLine("Z:        {0}", physicsState.PositionZ);
}

Moonlight at Remix 07

Miguel de Icaza just posted a long entry on a Hackathon the mono team did in the last 21 days to get some version of Moonlight ready for Remix 07 and it looks like they succeeded. Further progress information can also be found on the Moonlight site.

Next to the Silverlight 1.1 alpha which exposes the CLR, Moonlight is probably one of my favorite tech project to follow at this time. I don't even run X anywhere anymore, just using linux for servers, so I don't think i'll ever need Moonlight. But its the availability that has me excited. I am personally rooting for a web programming model that doesn't force javascript on you for client side programming, but I don't think Win/MacOS is "cross-platform" enough to establish this as a norm, rather than a specialty plug-in. I hope Moonlight tips the adoption likelihood in Silverlight's favor.

Currently, I'm mostly waiting for a Socket API to make it into Silverlight 1.1. Once that's available, I'm going to make sure that my LFSLib can run under silverlight. This would open the door for some very cool in-brower LFS admin tools. I also have an internal DirectX implementation of the LFS smx and pth formats for rendering top down views. I've been looking at porting that to WPF, since i don't required 3D and just rendering a plane at this point. If I can reduce it further to the Silverlight Xaml subset, I could easily produce a Silverlight equivalent of LFS Spectator. But I'm getting ahead of myself. Right now I just need to get full patch X support out the door for LFSLib.NET. The protocol is complete now, I just need to complete the TCP code, do some doc clean-up and testing.

LFSLib.NET v0.12b (this is a test version)

I've just put v0.12b on the server. This version does bring LFS 0.5X compatibility, but it does not expose the new functionality. The goal of this version is primarily to let 0.11b code work against LFS 0.5X with the least amount of changes (some data just isn't represented the same anymore and caused breaking changes). This version is also ill tested, as I'm not going to go through an exhaustive set of tests until i get full 0.5X feature exposure (yeah, I know, i should be doing this test driven.. But that means a mock LFS or an LFS test harness and I haven't had the patience for that).

So what has changed? Here are the notes:

  • Moved to .NET 2.0 and Visual Studio 2k5
  • Swapped out back-end for dealing with InSim packets to more closely resemble the native LFS formats and removed the intermediate Msg* classes (all internal changes)
  • Finally mostly functional Unicode support for LFS message in and out transfers
  • Updated existing functionality to work against patch X, with some breaking changes in what is available in Events and how that data is represented.
  • Full patch X protocol implemented, just not yet exposed, so new packets don't come across as unknown packets

An extra note on "mostly function Unicode support". Basically for conversion of unicode to LFS encoding, I am using a lookup table from unicode to codepage+byte and there are a couple of LFS specific characters that screw up under Japanese encoding. And split messages have some issues. This will be fixed in 0.13b.

The new version can be found here and the home of the lib is here

How to do Control Flow via Polymorphism

Let's say you have n objects implementing an interface. Call these message, implementing IMessage. Each message may cause a different action when given to another object, the receiver. Sounds like the perfect scenario for Polymorphism. Create a method Handle() for each of the n messages specifying the concrete type in the signature. Now, let's say you receive that message from a MessageFactory and, obviously, that factory hands you the message via the interface. So here's the pseudo code:

public interface IMessage
{
}

public class MessageA : IMessage
{
}

public class MessageB : IMessage
{
}

public class Receiver
{
  public void Handle(MessageA msg)
  {
  }

  public void Handle(MessageB msg)
  {
  }
}

public class MessageFactory
{
  public static IMessage GetMessage()
  {
  }
}

Now, how do you pass this message off to the appropriate Handle() version? You can't just call Handle() with your message because you message is actually an IMessage not the concrete type. I can think of three workarounds and don't like any of them. Is there another way, or is this just a limitation of C#? In the meantime, here are the three ways I can think of solving this:

The Switch

The traditional way, use if/else or switch to examine the incoming object and dispatch it. Just create a method Handle(IMessage msg) and have it dispatch each to the proper Handle(). Traditional, simple. But as n increases it becomes less and less readable and dispatch is now a runtime decision. It could just fail, if you overlooked a concrete class.

The Reflection

At runtime examine the actual type of the message and then inspect your receiver to dynamically invoke the appropriate methods. No worries about maintaining the code or readability. It's just magic... but runtime magic which may yet fail if you overlooked a concrete class.

The Self-Dispatcher

There is probably a named pattern that goes with this approach. It shares some aspects with the Visitor pattern (that's what inspired me actually), but I don't know what this pattern is actually called. The idea is that each message doesn't get passed to the receiver but passes itself. I.e. it calls the appropriate method. For this to work, we add a method to our interface:

public interface IMessage
{
  void Dispatch(Receiver receiver);
}

public class MessageA : IMessage
{
  public void Dispatch(Receiver receiver)
  {
    receiver.Handle(this);
  }
}

This works perfectly. After getting the message from the factory, you just call msg.Dispatch(receiver). Since each message implements its own dispatch for itself, we get compile time checking. Yay. But we basically copy and paste the Dispatch() method into every message class and we can't factor it into a common base-class, because that would break the flow control again. So it achieves the ends I'm after, but I don't like the implementation.

What other options are there?

Generic return values and explicit casting

Came across an artifact with generics that confused me. Let's say you had an interface IFoo:

public interface IFoo
{
  [...]
}

and a class Foothat implements IFoo:

public class Foo : IFoo
{
  [...]
}

then a given method returning IFoo doesn't have to explicitly cast Foo to the interface:

public IFoo Foo()
{
  return new Foo();
}

So, I figured that the same would be true for a generic method returning T with a constraint to IFoo. However, it seems that the constraint is not considered for implicit casting to T. So you have to explicitly cast Foo to IFoo and then cast that to T:

public T Foo<T>() where T : IFoo
{
  return (T)(IFoo)new Foo();
}

That just seems a bit strange to have to do.

ISecurableChannel in TcpChannel not ready on mono

I was just trying to move a remoting service from .NET 2.0 to mono and ran into problems with Interop. The client & server would work fine if running on the same architecture, but fail when crossing architectures. Turns out that the secure portion of TcpChannels isn't completed yet on mono, throwing an AuthenticationException when a Windows client tried to connect to a Linux server. The culprit is ISecurableChannel. To avoid this, simply, don't use the security feature for now (i.e. use at own risk, best on a private net).

To get it working replace

ChannelServices.RegisterChannel(chan, _**true**_);

with

ChannelServices.RegisterChannel(chan, _**false**_);

Silverlight, Moonlight and a true VM for your browser

Considering my previous rant about RIA platforms, I'm a bit slow out the gate with my Silverlight comments. But there was a lot to digest before making half-baked comments.

While I was at MEDC, Mix07 was going on next door. I didn't even hear the cool Silverlight announcements until I got back from Vegas. But now that i've played with it, it's exactly what I had hoped for (minus a disconnected use model): We have a true VM to code against on the client side. That means the full breadth of .NET languages to control the reduced WPF presentation layer, plus with the DLR true scripting support at near-compiled performance.

As I expected, there was no linux support announced by MS and neither does it appear that they've opened a channel to the mono team. But Miguel de Icaza has addressed this issue independently with the Moonlight project and listening to the chatter on the dev list and following the wiki updates, that project is getting serious attention. I may even be better this way. I think a firefox plug-in coming from the mono team would be more willingly installed by linux users than something coming directly from MS.

We'll have to see how much more of the WPF set of Xaml gets supported by Silverlight as 1.1 moves to beta and RTM. Obviously, the way custom controls are done is not ideal right now--the way properties are acting against implementationRoot (haven't gotten deep enough to understand why it's not using the DependencyObject/Property pattern) and the shadowing of inherited properties just make for a strange experience compared to Controls in WPF, Windows Forms or even ASP.NET. Hopefully that morphs into a better model as we move along. If nothing else, the development of the promised suite of UI controls provide internal motivation to refine the model. Not that I think that DependencyObject/Property is an elegant coding pattern (at least not until that legwork moves into code generation).

But while everyone is busy committing the same UI crimes that many Flash developers have been guilty of for years, I think the real significance of Silverlight is not it's Xaml and rich media support. In my opinion the most amazing feat of Silverlight is its DOM interoperation. The Silverlight VM is accessible in both directions, complete with object serialization across boundaries. This means you can have managed code attached to DOM events, and managed code modifying the DOM itself or calling javascript in the page. With a minimum of glue, you could move all your code inside of Silverlight and even if you don't care about C# et al., you'd at least get a much higher performance javascript out of the deal. Then add the rich communications infrastructure and the hinted at socket level networking in future versions and suddenly you can have very fast, very interactive web applications that could be truly stateful and have better event handling for asynchronous operation etc.

Right now, you need some 1x1 pixel Silverlight object that everything gets channeled through, but MS has already promised that that dependency is going away. So what you really have is a VM and rich framework addressable with bytecode compiled from a huge number of potential languages in the browser. Whether you use that VM to drive your HTML, Silverlight's presentation layer or even the canvas tag is up to you. It's what I hoped that the browser manufacturers would do themselves, but as a plug-in, the chance of this capability becoming ubiquitous is even better, imho.

Silverlight 1.1 alpha is clearly a very early peek into the tech, but it works just great already. I'm curious what it will look like by the time it's an official release. And I certainly hope that by that time, MS has given the disconnected, self-hosted option some consideration. After all, when competing with Flash/Flex, one shouldn't ignore Apollo.