Browse Source

Use `function_ref` instead of `function`

`function_ref` is a lightweight function pointer,
whereas `std::function` always involves a heap allocation.
pull/5464/head
Gleb Mazovetskiy 3 years ago
parent
commit
6dca019de2
  1. 4
      Source/DiabloUI/diabloui.cpp
  2. 5
      Source/DiabloUI/diabloui.h
  3. 5
      Source/DiabloUI/settingsmenu.cpp
  4. 8
      Source/engine/path.cpp
  5. 6
      Source/engine/path.h
  6. 2
      Source/missiles.cpp
  7. 2
      Source/monster.cpp
  8. 4
      Source/monster.h
  9. 17
      Source/panels/charpanel.cpp
  10. 1
      Source/platform/vita/CMakeLists.txt
  11. 5
      Source/utils/language.cpp

4
Source/DiabloUI/diabloui.cpp

@ -762,11 +762,11 @@ void UiClearScreen()
SDL_FillRect(DiabloUiSurface(), nullptr, 0x000000);
}
void UiPollAndRender(std::function<bool(SDL_Event &)> eventHandler)
void UiPollAndRender(std::optional<tl::function_ref<bool(SDL_Event &)>> eventHandler)
{
SDL_Event event;
while (PollEvent(&event) != 0) {
if (eventHandler && eventHandler(event))
if (eventHandler && (*eventHandler)(event))
continue;
UiFocusNavigation(&event);
UiHandleEvents(&event);

5
Source/DiabloUI/diabloui.h

@ -5,11 +5,14 @@
#include <cstddef>
#include <cstdint>
#include <function_ref.hpp>
#include "DiabloUI/ui_item.h"
#include "engine/clx_sprite.hpp"
#include "engine/load_pcx.hpp" // IWYU pragma: export
#include "player.h"
#include "utils/display.h"
#include "utils/stdcompat/optional.hpp"
namespace devilution {
@ -105,7 +108,7 @@ void UiFocusNavigationEsc();
void UiFocusNavigationYesNo();
void UiInitList(void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), const std::vector<std::unique_ptr<UiItemBase>> &items, bool wraps = false, void (*fnFullscreen)() = nullptr, bool (*fnYesNo)() = nullptr, size_t selectedItem = 0);
void UiClearScreen();
void UiPollAndRender(std::function<bool(SDL_Event &)> eventHandler = nullptr);
void UiPollAndRender(std::optional<tl::function_ref<bool(SDL_Event &)>> eventHandler = std::nullopt);
void UiRenderItem(const UiItemBase &item);
void UiRenderItems(const std::vector<UiItemBase *> &items);
void UiRenderItems(const std::vector<std::unique_ptr<UiItemBase>> &items);

5
Source/DiabloUI/settingsmenu.cpp

@ -1,5 +1,7 @@
#include "selstart.h"
#include <function_ref.hpp>
#include "DiabloUI/diabloui.h"
#include "DiabloUI/scrollbar.h"
#include "control.h"
@ -9,6 +11,7 @@
#include "miniwin/misc_msg.h"
#include "options.h"
#include "utils/language.h"
#include "utils/stdcompat/optional.hpp"
#include "utils/utf8.hpp"
namespace devilution {
@ -268,7 +271,7 @@ void UiSettingsMenu()
vecDialog.push_back(std::make_unique<UiArtText>(optionDescription, MakeSdlRect(rectDescription), UiFlags::FontSize12 | UiFlags::ColorUiSilverDark | UiFlags::AlignCenter, 1, IsSmallFontTall() ? 22 : 18));
size_t itemToSelect = 1;
std::function<bool(SDL_Event &)> eventHandler;
std::optional<tl::function_ref<bool(SDL_Event &)>> eventHandler;
switch (shownMenu) {
case ShownMenuType::Settings: {

8
Source/engine/path.cpp

@ -7,6 +7,8 @@
#include <array>
#include <function_ref.hpp>
#include "levels/gendung.h"
#include "lighting.h"
#include "objects.h"
@ -290,7 +292,7 @@ bool ParentPath(uint16_t pathIndex, Point candidatePosition, Point destinationPo
*
* @return false if we ran out of preallocated nodes to use, else true
*/
bool GetPath(const std::function<bool(Point)> &posOk, uint16_t pathIndex, Point destination)
bool GetPath(tl::function_ref<bool(Point)> posOk, uint16_t pathIndex, Point destination)
{
for (Displacement dir : PathDirs) {
const PathNode &path = PathNodes[pathIndex];
@ -362,7 +364,7 @@ bool IsTileOccupied(Point position)
return false;
}
int FindPath(const std::function<bool(Point)> &posOk, Point startPosition, Point destinationPosition, int8_t path[MaxPathLength])
int FindPath(tl::function_ref<bool(Point)> posOk, Point startPosition, Point destinationPosition, int8_t path[MaxPathLength])
{
/**
* for reconstructing the path after the A* search is done. The longest
@ -434,7 +436,7 @@ bool path_solid_pieces(Point startPosition, Point destinationPosition)
return rv;
}
std::optional<Point> FindClosestValidPosition(const std::function<bool(Point)> &posOk, Point startingPosition, unsigned int minimumRadius, unsigned int maximumRadius)
std::optional<Point> FindClosestValidPosition(tl::function_ref<bool(Point)> posOk, Point startingPosition, unsigned int minimumRadius, unsigned int maximumRadius)
{
return Crawl(minimumRadius, maximumRadius, [&](Displacement displacement) -> std::optional<Point> {
Point candidatePosition = startingPosition + displacement;

6
Source/engine/path.h

@ -6,10 +6,10 @@
#pragma once
#include <cstdint>
#include <functional>
#include <limits>
#include <SDL.h>
#include <function_ref.hpp>
#include "engine/direction.hpp"
#include "engine/point.hpp"
@ -36,7 +36,7 @@ bool IsTileOccupied(Point position);
* @brief Find the shortest path from startPosition to destinationPosition, using PosOk(Point) to check that each step is a valid position.
* Store the step directions (corresponds to an index in PathDirs) in path, which must have room for 24 steps
*/
int FindPath(const std::function<bool(Point)> &posOk, Point startPosition, Point destinationPosition, int8_t path[MaxPathLength]);
int FindPath(tl::function_ref<bool(Point)> posOk, Point startPosition, Point destinationPosition, int8_t path[MaxPathLength]);
/**
* @brief check if stepping from a given position to a neighbouring tile cuts a corner.
@ -83,6 +83,6 @@ const Displacement PathDirs[8] = {
* @param maximumRadius The maximum distance to check, defaults to 18 for vanilla compatibility but supports values up to 50
* @return either the closest valid point or an empty optional
*/
std::optional<Point> FindClosestValidPosition(const std::function<bool(Point)> &posOk, Point startingPosition, unsigned int minimumRadius = 0, unsigned int maximumRadius = 18);
std::optional<Point> FindClosestValidPosition(tl::function_ref<bool(Point)> posOk, Point startingPosition, unsigned int minimumRadius = 0, unsigned int maximumRadius = 18);
} // namespace devilution

2
Source/missiles.cpp

@ -458,7 +458,7 @@ void CheckMissileCol(Missile &missile, int minDamage, int maxDamage, bool isDama
PlaySfxLoc(MissilesData[missile._mitype].miSFX, missile.position.tile);
}
bool MoveMissile(Missile &missile, const std::function<bool(Point)> &checkTile, bool ifCheckTileFailsDontMoveToTile = false)
bool MoveMissile(Missile &missile, tl::function_ref<bool(Point)> checkTile, bool ifCheckTileFailsDontMoveToTile = false)
{
Point prevTile = missile.position.tile;
missile.position.traveled += missile.position.velocity;

2
Source/monster.cpp

@ -4049,7 +4049,7 @@ bool LineClearMissile(Point startPoint, Point endPoint)
return LineClear(PosOkMissile, startPoint, endPoint);
}
bool LineClear(const std::function<bool(Point)> &clear, Point startPoint, Point endPoint)
bool LineClear(tl::function_ref<bool(Point)> clear, Point startPoint, Point endPoint)
{
Point position = startPoint;

4
Source/monster.h

@ -11,6 +11,8 @@
#include <array>
#include <functional>
#include <function_ref.hpp>
#include "engine.h"
#include "engine/actor_position.hpp"
#include "engine/animationinfo.h"
@ -478,7 +480,7 @@ void FreeMonsters();
bool DirOK(const Monster &monster, Direction mdir);
bool PosOkMissile(Point position);
bool LineClearMissile(Point startPoint, Point endPoint);
bool LineClear(const std::function<bool(Point)> &clear, Point startPoint, Point endPoint);
bool LineClear(tl::function_ref<bool(Point)> clear, Point startPoint, Point endPoint);
void SyncMonsterAnim(Monster &monster);
void M_FallenFear(Point position);
void PrintMonstHistory(int mt);

17
Source/panels/charpanel.cpp

@ -3,6 +3,7 @@
#include <string>
#include <fmt/format.h>
#include <function_ref.hpp>
#include "control.h"
#include "engine/load_clx.hpp"
@ -42,8 +43,8 @@ struct PanelEntry {
std::string label;
Point position;
int length;
int labelLength; // max label's length - used for line wrapping
std::function<StyledText()> statDisplayFunc = nullptr; // function responsible for displaying stat
int labelLength; // max label's length - used for line wrapping
std::optional<tl::function_ref<StyledText()>> statDisplayFunc; // function responsible for displaying stat
};
UiFlags GetBaseStatColor(CharacterAttribute attr)
@ -145,8 +146,8 @@ PanelEntry panelEntries[] = {
return StyledText { UiFlags::ColorWhite, FormatInteger(MyPlayer->_pNextExper), spacing };
} },
{ N_("Base"), { LeftColumnLabelX, /* set dynamically */ 0 }, 0, 44 },
{ N_("Now"), { 135, /* set dynamically */ 0 }, 0, 44 },
{ N_("Base"), { LeftColumnLabelX, /* set dynamically */ 0 }, 0, 44, {} },
{ N_("Now"), { 135, /* set dynamically */ 0 }, 0, 44, {} },
{ N_("Strength"), { LeftColumnLabelX, 135 }, 45, LeftColumnLabelWidth,
[]() { return StyledText { GetBaseStatColor(CharacterAttribute::Strength), StrCat(MyPlayer->_pBaseStr) }; } },
{ "", { 135, 135 }, 45, 0,
@ -167,7 +168,7 @@ PanelEntry panelEntries[] = {
return StyledText { UiFlags::ColorRed, (MyPlayer->_pStatPts > 0 ? StrCat(MyPlayer->_pStatPts) : "") };
} },
{ N_("Gold"), { TopRightLabelX, /* set dynamically */ 0 }, 0, 98 },
{ N_("Gold"), { TopRightLabelX, /* set dynamically */ 0 }, 0, 98, {} },
{ "", { TopRightLabelX, 127 }, 99, 0,
[]() { return StyledText { UiFlags::ColorWhite, FormatInteger(MyPlayer->_pGold) }; } },
@ -283,7 +284,7 @@ void LoadCharPanel()
panelEntries[GoldHeaderEntryIndex].position.y = isSmallFontTall ? 105 : 106;
for (auto &entry : panelEntries) {
if (entry.statDisplayFunc != nullptr) {
if (entry.statDisplayFunc) {
DrawPanelField(out, entry.position, entry.length, boxLeft[0], boxMiddle[0], boxRight[0]);
}
DrawShadowString(out, entry);
@ -303,8 +304,8 @@ void DrawChr(const Surface &out)
Point pos = GetPanelPosition(UiPanels::Character, { 0, 0 });
RenderClxSprite(out, (*Panel)[0], pos);
for (auto &entry : panelEntries) {
if (entry.statDisplayFunc != nullptr) {
StyledText tmp = entry.statDisplayFunc();
if (entry.statDisplayFunc) {
StyledText tmp = (*entry.statDisplayFunc)();
DrawString(
out,
tmp.text,

1
Source/platform/vita/CMakeLists.txt

@ -23,4 +23,5 @@ target_link_libraries(libdevilutionx_vita PUBLIC
SceAppUtil_stub
SceNet_stub
SceNetCtl_stub
tl
)

5
Source/utils/language.cpp

@ -1,10 +1,11 @@
#include "utils/language.h"
#include <functional>
#include <memory>
#include <unordered_map>
#include <vector>
#include <function_ref.hpp>
#include "engine/assets.hpp"
#include "options.h"
#include "utils/file_util.h"
@ -104,7 +105,7 @@ string_view TrimRight(string_view str)
// English, Danish, Spanish, Italian, Swedish
unsigned PluralForms = 2;
std::function<int(int n)> GetLocalPluralId = [](int n) -> int { return n != 1 ? 1 : 0; };
tl::function_ref<int(int n)> GetLocalPluralId = [](int n) -> int { return n != 1 ? 1 : 0; };
/**
* Match plural=(n != 1);"

Loading…
Cancel
Save