Saturday 28 October 2017

TrafficControl: Protecting the Code With Asserts

Asserts are checking whether a condition is met. If the condition isn't met, the program will throw an error message and break. They are used to ensure that something never ever happens in the program (asserts are only used when debug flag is enabled).

TrafficControl is based on three lists of objects (trainList, trackList and stationList), The elements in those lists are called directly, so the entire logic of the program is based on a direct relation between the ID's of the elements and their position in the lists. Removing elements will not be allowed.

For example: Add three trains to the network. The result is a trainList:
trainList.at(0) has ID: 0
trainList.at(1) has ID: 1
trainList.at(2) has ID: 2
totalNbrOfTrains = 3

Remove the second train and reduce the totalNbrOfTrains:
trainList.at(0) has ID: 0
trainList.at(1) has ID: 2 
totalNbrOfTrains = 2

Now, there is a mismatch between the ID for the second train in the trainList and its position. 

To detect when it happens, I've added an assert that fires if there is such a mismatch for the last items in the lists.
The trainList must always be empty, or its last element' ID must match the length of the list.
If the assert fails, a dialog pops up and the user can decide whether to retry, abort or ignore the error.
The button are using the language specified by the operating system. In this case, they are: Abort, Retry and Ignore.
As a side note, I've discovered two bugs that I need to fix. I'll address the issues in future blog posts:

The program asserts when using a network without coordinates. It happens when the train is running on tracks and is trying to calculate its coordinates.

Solution: Check if the train and track has coordinates when updating the position for a train on the track.

The program is slower when importing network file. Before refactoring it, it took the program 5 seconds to scan the file. Now, it takes 25 seconds.

Solution: Scan all lines and send as a stringlist to new NetworkControl::parseNetworkCommands(QStringList). 

No comments:

Post a Comment