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...

Sunday, July 18, 2010

Not dead yet...

Been a while since I've written anything here..
Still working on Signaller as time permits, currently waiting for some tools to catch up, before I start back in.

Also, I found some more IECC pics, this time of Slough
http://photos.signallingnotices.org.uk/photo_index.php?pc=77

Wow, this site is amazing, he really gets all the details! So many good pictures, I had to download about 8000 of them, good thing I got this new 500 gb hard drive, I had about 4000 already in my collection, from all diff sites, but Danny's site is a gold mine!

Monday, November 23, 2009

More Random Pics

Found these lurking in my HD:


Made this to see what Halifax would look like as an IECC ;D
Not my program, I used the SimSig game font (and some photoshop hackjobbery) to mock it up. No claims of accuracy, operational or otherwise is intended ;D

Halifax is a bit odd.  (Link: The one and only online picture of the interior of Halifax signal box) Hard to see the switch panel at the bottom there. Up until September, it was Track Circuit Block controlled, from Greetland (Built in 1942), and Milner Royd Junction (Built in *1878*), despite them both being lever frames.. and Absolute Block (for about 4 miles, then TCB again!) to Mill Lane SB at Bradford. Greetland was closed for several years, then reopened in 2000, and now finally closed in 2009, along with Elland, with control passing to Healey Mills, now TCB to Halifax.
Not much at Halifax any more, compare to 1908:
http://www.flickr.com/photos/thanoz/3241202194/

Something REALLY old:

The experiments a C#, and Signaller. This was before WPF came along. Ugly! though it does show a few glimmers of ideas that would be carried forward. The lists are colour coded for things like speed, lateness, etc, The Departures window showing a customizable list of upcoming station departures, and to the right of that, the Upcoming Train entry list of when and where new trains are expected to enter your control area.

The thing at the top is an 'overview' of the entire system that allowed you to click somewhere and have the main view jump there. It even showed where the main view was on it. Not bad for a first go at both a program and a language...
Few more screenshots to share:

First, the start screen:

(Pic is Ferry Bridge NX Panel
Thanks, Luke! lukebartey1876.fotopic.net)

Nothing revolutionary here,
Just Play or Create :D

The picture is random on startup though...

I especially like how it automatically adjusts to fit the picture, The actual pic was 800x600, but I capped the window size at 640x480, yet it scales nicely.

WPF is great, it allows you to make incredible interfaces!
I was experimenting with this window, and as an experiment made this version:


Moved the buttons on top of the picture, and made them semi-transparent. Again, hardly revolutionary, but it was simple change, that didn't break how it works, just how it looks.




Bet your thinking, "Thats dumb, now the buttons are hard to read!"
well:

Move your mouse over a button, and it becomes opaque, and gets bigger! Kinda contrived, but to do that in something other than WPF would take all day to make, and not be very flexible.
That animation is smooth, and it took 15 mins to make, 10 of which was reading about how to do it :D

What's really powerful is that the text on the buttons could be much longer like (ie German) or even Japanese 終了 (exit)? or Russian? Моделирование (simulation)
the buttons would automatically size to fit. I could put a picture on those buttons with the text. Instead of that big picture, I could also have a video. Or a 3D version of that panel. Or a webcam of a train station, or even a live feed of someone else's screen playing Signaller. Heck I could put videos on the buttons!

Enough of that then.

These are from the next-to-current experimental version. It works, but the organization and structure was terrible, hence ->MVVM


Not much to see, but the Track count works, and the slider is to zoom in and out on the grid.

Right click somewhere and...







Add a new track segment....
The gray bar is shows the orientation of the segment, in this case, to the right.
Click OK when your done, and...











Behold!

The colours are just for editing, the blue and red being the ends new tracks connect, the cyan being where the train describer text will be, Actually they are being drawn twice as wide as they should be, but, um, Yeah, I meant to do it that way!

Now, select a blue or red section to add some more tracks:


and zoom out a bit...
Job done!
er, except for points, signals, trains, stations, timetables.....

Moving these segments around or changing there size doesn't affect the actual size of the simulated track, screens like this are never to scale. The purpose is to show the relationships. Imagine this: (Excuse the ASCII)
-----------\
__________\________

where the dotted line is the track shown in the screenshot above.
If I select all the straight sections, and move them up, the angled section representing the points would adjust itself longer to adapt:

-------\
           \
_________\________

The data representing the points won't change, just the visual display.


This is an  important point, when the visual section gets created, the actual data for what the trains actually run on is created in the background, and is independent of whatever control system I'm looking at. This is psuedo-IECC, which is is mostly a bunch of rectangles, circles, lines and text. (Remember what computer displays were like in the '80's!)  If I want to design NX panels like the one in the start picture up there, the editor will be different, consisting of pre-rendered tiles assembled in a mosiac fashion, but the underlying data is the same. Even if I wanted a 3D virtual representation of a lever frame, it works the same way!

Tuesday, November 10, 2009

The Learning Cliff

Been pounding away at Signaller, trying to re-do it using some semblance of structure, using the MVVM (Model - View - ViewModel) Pattern and Unity, neither which I knew anything about 2 weeks ago, but seem to provide the way forward. Of course, I've never really made a huge application before, so at least I don't have so much to unlearn...

I've made about 4 attempts at making this before, but I fell off the learning cliff.
I don't consider them failures because I tended to concentrate on different areas in each one, which carries forward into the next attempt.

This one so far is far better structured and elegant, and should prove easier to update.

A example:

On sim editor screen, I wanted the Title to display one of two things:

1: Default:
"Simulation Editor - New Simulation"

2: If the sim has a Name:
Simulation Editor - " + SimulationName

Naive Method:
Every time some code changes the SimulationName,

set the Window.Title to a new string, ie
StartScreen.Title = Simulation Editor - " + SimName;

This will work, but has to be inserted EVERYWHERE the name changes, which means that the class must know about the StartScreen instance, even pure data classes. A pain to maintain or change, as now a whole bunch of classes depend on StartScreen existing, and having a property named Title, which takes a string.
If that changes, you have to change the code everywhere, which especially in a team environment, might be a class you have no control of.

2nd Approach, using WPF Data binding (And my first attempt!)
Bind StartScreen directly to the Title property on the Data object, and use a Converter in the code-behind to create the appropriate string. Have the Data object implement INotifyPropertyChanged, and call NotifyPropertyChanged in the Data.SimulationName's setter. When the name changes, the StartScreen's binding recieves the change notification, and changes the title as necessary.
The data object now doesn't need to know (or care) about the Window,
but the Window is still dependent on the Data object, and the binding is a bit funky.




Lucky I have control of the data object, so I could add the NotifyPropertyChanged.
What if I didn't, if it was some old legacy library, that I couldn't edit?


Enter the MVVM pattern.
What it attempts to do is remove the dependencies between the View and the Model, and make your application cleaner, more flexible, easier to change and update, and unit-testable.

Before, I had:
Model: The ModelData object
View: The StartWindow.


Since the two were dependent on each other, a change in one might require a change in the other. If say the Model was dependent on other classes as well, then a change in the View could cause a cascade of changes in many classes, that are completely unrelated to the visual View.


With MVVM it adds a ViewModel in between the two. The ViewModel, is sort of like a super adapter between the two, The View simply binds to properties on the ViewModel ie Title="{Binding StartScreenTitle}. All the view needs is to set the Window.DataContext to the ViewModel. The view can exactly the data it wants in exactly the form it wants, and it doesn't depend on the data model at all.

For the StartScreen, its pretty trivial. As the complexity increases though, MVVM starts to make sense.


But for something like the Editor screen, well, I want to be to be able to create different signalling control systems.
Given a base set of data about tracks\signals, etc. plug that into whatever Visual representation (be it IECC, a mosaic panel, lever frame etc)
If I have a series of modules that provide the visuals etc, something like
SystemIECC.dll, SystemPanel.dll, or something, They would each have data on top of the base data that was only related to the Visual part. The interface for editing the visual portions would all be fairly different.

The naive method (And first thing I thought of! ;D ) was to make a series of Editor Windows, one for each of the Visual types I wanted to use.
That's a lot of duplication, and I'd have to create new windows everytime a new System*.dll is created. It would be possible, but be a complete pain to maintain and update. There would be lots of data that would only be appropriate to a specific signalling control technology, or to put it another way, to the View.
The base data shouldn't have to be changed to support a new module, with stuff that that only applies to specific cases.

Now, what If I have just one Editor window, but inject it with the appropriate VisualModel for the appropriate control system. The ViewModel holds all the View-specific data, and the underlying data Model isn't changed.
 
I've barely scratched the surface of what MVVM and dependecy  injection offers, I'm still trying to get my head around it too!

Saturday, October 3, 2009

The Manifesto!

Been a while since I've been here but I finally have a bit more free time. I've restarted work on Signaller, and I've wrote up a nice document explaining what I'd like to do, my opinions on other simulation products (SimSig, PCRail, etc.) and where I want it to go in the future. It's too long to really post here (4600 words!), so please download it!

Signaller Manifesto.pdf

(You can download it as a PDF\txt\DOC etc.


I'd like to hear your thoughts on this, and get some brainstorming going.
If I've gotten something wrong, I'd also like to know.

Oh, and all the opinions in it, are entirely my own!

Thursday, June 5, 2008

New Screenshots

Been a while since the last post, I've been pounding away, occasionally just pounding.... I've been working on the screens to enter data, each one seems to look and work better as I figure things out. The best one so far is the Signal Data window.


I got really stuck on the Databinding the details to the selected (At the top) signal, but it works great now. If you change the ID, the top combobox updates nicely.

I really like WPF's abilty to have anything on say a button, like that row of coloured circles representing the signal aspects. Especially cool is the last two yellow ones where the circles actually blink, to represent the 'flashing' aspects :)


Here's another signal, that has the Flashing Yellows off, and also the white Position light aspect selected..




Another neat thing is how it can hide various non-applicable sections, and how it resizes to fit everything nicely...