
Short Description of the Simutrans code
=======================================

Simutrans is actually quite hierarchical, as it was a learning project for OOP once.

It starts all with karte_t, which holds an array of planquadrat_t (a 2D coordinate), which holds arrays of grund_t (the actual ground, or foundations, tunnel, bridges, highways, water). Each ground holds an objlist, which contains moving objects such as cars, trains and airplanes as well as other objects including buildings and trees. The objects are derived from obj_t and are located in the obj/ folder.

Each stuff can have three periodic calls: for very regularly and fast actions which require exclusive access on the map (moving cars, collision avoidance) there is sync_step, called before every frame. Slower actions like route_finding, way building etc. is done in step(), where the map can change in between slightly. Some objects (most notable trees) require seasonal changes, which are covered by the relatively new action method of check_season();

The program was developed by a single person most of the time, so sometimes the documentation might not be as good as it could be. So if you find something out about a section of code please document it. But other than that, most of Simutrans is quite compartmentalised and separate from other modules. Therefore it is, in my humble opinion, best to just work locally on one issue, and submit a patch. You will get some critical reception in the forum at https://forum.simutrans.com.


How the UI works
----------------

The UI is almost fully separated from the main code. All dialogues are nowadays derived from gui_frame_t and fully object oriented.

If you want to add a new dialogue, derive it from the gui_frame class. Then add components out of the gui/components folder. You will find almost all components there you could need. Scroll bars are best used as scroll panes: the containing component will be clipped and can be drawn as normal.

After initializing a component you have to add it to your dialogue using add_component(). Failing to do so will just not show it. Certain active things like buttons and many more can give a feedback. Use action_listener(this) for them, or query them on closing; you do not need to handle events for them yourself. Comboboxes are more tricky, but you can ignore this for now.

When there is an action (like a mouse click, test input finished by return etc.) and you have called action_listener(this) before, then action_triggered() will be called by the element. It has two parameters, one is a pointer to the element (to find also out which called) and the second the returned value.

For buttons there are two variants of types. The one with _state are the recommended one, as they will keep their latest state.

If you use only components from gui/components, it may be enough to init your dialogue and query them when the dialogue is closed. You do not need to define drawing or action routines. It can be as easy as that. The extended settings are an example for this.

Certain elements have certain spacings. Please use the spacings provided by gui_themes.h which will scale nicely even with different button or font sizes. Avoid fixed numbers without good reasons.


Written Nov. 2011/Feb 2014 by prissi
