Go to the documentation of this file.
72 static const StringID _start_replace_dropdown[] = {
73 STR_REPLACE_VEHICLES_NOW,
74 STR_REPLACE_VEHICLES_WHEN_OLD,
107 if ((rvi->railveh_type ==
RAILVEH_WAGON) == show_engines)
return false;
111 if (rvi->
railtype != this->sel_railtype)
return false;
118 for (
const auto &item : source) {
119 if (item.variant_id !=
parent || item.engine_id ==
parent)
continue;
132 AddChildren(source, target, item.engine_id, indent + 1, side);
143 std::vector<EngineID> variants;
146 byte side = draw_left ? 0 : 1;
161 if (e->u.road.
roadtype != this->sel_roadtype)
continue;
183 if (eid == this->sel_engine[side]) selected_engine = eid;
188 for (
const auto &variant : variants) {
189 if (std::find(list.begin(), list.end(), variant) == list.end()) {
196 this->sel_engine[side] = selected_engine;
204 this->engines[side].clear();
208 this->engines[side].swap(list);
217 if (this->engines[0].NeedRebuild()) {
220 this->vscroll[0]->
SetCount((uint)this->engines[0].size());
221 if (this->reset_sel_engine && this->sel_engine[0] ==
INVALID_ENGINE && this->engines[0].size() != 0) {
222 this->sel_engine[0] = this->engines[0][0].engine_id;
226 if (this->engines[1].NeedRebuild() || e != this->sel_engine[0]) {
230 this->engines[1].clear();
233 if (this->reset_sel_engine && this->sel_engine[0] !=
INVALID_ENGINE) {
240 this->vscroll[1]->
SetCount((uint)this->engines[1].size());
241 if (this->reset_sel_engine && this->sel_engine[1] !=
INVALID_ENGINE) {
243 for (
const auto &item : this->engines[1]) {
244 if (item.engine_id == this->sel_engine[1])
break;
254 this->reset_sel_engine =
false;
263 EngineID veh_from = this->sel_engine[0];
264 EngineID veh_to = this->sel_engine[1];
273 this->replace_engines =
true;
276 this->reset_sel_engine =
true;
277 this->details_height = ((vehicletype ==
VEH_TRAIN) ? 10 : 9);
287 widget->
widget_data = STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN + vehicletype;
288 widget->
tool_tip = STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP + vehicletype;
289 widget->
SetLowered(this->show_hidden_engines);
294 widget->
tool_tip = STR_REPLACE_HELP_RAILTYPE + vehicletype;
300 this->sel_group = id_g;
309 d.height += padding.height;
317 size->height = (this->window_number <=
VEH_ROAD ? 8 : 4) *
resize->height;
331 d.width += padding.width;
332 d.height += padding.height;
340 d.width += padding.width;
341 d.height += padding.height;
349 d.width += padding.width;
350 d.height += padding.height;
362 if (rti->
label == 0)
continue;
371 if (rti->
label == 0)
continue;
376 default: NOT_REACHED();
378 d.width += padding.width;
379 d.height += padding.height;
389 d.width += padding.width;
390 d.height += padding.height;
401 SetDParam(0, STR_REPLACE_VEHICLE_TRAIN + this->window_number);
402 switch (this->sel_group) {
404 SetDParam(1, STR_GROUP_ALL_TRAINS + this->window_number);
408 SetDParam(1, STR_GROUP_DEFAULT_TRAINS + this->window_number);
432 SetDParam(0, STR_GROUP_DEFAULT_TRAINS + this->window_number);
434 SetDParam(2, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
439 SetDParam(0, this->replace_engines ? STR_REPLACE_ENGINES : STR_REPLACE_WAGONS);
456 str = STR_REPLACE_NOT_REPLACING;
458 bool when_old =
false;
460 str = when_old ? STR_REPLACE_REPLACING_WHEN_OLD : STR_ENGINE_NAME;
464 str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED;
475 EngineID end =
static_cast<EngineID>(std::min<size_t>(this->vscroll[side]->GetCapacity() + start, this->engines[side].size()));
478 DrawEngineList((
VehicleType)this->window_number, r, this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
486 if (this->engines[0].NeedRebuild() || this->engines[1].NeedRebuild()) this->GenerateLists();
501 switch (this->window_number) {
517 if (!this->IsShaded()) {
518 int needed_height = this->details_height;
520 for (
int side = 0; side < 2; side++) {
526 ted.FillDefaultCapacities(e);
534 if (needed_height != this->details_height) {
535 this->details_height = needed_height;
546 this->descending_sort_order ^=
true;
553 this->show_hidden_engines ^=
true;
556 this->SetWidgetLoweredState(widget, this->show_hidden_engines);
573 switch (this->window_number) {
596 if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
598 ReplaceClick_StartReplace(
false);
607 EngineID veh_from = this->sel_engine[0];
621 size_t engine_count = this->engines[click_side].size();
624 if (i < engine_count) {
625 const auto &item = this->engines[click_side][i];
649 if (e == this->sel_engine[click_side])
break;
650 this->sel_engine[click_side] = e;
651 if (click_side == 0) {
653 this->reset_sel_engine =
true;
665 if (this->sort_criteria != index) {
666 this->sort_criteria = index;
674 switch (this->window_number) {
677 if (temp == sel_railtype)
return;
684 if (temp == sel_roadtype)
return;
689 default: NOT_REACHED();
698 this->reset_sel_engine =
true;
703 this->replace_engines = index != 0;
705 this->reset_sel_engine =
true;
711 this->ReplaceClick_StartReplace(index != 0);
722 params[0] = STR_REPLACE_REMOVE_WAGON_HELP;
723 GuiShowTooltips(
this, STR_REPLACE_REMOVE_WAGON_GROUP_HELP, 1, params, close_cond);
725 GuiShowTooltips(
this, STR_REPLACE_REMOVE_WAGON_HELP, 0,
nullptr, close_cond);
752 static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
762 NWidget(
WWT_LABEL, COLOUR_GREY),
SetDataTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP),
SetFill(1, 1),
SetMinimalSize(0, 12),
SetResize(1, 0),
765 NWidget(
WWT_LABEL, COLOUR_GREY),
SetDataTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP),
SetFill(1, 1),
SetMinimalSize(0, 12),
SetResize(1, 0),
771 NWidget(
WWT_DROPDOWN, COLOUR_GREY,
WID_RV_RAIL_ROAD_TYPE_DROPDOWN),
SetMinimalSize(136, 12),
SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE),
SetFill(1, 0),
SetResize(1, 0),
788 NWidget(
WWT_MATRIX, COLOUR_GREY,
WID_RV_LEFT_MATRIX),
SetMinimalSize(216, 0),
SetFill(1, 1),
SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY),
SetResize(1, 1),
SetScrollbar(
WID_RV_LEFT_SCROLLBAR),
790 NWidget(
WWT_MATRIX, COLOUR_GREY,
WID_RV_RIGHT_MATRIX),
SetMinimalSize(216, 0),
SetFill(1, 1),
SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY),
SetResize(1, 1),
SetScrollbar(
WID_RV_RIGHT_SCROLLBAR),
797 NWidget(
WWT_PUSHTXTBTN, COLOUR_GREY,
WID_RV_TRAIN_WAGONREMOVE_TOGGLE),
SetMinimalSize(138, 12),
SetDataTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP),
SetFill(1, 0),
SetResize(1, 0),
810 WDP_AUTO,
"replace_vehicle_train", 500, 140,
813 _nested_replace_rail_vehicle_widgets,
lengthof(_nested_replace_rail_vehicle_widgets)
816 static const NWidgetPart _nested_replace_road_vehicle_widgets[] = {
826 NWidget(
WWT_LABEL, COLOUR_GREY),
SetDataTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP),
SetFill(1, 1),
SetMinimalSize(0, 12),
SetResize(1, 0),
829 NWidget(
WWT_LABEL, COLOUR_GREY),
SetDataTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP),
SetFill(1, 1),
SetMinimalSize(0, 12),
SetResize(1, 0),
834 NWidget(
WWT_DROPDOWN, COLOUR_GREY,
WID_RV_RAIL_ROAD_TYPE_DROPDOWN),
SetMinimalSize(136, 12),
SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE),
SetFill(1, 0),
SetResize(1, 0),
849 NWidget(
WWT_MATRIX, COLOUR_GREY,
WID_RV_LEFT_MATRIX),
SetMinimalSize(216, 0),
SetFill(1, 1),
SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY),
SetResize(1, 1),
SetScrollbar(
WID_RV_LEFT_SCROLLBAR),
851 NWidget(
WWT_MATRIX, COLOUR_GREY,
WID_RV_RIGHT_MATRIX),
SetMinimalSize(216, 0),
SetFill(1, 1),
SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY),
SetResize(1, 1),
SetScrollbar(
WID_RV_RIGHT_SCROLLBAR),
868 WDP_AUTO,
"replace_vehicle_road", 500, 140,
871 _nested_replace_road_vehicle_widgets,
lengthof(_nested_replace_road_vehicle_widgets)
874 static const NWidgetPart _nested_replace_vehicle_widgets[] = {
884 NWidget(
WWT_LABEL, COLOUR_GREY),
SetDataTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP),
SetFill(1, 1),
SetMinimalSize(0, 12),
SetResize(1, 0),
887 NWidget(
WWT_LABEL, COLOUR_GREY),
SetDataTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP),
SetFill(1, 1),
SetMinimalSize(0, 12),
SetResize(1, 0),
904 NWidget(
WWT_MATRIX, COLOUR_GREY,
WID_RV_LEFT_MATRIX),
SetMinimalSize(216, 0),
SetFill(1, 1),
SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY),
SetResize(1, 1),
SetScrollbar(
WID_RV_LEFT_SCROLLBAR),
906 NWidget(
WWT_MATRIX, COLOUR_GREY,
WID_RV_RIGHT_MATRIX),
SetMinimalSize(216, 0),
SetFill(1, 1),
SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY),
SetResize(1, 1),
SetScrollbar(
WID_RV_RIGHT_SCROLLBAR),
915 NWidget(
WWT_PANEL, COLOUR_GREY,
WID_RV_INFO_TAB),
SetMinimalSize(167, 12),
SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB),
SetResize(1, 0),
EndContainer(),
922 WDP_AUTO,
"replace_vehicle", 456, 118,
925 _nested_replace_vehicle_widgets,
lengthof(_nested_replace_vehicle_widgets)
937 switch (vehicletype) {
938 case VEH_TRAIN: desc = &_replace_rail_vehicle_desc;
break;
939 case VEH_ROAD: desc = &_replace_road_vehicle_desc;
break;
940 default: desc = &_replace_vehicle_desc;
break;
EngList_SortTypeFunction *const _engine_sort_functions[][11]
Sort functions for the vehicle sort criteria, for each vehicle type.
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
static constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
Determines order of engines by engineID.
@ ROADTYPE_END
Used for iterations.
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
@ HasVariants
Set if engine has variants.
static Titem * Get(size_t index)
Returns Titem with given index.
DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
Create a drop down list for all the rail types of the local company.
GroupID sel_group
Group selected to replace.
Dimensions (a width and height) of a rectangle in 2D.
uint64 PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32 extra_data=0)
Combine an engine ID and a name context to an engine name dparam.
bool replace_engines
If true, engines are replaced, if false, wagons are replaced (only for trains).
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
const Scrollbar * GetScrollbar(uint widnum) const
Return the Scrollbar to a widget index.
@ WDF_CONSTRUCTION
This window is used for construction; close it whenever changing company.
void SetStringParameters(int widget) const override
Initialize string parameters for a widget.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
bool _engine_sort_last_order[]
Last set direction of the sort order, for each vehicle type.
bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override
Event to display a custom tooltip.
@ IsFolded
Set if display of variants should be folded (hidden).
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void GenerateReplaceVehList(bool draw_left)
Generate an engines list.
bool _engine_sort_direction
false = descending, true = ascending.
StringID replace_text
Text used in the autoreplace GUI.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
void CreateNestedTree(bool fill_nested=true)
Perform the first part of the initialization of a nested widget tree.
Tindex index
Index of this pool item.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
static EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old=nullptr)
Retrieve the engine replacement for the given company and original engine type.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
This struct contains all the info that is needed to draw and construct tracks.
bool _ctrl_pressed
Is Ctrl pressed?
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
StringID replace_text
Text used in the autoreplace GUI.
@ VEH_ROAD
Road vehicle type.
RoadType roadtype
Road type.
GUIEngineList engines[2]
Left and right list of engines.
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
bool _engine_sort_show_hidden_engines[]
Last set 'show hidden engines' setting for each vehicle type.
@ INVALID_ROADTYPE
flag for invalid roadtype
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
void DisplayVehicleSortDropDown(Window *w, VehicleType vehicle_type, int selected, int button)
Display the dropdown for the vehicle sort criteria.
static const GroupID ALL_GROUP
All vehicles are in this group.
High level window description.
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
void OnPaint() override
The window must be repainted.
bool renew_keep_length
sell some wagons if after autoreplace the train is longer than before
EngineID display_last_variant
NOSAVE client-side-only last variant selected.
uint16 EngineID
Unique identification number of an engine.
void OnResize() override
Called after the window got resized.
Information about a rail vehicle.
const StringID _engine_sort_listing[][12]
Dropdown menu strings for the vehicle sort criteria.
@ WDP_AUTO
Find a place automatically.
RailType
Enumeration for all possible railtypes.
ResizeInfo resize
Resize information.
RoadType sel_roadtype
Type of road selected. INVALID_ROADTYPE to show all.
void GuiShowTooltips(Window *parent, StringID str, uint paramcount, const uint64 params[], TooltipCloseCondition close_tooltip)
Shows a tooltip.
EngineID sel_engine[2]
Selected engine left and right.
bool descending_sort_order
Order of sorting vehicles.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width, bool auto_width, bool instant_close)
Show a drop down list.
EngineDisplayFlags display_flags
NOSAVE client-side-only display flags for build engine list.
@ WC_REPLACE_VEHICLE
Replace vehicle window; Window numbers:
@ Shaded
Set if engine should be masked.
CompanySettings settings
settings specific for each company
Window * parent
Parent window.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
WindowFlags flags
Window flags.
void GenerateLists()
Generate the lists.
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Extra information about refitted cargo and capacity.
fluid_settings_t * settings
FluidSynth settings handle.
int details_height
Minimal needed height of the details panels, in text lines (found so far).
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
bool GenerateReplaceRailList(EngineID e, bool draw_left, bool show_engines)
Figure out if an engine should be added to a list.
bool reset_sel_engine
Also reset sel_engine while updating left and/or right and no valid engine selected.
Coordinates of a point in 2D.
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width)
Show a dropdown menu window near a widget of the parent window.
void OnDropdownSelect(int widget, int index) override
A dropdown option associated to this window has been selected.
byte _engine_sort_last_criteria[]
Last set sort criteria, for each vehicle type.
WindowNumber window_number
Window number within the window class.
VehicleType
Available vehicle types.
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group)
Engine drawing loop.
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
@ SA_HOR_CENTER
Horizontally center the text.
@ RAILVEH_WAGON
simple wagon, not motorized
EngineID engine_id
Engine to display in build purchase list.
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Window for the autoreplacing of vehicles.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
@ SBS_DOWN
Sort ascending.
bool IsHidden(CompanyID c) const
Check whether the engine is hidden in the GUI for the given company.
uint16 GroupID
Type for all group identifiers.
EngineDisplayFlags
Flags used client-side in the purchase/autorenew engine list.
@ WC_BUILD_VEHICLE
Build vehicle; Window numbers:
RoadTypeLabel label
Unique 32 bit road type identifier.
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
Show the autoreplace configuration window for a particular group.
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
@ RAILTYPE_END
Used for iterations.
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
EngineID variant_id
Engine variant ID. If set, will be treated specially in purchase lists.
RailTypeLabel label
Unique 32 bit rail type identifier.
void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare)
Sort all items using quick sort and given 'CompareItems' function.
bool show_hidden_engines
Whether to show the hidden engines.
static const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
RoadType
The different roadtypes we support.
RailType railtype
Railtype, mangled if elrail is disabled.
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
RailType sel_railtype
Type of rail tracks selected. INVALID_RAILTYPE to show all.
uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e)
Get the number of engines with EngineID id_e in the group with GroupID id_g and its sub-groups.
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g)
Rebuild the left autoreplace list if an engine is removed or added.
void ForceRebuild()
Force that a rebuild is needed.
@ PurchaseList
Name is shown in the purchase list (including autoreplace window).
#define lengthof(x)
Return the length of an fixed size array.
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force)
Close a window by its class and window number (if it is open).
byte sort_criteria
Criteria of sorting vehicles.
bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
Checks some basic properties whether autoreplace is allowed.
Data structure for an opened window.
void RebuildDone()
Notify the sortlist that the rebuild is done.
@ VEH_TRAIN
Train vehicle type.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
struct RailtypeInfo::@39 strings
Strings associated with the rail type.
@ GF_REPLACE_WAGON_REMOVAL
If set, autoreplace will perform wagon removal on vehicles in this group.
void AddRemoveEngineFromAutoreplaceAndBuildWindows(VehicleType type)
When an engine is made buildable or is removed from being buildable, add/remove it from the build/aut...
Specification of a rectangle with absolute coordinates of all edges.
static bool EngineHasReplacementForCompany(const Company *c, EngineID engine, GroupID group)
Check if a company has a replacement set up for the given engine.
@ ROADTYPE_BEGIN
Used for iterations.
int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, TestedEngineDetails &te)
Draw the purchase info details of a vehicle at a given location.
static bool EngineHasReplacementWhenOldForCompany(const Company *c, EngineID engine, GroupID group)
Check if a company has a replacement set up for the given engine when it gets old.
uint GetEngineListHeight(VehicleType type)
Get the height of a single 'entry' in the engine lists.
@ TD_RTL
Text is written right-to-left by default.
TextDirection _current_text_dir
Text direction of the currently selected language.
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
void ReplaceClick_StartReplace(bool replace_when_old)
Handle click on the start replace button.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
struct RoadTypeInfo::@42 strings
Strings associated with the rail type.
@ INVALID_RAILTYPE
Flag for invalid railtype.
@ RAILTYPE_BEGIN
Used for iterations.