From 9b3326e3fdf5d90a2ab763869d0c678c8bd18c33 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Fri, 24 Feb 2023 00:49:57 +0100 Subject: [PATCH] Codechange: [Script] Use std::vector instead of a hand-rolled alternative. --- cmake/scripts/SquirrelExport.cmake | 2 +- src/script/api/script_road.cpp | 34 ++++++++++++++--------------- src/script/api/script_road.hpp | 3 ++- src/script/squirrel_helper.hpp | 23 +++++-------------- src/script/squirrel_helper_type.hpp | 8 +++---- 5 files changed, 30 insertions(+), 40 deletions(-) diff --git a/cmake/scripts/SquirrelExport.cmake b/cmake/scripts/SquirrelExport.cmake index 5c41618d6c..d13bd8d4d0 100644 --- a/cmake/scripts/SquirrelExport.cmake +++ b/cmake/scripts/SquirrelExport.cmake @@ -627,7 +627,7 @@ foreach(LINE IN LISTS SOURCE_LINES) string(APPEND TYPES "p") elseif("${PARAM}" MATCHES "^Array") string(APPEND TYPES "a") - elseif("${PARAM}" MATCHES "^struct Array") + elseif("${PARAM}" MATCHES "^const Array") string(APPEND TYPES "a") elseif("${PARAM}" MATCHES "^Text") string(APPEND TYPES ".") diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index 20e38398de..1cb01327c4 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -148,9 +148,9 @@ * @param end The part that will be build second. * @return True if and only if the road bits can be build. */ -static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32 end) +static bool CheckAutoExpandedRoadBits(const Array<> &existing, int32 start, int32 end) { - return (start + end == 0) && (existing->size == 0 || existing->array[0] == start || existing->array[0] == end); + return (start + end == 0) && (existing.empty() || existing[0] == start || existing[0] == end); } /** @@ -163,7 +163,7 @@ static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32 * they are build or 2 when building the first part automatically * builds the second part. */ -static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, int32 start, int32 end) +static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array<> &existing, int32 start, int32 end) { switch (slope) { /* Flat slopes can always be build. */ @@ -175,9 +175,9 @@ static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, in * in the game have been changed. */ case SLOPE_NE: case SLOPE_SW: - return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing->size == 0 ? 2 : 1) : 0; + return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing.empty() ? 2 : 1) : 0; case SLOPE_SE: case SLOPE_NW: - return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing->size == 0 ? 2 : 1) : 0; + return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing.empty() ? 2 : 1) : 0; /* Any other tile cannot be built on. */ default: @@ -227,7 +227,7 @@ static RoadBits NeighbourToRoadBits(int32 neighbour) * they are build or 2 when building the first part automatically * builds the second part. */ -static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start, int32 end) +static int32 LookupWithBuildOnSlopes(::Slope slope, const Array<> &existing, int32 start, int32 end) { /* Steep slopes behave the same as slopes with one corner raised. */ if (IsSteepSlope(slope)) { @@ -277,9 +277,6 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start /* Now perform the actual rotation. */ for (int j = 0; j < base_rotate; j++) { - for (size_t i = 0; i < existing->size; i++) { - existing->array[i] = RotateNeighbour(existing->array[i]); - } start = RotateNeighbour(start); end = RotateNeighbour(end); } @@ -288,8 +285,11 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start RoadBits start_roadbits = NeighbourToRoadBits(start); RoadBits new_roadbits = start_roadbits | NeighbourToRoadBits(end); RoadBits existing_roadbits = ROAD_NONE; - for (size_t i = 0; i < existing->size; i++) { - existing_roadbits |= NeighbourToRoadBits(existing->array[i]); + for (int32 neighbour : existing) { + for (int j = 0; j < base_rotate; j++) { + neighbour = RotateNeighbour(neighbour); + } + existing_roadbits |= NeighbourToRoadBits(neighbour); } switch (slope) { @@ -377,7 +377,7 @@ static bool NormaliseTileOffset(int32 *tile) return false; } -/* static */ int32 ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array *existing, TileIndex start_, TileIndex end_) +/* static */ int32 ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array<> existing, TileIndex start_, TileIndex end_) { ::Slope slope = (::Slope)slope_; int32 start = start_; @@ -386,8 +386,8 @@ static bool NormaliseTileOffset(int32 *tile) /* The start tile and end tile cannot be the same tile either. */ if (start == end) return -1; - for (size_t i = 0; i < existing->size; i++) { - if (!NormaliseTileOffset(&existing->array[i])) return -1; + for (size_t i = 0; i < existing.size(); i++) { + if (!NormaliseTileOffset(&existing[i])) return -1; } if (!NormaliseTileOffset(&start)) return -1; @@ -405,8 +405,6 @@ static bool NormaliseTileOffset(int32 *tile) /* ROAD_NW ROAD_SW ROAD_SE ROAD_NE */ const TileIndexDiff neighbours[] = {::TileDiffXY(0, -1), ::TileDiffXY(1, 0), ::TileDiffXY(0, 1), ::TileDiffXY(-1, 0)}; - Array *existing = (Array*)alloca(sizeof(Array) + lengthof(neighbours) * sizeof(int32)); - existing->size = 0; ::RoadBits rb = ::ROAD_NONE; if (::IsNormalRoadTile(tile)) { @@ -414,8 +412,10 @@ static bool NormaliseTileOffset(int32 *tile) } else { rb = ::GetAnyRoadBits(tile, RTT_ROAD) | ::GetAnyRoadBits(tile, RTT_TRAM); } + + Array<> existing; for (uint i = 0; i < lengthof(neighbours); i++) { - if (HasBit(rb, i)) existing->array[existing->size++] = neighbours[i]; + if (HasBit(rb, i)) existing.emplace_back(neighbours[i]); } return ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::GetSlope(tile), existing, start - tile, end - tile); diff --git a/src/script/api/script_road.hpp b/src/script/api/script_road.hpp index 9631309ebc..a042644078 100644 --- a/src/script/api/script_road.hpp +++ b/src/script/api/script_road.hpp @@ -11,6 +11,7 @@ #define SCRIPT_ROAD_HPP #include "script_tile.hpp" +#include "../squirrel_helper_type.hpp" #include "../../../road.h" /** @@ -245,7 +246,7 @@ public: * they are build or 2 when building the first part automatically * builds the second part. -1 means the preconditions are not met. */ - static int32 CanBuildConnectedRoadParts(ScriptTile::Slope slope, struct Array *existing, TileIndex start, TileIndex end); + static int32 CanBuildConnectedRoadParts(ScriptTile::Slope slope, Array<> existing, TileIndex start, TileIndex end); /** * Lookup function for building road parts independent of whether the diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp index a717fbdad5..47c5eb62a0 100644 --- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.hpp @@ -91,8 +91,9 @@ namespace SQConvert { } }; - template <> struct Param { - static inline Array *Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) + template + struct Param> { + static inline Array Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { /* Sanity check of the size. */ if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large"); @@ -102,27 +103,15 @@ namespace SQConvert { sq_pushobject(vm, obj); sq_pushnull(vm); - std::vector data; + Array data; while (SQ_SUCCEEDED(sq_next(vm, -2))) { - SQInteger tmp; - if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) { - data.push_back((int32)tmp); - } else { - sq_pop(vm, 4); - throw sq_throwerror(vm, "a member of an array used as parameter to a function is not numeric"); - } - + data.emplace_back(Param::Get(vm, -1, ptr)); sq_pop(vm, 2); } sq_pop(vm, 2); - Array *arr = (Array *)MallocT(sizeof(Array) + sizeof(int32) * data.size()); - arr->size = data.size(); - memcpy(arr->array, data.data(), sizeof(int32) * data.size()); - - ptr->push_back(arr); - return arr; + return data; } }; diff --git a/src/script/squirrel_helper_type.hpp b/src/script/squirrel_helper_type.hpp index c20655ca19..05f3824fd9 100644 --- a/src/script/squirrel_helper_type.hpp +++ b/src/script/squirrel_helper_type.hpp @@ -10,10 +10,10 @@ #ifndef SQUIRREL_HELPER_TYPE_HPP #define SQUIRREL_HELPER_TYPE_HPP +#include + /** Definition of a simple array. */ -struct Array { - size_t size; ///< The size of the array. - int32 array[]; ///< The data of the array. -}; +template +using Array = std::vector; #endif /* SQUIRREL_HELPER_TYPE_HPP */