Loksim3D Developer Stories – Part 2 – C++ template magic

In Loksim a rail track can have a lot of associated properties. Properties like maximum speed, signals, illumination characteristics, name, stops and so on, which can be seen in the following screenshot:
props

So far the internal implementation of this system heavily depends on constants. For example, if you want to get the maximum speed on a track ‘t’ at position ‘pos’ you would use a function call similar to this:

auto& propSpeed = t.GetProperty(PROPERTY_MAXIMUM_SPEED, pos);

However, ‘p’ does not contain the actual maximum speed: A maximum speed is not a single value, it e.g. contains information if this maximum speed is different for trains with tilt technology or if it is shown in the timetable of the train operator. So a second query – again using a constant – is needed:

float maxSpeed = propSpeed.GetPropertyFloat(PROPERTY_MAXIMUM_SPEED_NORMAL_TRAIN);

This also shows, that one has to know the data type of the actual property when retrieving it. In fact, at the moment all these properties are stored as strings and converted to the requested type when they are queried by the GetPropertyType functions.

This system has two main advantages:

  • It can be extended quite easily: One just has to introduce a new constant PROPERTY_XXX
  • It can be serialized and deserialized to XML in a straightforward way: The values are just written out using the PROPERTY_XXX constants as attribute names

However, working with this system for some years also showed some disadvantages:

  • There does not exist any static check if the property that is queried really makes sense. E.g. in the example above, one could easily write the line propSpeed.GetPropertyString(PROPERTY_STOP_NAME). The compiler can never recognize this error and you would just get an empty property (string) back
  • It can be hard to find the appropriate constant for a property of a rail track. In fact I often end up checking the name in the GUI, searching for it in GUI resource file, than searching for the resource identifier in the code of the editor. There you find the connection between the constant and the GUI name, since there exists some kind of data binding between the GUI and the properties store
  • There exists no IntelliSense that could help to find the existing properties.
  • The data values are converted when they are retrieved and not stored in the original format

One additional characteristic of the system is, that there exist properties which are the same for both directions (e.g. illumination of the rail track) and other ones which are different depending if you are driving forwards or backwards on the track (e.g. stops and names). So far the developer has to know which properties are valid for both directions and which ones depend on the direction on the track. The GetProperty funktion takes an additional argument which determines if the property for the forward or for the backward direction is retrieved.

In the process of rewriting the system for generation of 3D models for the rail tracks I need to access some of these properties. I decided this would be a good occasion to experiment with a new system for such properties. My main design goals were the following:

  • Design system in a way, that the compiler can check for invalid usage of properties and allow the IDE to offer IntelliSense
  • Available properties and the types of the properties should be represented in some way in the source code
  • Static differentation between properties that are the same in both directions and ones where different properties for both directions exist
  • Values should be stored in a typesafe way and not needed to be converted each time properties are accessed
  • Allow fast access and filtering of properties, which means the property lists should store the properties by value and not allocate space on the heap for each single property

First of all I decided to use structures to store the different types of properties. Since every property has at least a position (relative to the track it is associated with), I created a base class for all different kind of properties:

template <bool TBothDirections>
struct RailProperty
{
	static const bool BothDirections = TBothDirections;

	RailProperty() : RailProperty(0.0f * units::meter) { }
	explicit RailProperty(units::distance_m position) :
		position_(position)
	{
	}

	units::distance_m position_;
};

The template parameter TBothDirections is used to differentiate between properties that are valid for both directions and one where different properties for forward and backward exist.

Each type of property is a subclass of the RailProperty struct. In the following two examplary properties are shown:

struct PropLimit : public RailProperty<true>
{
	PropLimit(units::distance_m position, l3d::units::speed_kph limitNormal = units::speed_kph::from_value(100.0f));
	PropLimit(units::distance_m position, l3d::units::speed_kph limitNormal, l3d::units::speed_kph limitNeigetechnik);

	units::speed_kph limitNormal_;
	units::speed_kph limitNeigetechnik_;
};

struct PropUeberhoehung : public RailProperty<false>
{
	PropUeberhoehung(/* ctor parameters */);

	// Properties
};

So how can these properties now be accessed? The user of the interface accesses them through a RailDescription class, which stores information about one rail. Each type of property is stored in an own custom list class. The lists itself are organized in a map[1], where std::type_index is used as a key. The type_index class is new in C++11, can be constructed from std::type_info (which is returned by the typeid operator) and can be used in (hash) maps.
The RailDescription class contains a Properties() function which provides access to a list of properties of the specified type. Since the type of the property is given as a template parameter, the concrete type of the return value is determined at compile time and can be used by IDEs for IntelliSense.

class RailDescription
{
public:
	/* other stuff */

	template <class Prop>
	railprops::PositionedPropertyList<Prop>& Properties()
	{
		auto& l = propLists_[typeid(Prop)];
		if (l.get() == nullptr) {
			l = std::make_unique<railprops::PositionedPropertyList<Prop>>();
		}
		return static_cast<railprops::PositionedPropertyList<Prop>&>(*l);
	}

private:
	std::map<std::type_index, std::unique_ptr<railprops::PositionedPropertyListBase>> propLists_;
	/* other stuff */
};

So what about the PositionedPropertyList class?

template <class Prop>
class PositionedPropertyList : 
	public std::conditional<Prop::BothDirections, PositionedPropertyListWithDir<Prop>, PositionedPropertyListWithoutDir<Prop>>::type
{
};

This class has only one purpose: If the properties that are stored in the list are handled differently for the two directions, PositionedPropertyList is a subclass of PositionedPropertyListWithDir, otherwise of PositionedPropertyListWithoutDir

The PositionedPropertyListWithDir class is responsible to provide two lists itself: One for the forward and one for the backward direction:

template <class Prop>
class PositionedPropertyListWithDir : public PositionedPropertyListBase
{
public:
	PositionedPropertyListWithDir();

	// forward
	PositionedPropertyListWithoutDir<Prop>& Fwd() { return *forwards_; }
	// backwards
	PositionedPropertyListWithoutDir<Prop>& Bwd() { return *backwards_; }
private:
	std::unique_ptr<PositionedPropertyListWithoutDir<Prop>> forwards_;
	std::unique_ptr<PositionedPropertyListWithoutDir<Prop>> backwards_;
};

The class in which the properties are actually stored is the PositionedPropertyListWithoutDir class:

template <class Prop>
class PositionedPropertyListWithoutDir : public PositionedPropertyListBase
{
public:
	// Property with position_ <= position
	// Returns nullptr if there does not exist such property
	const Prop* At(units::distance_m position) const
	{
		auto it = std::upper_bound(cbegin(orderedProps_), cend(orderedProps_), position);
		if (it != cbegin(orderedProps_)) {
			return &(*(it - 1));
		}
		else {
			return nullptr;
		}
	}

	/* Implementation of functions omitted */
	Prop* At(units::distance_m position);
	Prop& Add(const Prop& v);
	Prop& Emplace(units::distance_m position);		
	template<class... Args>
	Prop& Emplace(units::distance_m position, Args&&... args);
	bool DeleteAt(units::distance_m position);
	
private:
	std::vector<Prop> orderedProps_;
};

In this class the properties are stored in a std::vector and a handful of methods to retrieve, add new and delete properties exist. For some use cases probably more advanced methods to retrieve a range of properties are needed, which are not yet implemented.

In the end, the user can access the properties in the following way:

RailDescription rd;

rd.Properties<PropLimit>().Fwd().Add(PropLimit(10.0f * l3d::units::meter, 100.0f * units::kilometer_per_hour));
rd.Properties<PropLimit>().Fwd().Emplace(50.6f * l3d::units::meter, 100.0f * units::kilometer_per_hour);
auto& p1 = rd.Properties<PropLimit>().Fwd().At(4.0f * l3d::units::meter)

rd.Properties<PropUeberhoehung>().Emplace(100.0f * units::meter, UeberhoehungType::FesterWert, 45.0f * units::degrees);
auto& a = rps.Properties<PropUeberhoehung>().At(100.0f * l3d::units::meter)->angle_;

Everything is type checked at compile time and the IDE can provide full IntelliSense. I always knew that C++ templates are a real nice technique to work with. However, I really had a lot of fun creating this system for storing properties. I still think that it offers a nice interface forusers of this part of the code and can be easily used even by people who do not know anything about the way it is implemented. The main reason for this is, that it is statically typed and therefore prevents a lot of careless mistakes.

So far I did not think a lot about serialization of this new property store. I have a few options in mind, but at the moment I do not need it and writing code that is not needed at the moment is… unnecessary 😉

[1] Accoring to a talk by Chandler Carruth both std::map and std::unordered_map are not really optimal data structures. Maybe I will exchange the usage of std::map with a better map sometime, but this is not really relevant for this post.

This entry was posted in Development and tagged , . Bookmark the permalink.

0 Responses to Loksim3D Developer Stories – Part 2 – C++ template magic

  1. Brucedab says:
    Your comment is awaiting moderation.

    Rich-featured CAD application that enables users to quickly load, visualize and edit all their DWG files, as well as create new drawings from scratch

    Press the “Download Now” button to download DraftSight Cracked Latest.
    The whole process will just take a few moments.

    Mirror Link —> DraftSight license

    – Version: 2019
    – Company: Dassault Systemes
    – Downloads: 2035
    – Download type: safety (no torrent/no viruses)
    – File status: clean (as of last analysis)
    – File size: undefined
    – Price: 0
    – Special requirements: no requirements
    – Home page: 3ds.com/products/draftsight/free-cad-software
    – Rating:

    Tags:
    DraftSight cracked
    DraftSight keygen free download
    DraftSight key crack
    DraftSight crack exe
    DraftSight crack and keygen free download

    More software:
    Flvto Youtube Downloader crack files
    iBackup Viewer crack serial number
    Website 2 APK Builder Pro activator
    Security Eye and crack
    CareUEyes – Free blue Light Filter, screen dimmer serial code
    уникальность текста бесплатно
    Simple-to-make Wild Bird Food for our Northwest Winter
    download google books
    fw14eton4 – Pinstripes

  2. Brucedab says:
    Your comment is awaiting moderation.

    Press the “Download Now” button to download Renee PassNow activator.
    The whole process will just take a few moments.

    Mirror Link —> Renee PassNow patch

    An application designed to help users recover their system login passwords by reseting them to blank, directly from the boot sequence

    · Build: 2017.07.10.104
    · Developer: Rene.E Laboratory Ltd.
    · Downloads: 766
    · Download type: safety (no torrent/no viruses)
    · File status: clean (as of last analysis)
    · File size: undefined
    · Price: free
    · Special requirements: no
    · User rating:

    Tags:
    renee passnow licence keys, renee passnow license, renee passnow crack latest version, renee passnow + crack latest, renee passnow crack latest version, renee passnow crack and keygen free download, renee passnow serial key, renee passnow full crack, renee passnow full patched, renee passnow serial code

    It may be interesting:
    Steganos Tuning PRO serial code
    Sayatoo SubtitleMaker keygen free download
    Easy Screen OCR + Full Crack
    Как обмануть антиплагиат онлайн
    Minutes of meeting in Afyon, Turkey | PEOPLE Project – Grundtvig
    Download Starcraft Full Version With Keys Latest
    download google books
    how to download adult video
    Export Oostenrijkse wijn stagneert door geringe oogst. – OWM
    Готовые Домашние задания 1-11 класс онлайн
    Software Cracks Keygens
    Repair missing or corrupt bass.dll

  3. Brucedab says:
    Your comment is awaiting moderation.

    Press the “Download Now” button to download DBF Viewer 2000 activator.
    The whole process will just take a few moments.

    Mirror Link —> DBF Viewer 2000 crack install

    An efficient and reliable software utility designed to function as a viewer and editor for DBF files (Clipper, dBase, Foxpro, VFP, DB2K)

    · Version: 7.17
    · Company: HiBase Group
    · Downloads: 692
    · Download type: safety (no torrent/no viruses)
    · Status file: clean (as of last analysis)
    · File size: undefined
    · Price: 0
    · Special requirements: no
    · User rating:

    Tags:
    dbf viewer 2000 licence keys, dbf viewer 2000 patch, dbf viewer 2000 crack only, dbf viewer 2000 keygen serial, dbf viewer 2000 with crack, dbf viewer 2000 license crack, dbf viewer 2000 crack only, dbf viewer 2000 full version serial keys latest, dbf viewer 2000 crack and keygen free download, dbf viewer 2000 keygen crack

    Popular software:
    ProtonVPN how to ctack
    OBD Auto Doctor Licence Keys
    Paintstorm Studio crack serial number
    как обмануть антиплагиат?
    Banda gastrica | Dr. Luis Fernando Aguilar Castillejos
    Download Europa Universalis III: Heir to the Throne cracked full
    Convert Google books to PDF, PNG or JPG
    pornhub video downloader
    The Ingraham Angle 8/23/18 | Fox News Today Aug 23, 2018 – ViralHerd
    готовые домашние задания и решебники
    Windows Software Cracks
    Repair missing or corrupt libcrypto-1_1.dll

  4. Brucedab says:
    Your comment is awaiting moderation.

    Click the “Download Now” button to download MagicPicker crack windows.
    The whole process will just take a few moments.

    Aimed at matte and digital painters as well as comic artists and visual arts aficionados, this Photoshop and Illustrator plugin helps you make the most of your color palette

    Mirror Link —> MagicPicker Full Patched

    · Release version: 6.4
    · Patch date: Sep 19th 2018
    · Developer: Anastasiy
    · Downloads: 28001
    · Download type: safety (no torrent/no viruses)
    · File status: clean (as of last analysis)
    · File size: na
    · Price: gratis
    · Special requirements: no
    · Supported systems: Windows 10 64 bit, Windows 10, Windows 8 64 bit, Windows 8, Windows 7 64 bit, Windows 7, Windows Vista 64 bit, Windows Vista, Windows XP
    · User rating:

    Keywords:
    magicpicker license crack, magicpicker cracked, magicpicker full version with keys latest, magicpicker activate code, magicpicker + crack latest, magicpicker license, magicpicker crack patch, magicpicker activator, magicpicker crack fix, magicpicker crack new

    More software: here

  5. Brucedab says:
    Your comment is awaiting moderation.

    Press the “Download Now” button to download ZOOK OST to PST Converter license.
    The process will just take a few moments.

    Convert large numbers of Outlook OST files to the PST format quickly and effortlessly, by using this straightforward piece of software

    MIRROR LINK —> https://serial4download.com/crack/zook-ost-to-pst-converter-24148

    · Build: 4.0
    · Crack date: Jul 22nd 2017
    · Developer: ZOOK Software
    · Downloads: 11315
    · Download type: safety (no torrent/no viruses)
    · Status: clean (as of last analysis)
    · File size: unknown
    · Price: 0
    · Special requirements: no
    · Systems: Win 10 64 bit / Win 10 / Win 8 64 bit / Win 8 / Win 7 64 bit / Win 7 / Win Vista 64 bit / Win Vista / Win XP 64 bit / Win XP
    · Rating:

    Keywords:
    zook ost to pst converter crack serial, zook ost to pst converter license crack, zook ost to pst converter serial key, zook ost to pst converter crack patch, zook ost to pst converter + crack latest, zook ost to pst converter crack serial, zook ost to pst converter full crack, zook ost to pst converter crack latest, zook ost to pst converter crack patch, zook ost to pst converter activate code

    Popular software: https://serial4download.com

  6. Brucedab says:
    Your comment is awaiting moderation.

    Drücken Sie die Schaltfläche “jetzt Herunterladen” zum download FlowJo crack files.
    Der Prozess wird nur ein paar Momente dauern.

    Eine einfache und effiziente software, die Ihnen eine Arbeitsumgebung für zytometrische flussdatenanalysen bietet

    MIRROR —> FlowJo key crack

    · Version: 0.7 Build 53
    · Patch-Datum: Jun 29th 2018
    · Entwickler: Tree Star, Inc
    · Downloads: 21248
    · Download-Typ: Sicherheit (kein torrent/keine Viren)
    · Dateistatus: clean (ab letzter Analyse)
    · Dateigröße: klein
    · Price: gratis
    · Spezielle Anforderungen: Nein
    · Unterstützungssystem: Windows 10 64 bit, Windows 10, Windows 8 64 bit, Windows 8, Windows 7, Windows Vista, Windows XP
    · Benutzer Bewertung:

    Tags Wolke :
    flowjo crack for windows free download, flowjo and crack, flowjo crack install, flowjo cracked latest, flowjo crack exe, flowjo crack patch, flowjo license crack, flowjo crack for windows free download, flowjo keygen free download, flowjo keygen serial

    More keygens: https://serialcrackkeygen.com

    Andere nützliche Ressourcen:
    Антиантиплагиат как работает программа
    Contact Us
    Download Monster Madness: Battle for Suburbia crack keygen for windows
    PointGrid Plugin For Sketch
    tool for downloading Google books
    Vlog 1 – Een nieuw seizoen – Hearts Burning for the unreached
    готовые домашние задания и решебники
    Home – Oakley Builders & Groundwork Contractors Ltd.
    Download activation.dll to fix missing or corrupted DLL errors

Leave a Reply

Your email address will not be published. Required fields are marked *