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!