dev:core:path
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| dev:core:path [2020-04-14 10:48] – created orwell | dev:core:path [2023-01-11 14:13] (current) – [Path generation] Add newline for clearer text 56independent | ||
|---|---|---|---|
| Line 26: | Line 26: | ||
| A train is moved by advancing its index. It is important to note that the train' | A train is moved by advancing its index. It is important to note that the train' | ||
| + | |||
| + | ===== Distances ===== | ||
| + | |||
| + | It is important to keep in mind that the index has little to no relation to actual distances in the cartesian space. Depending on the track orientation, | ||
| + | |||
| + | To calculate an index for a given starting index and a given distance, you can use '' | ||
| + | |||
| + | ===== In train table ===== | ||
| + | The following tables in the train table are handled by the path system: | ||
| + | < | ||
| + | -- path - path positions. ' | ||
| + | -- is the node this item corresponds to, however, this will change in the future. | ||
| + | -- path_node - (reserved) | ||
| + | -- path_cn | ||
| + | -- path_cp | ||
| + | -- When the day comes on that path!=node, these will only be set if this index represents a transition between rail nodes | ||
| + | -- path_dist - The total distance of this path element from path element 0 | ||
| + | -- path_dir | ||
| + | --Variables: | ||
| + | -- path_speed | ||
| + | -- - If 0, the train will stop 0.1 indices before this path item (definable by LZB_ZERO_APPROACH_DIST in trainlogic.lua) | ||
| + | -- path_ext_f/ | ||
| + | -- path_trk_f/ | ||
| + | -- path_req_f/ | ||
| + | </ | ||
| + | |||
| ===== Path generation ===== | ===== Path generation ===== | ||
| + | The path is generated on the fly, as path items are requested. | ||
| + | |||
| + | Every call to '' | ||
| + | |||
| + | In order to access any of the secondary path tables (such as path_speed or path_cn), you need to make sure that '' | ||
| + | |||
| + | The path system deletes path items that are behind the train and no longer needed automatically. | ||
| + | |||
| + | ===== Invalidation and restoration ===== | ||
| + | |||
| + | Whenever the tracks in the world change (e.g. a switch is switched), it is required to update (say ' | ||
| + | |||
| + | //With the '' | ||
| + | |||
| + | A path invalidation clears all path-related tables and variables. They remain cleared until the next call to '' | ||
| + | |||
| + | To restore the path from save files or after a path invalidation, | ||
| + | |||
| + | < | ||
| + | train.last_pos -- the world position of the path item currently at floor(train.index) | ||
| + | train.last_connid = the connid of the track connection pointing forward | ||
| + | train.last_frac = the fractional part of train.index | ||
| + | </ | ||
| + | |||
| + | To restore, train.last_pos becomes path item 0, train.index becomes last_frac, and path generation continues in last_connid direction. This causes an index shift, which also prevents integer overflows. | ||
| + | |||
| + | Note that, to have an estimated rough position of a train, you can simply query '' | ||
| + | |||
| + | A path invalidation can also occur when LZB checkpoints change, see [[dev: | ||
| + | |||
| + | ===== Invalidate Ahead ===== | ||
| + | |||
| + | In order to prevent a complete path recalculation when a far-away rail changes, '' | ||
| + | |||
| + | Obviously, due to the way the path restoration works, this would cause problems when the starting index is behind the train' | ||
| + | |||
| + | '' | ||
| + | |||
| + | In the future, path_invalidate_ahead() is to be preferred over path_invalidate(). | ||
| + | |||
| + | ===== Callbacks ===== | ||
| + | |||
| + | A callback system exists to react to path-related events. Most internal components (e.g. LZB) use these to hook into the path system. | ||
| + | |||
| + | ==== Path callbacks ==== | ||
| + | |||
| + | There' | ||
| + | < | ||
| + | Callback system for 3rd-party path checkers: | ||
| + | advtrains.te_register_on_new_path(func(id, | ||
| + | -- Called when a train' | ||
| + | -- or the saves were just loaded | ||
| + | -- It can be assumed that everything is in the state of when the last run | ||
| + | -- of on_update was made, but all indices are shifted by an unknown amount. | ||
| + | |||
| + | advtrains.te_register_on_update(func(id, | ||
| + | -- Called each step and after a train moved, its length changed or some other event occured | ||
| + | -- The path is unmodified, and train.index and train.end_index can be reliably | ||
| + | -- queried for the new position and length of the train. | ||
| + | -- note that this function might be called multiple times per step, and this | ||
| + | -- function being called does not necessarily mean that something has changed. | ||
| + | -- It is ensured that on_new_path callbacks are executed prior to these callbacks whenever | ||
| + | -- an invalidation or a reload occured. | ||
| + | |||
| + | advtrains.te_register_on_create(func(id, | ||
| + | -- Called right after a train is created, right after the initial new_path callback | ||
| + | advtrains.te_register_on_remove(func(id, | ||
| + | -- Called right before a train is deleted | ||
| + | |||
| + | |||
| + | All callbacks are allowed to save certain values inside the train table, but they must ensure that | ||
| + | those are reinitialized in the on_new_path callback. The on_new_path callback must explicitly | ||
| + | set ALL OF those values to nil or to a new updated value, and must not rely on their existence. | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | < | ||
| + | advtrains.te_register_on_invalidate_ahead(func(id, | ||
| + | </ | ||
| + | |||
| + | ==== Node Callbacks ==== | ||
| + | |||
| + | The node callbacks are driven by a special Path Callback defined in trainlogic.lua: | ||
| + | < | ||
| + | -- enter/ | ||
| + | -- signature is advtrains.tnc_register_on_enter/ | ||
| + | advtrains.tnc_register_on_enter(func(pos, | ||
| + | advtrains.tnc_register_on_leave(func(pos, | ||
| + | |||
| + | -- Node callback for approaching | ||
| + | -- Might be called multiple times, whenever path is recalculated. Also called for the first node the train is standing on, then has_entered is true. | ||
| + | -- signature is function(pos, | ||
| + | -- has_entered: | ||
| + | -- lzbdata: arbitrary data (shared between all callbacks), deleted when LZB is restarted. | ||
| + | -- These callbacks are called in order of distance as train progresses along tracks, so lzbdata can be used to | ||
| + | -- keep track of a train' | ||
| + | advtrains.tnc_register_on_approach(func(pos, | ||
| + | </ | ||
dev/core/path.1586861302.txt.gz · Last modified: by orwell
