News:

Simutrans Wiki Manual
The official on-line manual for Simutrans. Read and contribute.

Incorrect maximum in-transit with cross linking enabled (RC120 - r7312)

Started by DrSuperGood, September 09, 2014, 02:04:07 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

DrSuperGood

The loading logic for factories when cross-linking is enabled is incorrect. It is meant to add each factory to all consumers as it loads but instead it adds all producers to each factory. Since the maximum output storage value has not yet been computed for some factories, which is needed for the maximum in-transit calculation, the result is nonsense in-transit amounts (1 unit per factory).

Some factories appear to work normally since when loading progresses more industries have correct output storage amounts so will produce correct maximum in-transit amounts.

void fabrik_t::add_supplier(koord ziel)
This function adds the target (ziel) as a supplier for this.

void fabrik_t::add_lieferziel(koord ziel)
This function adds this as a supplier for the target (ziel).

void fabrik_t::add_all_suppliers()
This function adds all factories as a supplier for this.

void fabrik_t::laden_abschliessen()
Uses void fabrik_t::add_all_suppliers() to add all factories as suppliers to this. However this is illegal since other factories may have not yet been initialized so will result in order dependent behaviour that is just plain wrong.

It is not possible to fix this just by changing void fabrik_t::add_all_suppliers() since that is behaving as intended and used by various tools when cross connecting is enabled. When making a factory it is used to add all suppliers to it which will work perfectly as they are all initialized after loading.

The solution is either another function or simply...

What is there now.

void fabrik_t::laden_abschliessen()
{
...
// now we have a valid storage limit
if (welt->get_settings().is_crossconnect_factories()) {
add_all_suppliers();
}
else {
...
}
}


Could be made...

void fabrik_t::laden_abschliessen()
{
...
// now we have a valid storage limit
if (welt->get_settings().is_crossconnect_factories()) {
FOR(slist_tpl<fabrik_t*>, const fab, welt->get_fab_list()) {
fab->add_supplier(this);
}
}
else {
....
}
}


That particular overload of add supplier does all the checking if the factory has any appropriate goods so it does work. I tested it and it resolves the maximum in-transit issue that is present on the one server.

Looking at the cross connect code there is a performance concern that loading becomes O(n^2) where n is the number of factories on the map. Although cross connect will always have that order there is no reason why it should be related to all industries on the map and instead could be reduced to at least relevant industries (which will make n smaller so considerably faster). For possible future work I would advise adding separate lists for certain good types which can be built at load time yet make connecting considerably faster (no tests if a factory has the goods, no processing of factories that do not have the goods). The memory overhead of such pointer lists should be minimal (pointers used is the sum of all inputs for all factories which would only exceed 1000 odd for quite well developed maps). Possibly separate lists for inputs and outputs could be made.

prissi

Thank you, I added your fix. Most player do not your the crossconnect feature it seems.

DrSuperGood

QuoteMost player do not your the crossconnect feature it seems.
Yeh, it is not that fun sadly but still people do use it so its best it works! I will advise he updates to the coming nightly.