* Predict the next order the vehicle will execute and resolve conditionals by * recursion and return next non-conditional order in list. * @param cur Current order being evaluated. * @param next Next order to be evaluated. * @param flags RefreshFlags to give hints about the previous link and state carried over from that. * @param num_hops Number of hops already taken by recursive calls to thi
| 139 | * @return new next Order. |
| 140 | */ |
| 141 | VehicleOrderID LinkRefresher::PredictNextOrder(VehicleOrderID cur, VehicleOrderID next, RefreshFlags flags, uint num_hops) |
| 142 | { |
| 143 | assert(this->vehicle->orders != nullptr); |
| 144 | const OrderList &orderlist = *this->vehicle->orders; |
| 145 | auto orders = orderlist.GetOrders(); |
| 146 | |
| 147 | /* next is good if it's either nullptr (then the caller will stop the |
| 148 | * evaluation) or if it's not conditional and the caller allows it to be |
| 149 | * chosen (by setting RefreshFlag::UseNext). */ |
| 150 | while (next < orderlist.GetNumOrders() && (!flags.Test(RefreshFlag::UseNext) || orders[next].IsType(OT_CONDITIONAL))) { |
| 151 | |
| 152 | /* After the first step any further non-conditional order is good, |
| 153 | * regardless of previous RefreshFlag::UseNext settings. The case of cur and next or |
| 154 | * their respective stations being equal is handled elsewhere. */ |
| 155 | flags.Set(RefreshFlag::UseNext); |
| 156 | |
| 157 | if (orders[next].IsType(OT_CONDITIONAL)) { |
| 158 | VehicleOrderID skip_to = orderlist.GetNextDecisionNode(orders[next].GetConditionSkipToOrder(), num_hops); |
| 159 | if (skip_to != INVALID_VEH_ORDER_ID && num_hops < orderlist.GetNumOrders()) { |
| 160 | /* Make copies of capacity tracking lists. There is potential |
| 161 | * for optimization here: If the vehicle never refits we don't |
| 162 | * need to copy anything. Also, if we've seen the branched link |
| 163 | * before we don't need to branch at all. */ |
| 164 | LinkRefresher branch(*this); |
| 165 | branch.RefreshLinks(cur, skip_to, flags, num_hops + 1); |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | /* Reassign next with the following stop. This can be a station or a |
| 170 | * depot.*/ |
| 171 | next = orderlist.GetNextDecisionNode(orderlist.GetNext(next), num_hops++); |
| 172 | } |
| 173 | return next; |
| 174 | } |
| 175 | |
| 176 | /** |
| 177 | * Refresh link stats for the given pair of orders. |
no test coverage detected