Sunday, September 12, 2010

Can I claim Signaller as a medical expense?

Still not dead, though there were a few days that I've blocked out, details below :P



The current Signaller version is something like the 7th (sort of) total rewrite.

  • 1st version: more experiment with C#, WinForms, ugly!
  • 2nd Version: Discovered WPF! The only thing uglier than my first WPF stuff was my code :D
  • 3rd Version: Looked around for info on program organization\design, saw something called MVVM (Model-View-Viewmodel). Tried to change 2nd version to some sort of MVVM, created a Program So Horrible, it destroyed several city blocks before being locked away.
  • 4th Version: MVVM from the start, nothing very complex. I was trying more or less to go by Jason Dolinger's awesome MVVM video This one was semi-decent, ie if you read it, you would only go blind after an hour so.
  • 5th Version: Found a great MVVM framework called Cinch. I tried gradually modifying v4 to gradually use Cinch, but it was kinda weird.
  • 6th  Version: Start from scratch using Cinch. The best version by far, it worked fairly well, and the code was fairly clean. I still had various things in it from previous versions because either Cinch didn't cover them, or I was doing it wrong :D
  •  7th Version: Started again with New and Improved Cinch V2! (Now with 100% more MEFedMVVM goodness!) This is the current version, and It's finally looking like I might know what I'm doing :D Of course much of this has to do with Cinch and MEFedMVVM. Thanks to Sacha Barber and Marlon Grech...
I also had the most annoying "bug" I have EVER encountered.
One of the things I want to do is have all the details for a particular signal control system ie How to display it, interact with it, editor etc. all contained in single .DLL file. This would make it easy to add new systems, as well as abstract the details and not be tied to one system.
One of the first challenges I faced was how to get metadata out of the DLL (Name, description, sample pictures, etc) so a user can decide which one to use. After researching, I found there wasn't really a simple way to do it, and most of the solutions I found were slightly funky. Eventually I used a simple XML file, and read that into the program. Not what I wanted, but good enough, and XML is surprisingly easy to use in .net. I liked this part:

List SystemInfoFiles = Directory.GetFiles(SignalSystemPath, "*.*", SearchOption.AllDirectories).Where(filename => Regex.Match(filename, @"\.xml$",
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase).Success).ToList();


What would normally be a bunch of nested loops turned into a single elegant expression.
I love LINQ. (LINQ is sort of like a SQL queries, but built in to .net and you can use the same functions to do queries on normal .net objects, XML, databases or anything else :D)

I'd like to be able for users of Signaller to write there own queries using LINQ syntax or some sort of user-friendly query builder, so you can query stuff out of the program data.

Examples:

Add sticky notes on the sims screen, with a query like:
(TrainID, Platform, Time)[10] where Station=ThisStation
would fill the note with the next 10 departures from a particulat station, which would update by itself.

(TrainID, Time)[1] where EntryPoint=YardX  would show the Next train to enter from a particular location.

All the information layers it can display will be using these kind of things.

If I want to hightlight the track that is say is 3rd Rail, I would have something like this of the top of my head code:

List 3rdRailSegments = from TrackSegment in TrackSegments 
                                                             where TrackSegment.Power = Power.ThirdRail
foreach TrackSegment in 3rdRailSegments
{
   TrackSegment,Background = Blue;
}

Cool, says I.


Work on v7 stopped for several days, due to the most annoying "bug" I've ever had...
As I metioned above, I have seperate DLL's for every system I want to model, that have some metadata I can read out of. When I first tried this, I could not get it to import the info from the dll. Nothing worked. Checked and rechecked my very simplistic code to follow exactly the examples. Still nothing. I would spend several hours trying different things, Nothing had any effect. Would quit in disgust... Read and reread the docs. It should be working. Posted to some boards, changed some more things, still nothing.

I had a ISignalSystem, with ISignalSystemMetadata attached to it.
My program was looking for an ISignalSystem, with ISignalSystemMetadata.
No matter what I did, it steadfastly refused to believe it existed...

While making a new separate testing project to isolate this stuff so I could debug it I realized why it was broken.

The dll is a separate project in my solution. I built the 1st one with no metadata, and copied it to the bin dir of the main project. Later when I added the metadata and created the new dll, I never copied it over, nor did I have Visual Studio copy it automatically.

Fixed that, and it worked perfectly.

5 days, much aggravation, but man, did it feel good when I finally saw it import the 1st time :D

It wasn't totally wasted, though, I learned a lot about how MEFedMVVM, Cinch and MEF worked. Same thing on the previous 6 iterations, every one has neat little bits of code that make the next version that much better...

Anyway, back to the trenches I go...

No comments: