Skip to content

Commit

Permalink
Merge pull request OpenRCT2#22723 from Gymnasiast/refactor/flag-holder
Browse files Browse the repository at this point in the history
 Create FlagHolder
  • Loading branch information
Gymnasiast authored Sep 19, 2024
2 parents 4b44f4f + 1f33aec commit eb664a2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 38 deletions.
59 changes: 21 additions & 38 deletions src/openrct2-ui/windows/Footpath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <openrct2/actions/FootpathPlaceAction.h>
#include <openrct2/actions/FootpathRemoveAction.h>
#include <openrct2/audio/audio.h>
#include <openrct2/core/FlagHolder.hpp>
#include <openrct2/localisation/Formatter.h>
#include <openrct2/object/FootpathObject.h>
#include <openrct2/object/FootpathRailingsObject.h>
Expand Down Expand Up @@ -64,35 +65,16 @@ namespace OpenRCT2::Ui::Windows
forceRecheck = 2,
};

using ProvisionalPathFlags = FlagHolder<uint8_t, ProvisionalPathFlag>;
struct ProvisionalFootpath
{
ObjectEntryIndex type;
CoordsXYZ position;
uint8_t slope;
uint8_t flags;
ProvisionalPathFlags flags;
ObjectEntryIndex surfaceIndex;
ObjectEntryIndex railingsIndex;
PathConstructFlags constructFlags;

bool hasFlag(ProvisionalPathFlag flag)
{
return HasFlag(flags, flag);
}

void setFlag(ProvisionalPathFlag flag)
{
flags |= EnumToFlag(flag);
}

void clearFlag(ProvisionalPathFlag flag)
{
flags &= ~EnumToFlag(flag);
}

void flipFlag(ProvisionalPathFlag flag)
{
flags ^= EnumToFlag(flag);
}
};

static ProvisionalFootpath _provisionalFootpath;
Expand Down Expand Up @@ -572,14 +554,14 @@ namespace OpenRCT2::Ui::Windows
}

// Recheck area for construction. Set by ride_construction window
if (_provisionalFootpath.hasFlag(ProvisionalPathFlag::forceRecheck))
if (_provisionalFootpath.flags.has(ProvisionalPathFlag::forceRecheck))
{
FootpathRemoveProvisional();
_provisionalFootpath.clearFlag(ProvisionalPathFlag::forceRecheck);
_provisionalFootpath.flags.unset(ProvisionalPathFlag::forceRecheck);
}

// Update provisional bridge mode path
if (!(_provisionalFootpath.hasFlag(ProvisionalPathFlag::placed)))
if (!(_provisionalFootpath.flags.has(ProvisionalPathFlag::placed)))
{
ObjectEntryIndex type;
ObjectEntryIndex railings = gFootpathSelection.Railings;
Expand All @@ -600,13 +582,13 @@ namespace OpenRCT2::Ui::Windows
{
_footpathConstructionNextArrowPulse = curTime + ARROW_PULSE_DURATION;

_provisionalFootpath.flipFlag(ProvisionalPathFlag::showArrow);
_provisionalFootpath.flags.flip(ProvisionalPathFlag::showArrow);
CoordsXYZ footpathLoc;
int32_t slope;
FootpathGetNextPathInfo(nullptr, footpathLoc, &slope);
gMapSelectArrowPosition = footpathLoc;
gMapSelectArrowDirection = _footpathConstructDirection;
if (_provisionalFootpath.hasFlag(ProvisionalPathFlag::showArrow))
if (_provisionalFootpath.flags.has(ProvisionalPathFlag::showArrow))
{
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW;
}
Expand Down Expand Up @@ -1025,7 +1007,8 @@ namespace OpenRCT2::Ui::Windows

// Check for change
auto provisionalPos = CoordsXYZ(*mapPos, _footpathPlaceZ);
if ((_provisionalFootpath.hasFlag(ProvisionalPathFlag::placed)) && _provisionalFootpath.position == provisionalPos)
if ((_provisionalFootpath.flags.has(ProvisionalPathFlag::placed))
&& _provisionalFootpath.position == provisionalPos)
{
return;
}
Expand Down Expand Up @@ -1220,7 +1203,7 @@ namespace OpenRCT2::Ui::Windows
ToolCancel();
gFootpathConstructFromPosition = { mapCoords, z };
_footpathConstructDirection = direction;
_provisionalFootpath.flags = 0;
_provisionalFootpath.flags.clearAll();
gFootpathConstructSlope = 0;
_footpathConstructionMode = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL;
_footpathConstructValidDirections = INVALID_DIRECTION;
Expand Down Expand Up @@ -1769,7 +1752,7 @@ namespace OpenRCT2::Ui::Windows
_provisionalFootpath.position = footpathLoc;
_provisionalFootpath.slope = slope;
_provisionalFootpath.constructFlags = constructFlags;
_provisionalFootpath.setFlag(ProvisionalPathFlag::placed);
_provisionalFootpath.flags.set(ProvisionalPathFlag::placed);

if (gFootpathGroundFlags & ELEMENT_IS_UNDERGROUND)
{
Expand Down Expand Up @@ -1814,9 +1797,9 @@ namespace OpenRCT2::Ui::Windows
*/
void FootpathRemoveProvisional()
{
if (_provisionalFootpath.hasFlag(ProvisionalPathFlag::placed))
if (_provisionalFootpath.flags.has(ProvisionalPathFlag::placed))
{
_provisionalFootpath.clearFlag(ProvisionalPathFlag::placed);
_provisionalFootpath.flags.unset(ProvisionalPathFlag::placed);

auto action = FootpathRemoveAction(_provisionalFootpath.position);
action.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST);
Expand All @@ -1830,9 +1813,9 @@ namespace OpenRCT2::Ui::Windows
*/
void FootpathUpdateProvisional()
{
if (_provisionalFootpath.hasFlag(ProvisionalPathFlag::showArrow))
if (_provisionalFootpath.flags.has(ProvisionalPathFlag::showArrow))
{
_provisionalFootpath.clearFlag(ProvisionalPathFlag::showArrow);
_provisionalFootpath.flags.unset(ProvisionalPathFlag::showArrow);

gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
MapInvalidateTileFull(gFootpathConstructFromPosition);
Expand All @@ -1842,18 +1825,18 @@ namespace OpenRCT2::Ui::Windows

void FootpathRemoveProvisionalTemporarily()
{
if (_provisionalFootpath.hasFlag(ProvisionalPathFlag::placed))
if (_provisionalFootpath.flags.has(ProvisionalPathFlag::placed))
{
FootpathRemoveProvisional();
_provisionalFootpath.setFlag(ProvisionalPathFlag::placed);
_provisionalFootpath.flags.set(ProvisionalPathFlag::placed);
}
}

void FootpathRestoreProvisional()
{
if (_provisionalFootpath.hasFlag(ProvisionalPathFlag::placed))
if (_provisionalFootpath.flags.has(ProvisionalPathFlag::placed))
{
_provisionalFootpath.clearFlag(ProvisionalPathFlag::placed);
_provisionalFootpath.flags.unset(ProvisionalPathFlag::placed);
FootpathProvisionalSet(
_provisionalFootpath.surfaceIndex, _provisionalFootpath.railingsIndex, _provisionalFootpath.position,
_provisionalFootpath.slope, _provisionalFootpath.constructFlags);
Expand All @@ -1862,6 +1845,6 @@ namespace OpenRCT2::Ui::Windows

void FootpathRecheckProvisional()
{
_provisionalFootpath.setFlag(ProvisionalPathFlag::forceRecheck);
_provisionalFootpath.flags.set(ProvisionalPathFlag::forceRecheck);
}
} // namespace OpenRCT2::Ui::Windows
45 changes: 45 additions & 0 deletions src/openrct2/core/FlagHolder.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/

#pragma once

template<typename THolderType, typename TEnumType> struct FlagHolder
{
THolderType holder{};

constexpr void clearAll()
{
holder = 0;
}

[[nodiscard]] constexpr bool isEmpty() const
{
return holder == 0;
}

[[nodiscard]] constexpr bool has(TEnumType flag) const
{
return (holder & EnumToFlag(flag)) != 0;
}

constexpr void set(TEnumType flag)
{
holder |= EnumToFlag(flag);
}

constexpr void unset(TEnumType flag)
{
holder &= ~EnumToFlag(flag);
}

constexpr void flip(TEnumType flag)
{
holder ^= EnumToFlag(flag);
}
};
1 change: 1 addition & 0 deletions src/openrct2/libopenrct2.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
<ClInclude Include="core\Range.hpp" />
<ClInclude Include="core\RTL.h" />
<ClInclude Include="core\FixedVector.h" />
<ClInclude Include="core\FlagHolder.hpp" />
<ClInclude Include="core\Speed.hpp" />
<ClInclude Include="core\String.hpp" />
<ClInclude Include="core\StringBuilder.h" />
Expand Down

0 comments on commit eb664a2

Please sign in to comment.