Changeset - r27779:653ba52c002e
[Not reviewed]
master
0 3 0
Patric Stout - 10 months ago 2023-08-11 12:53:51
truebrain@openttd.org
Codechange: make no assumptions on how the internals of TileIndex work (#11183)

Basically, avoid ".value", and just cast it to its original type
if you want to retrieve this.
3 files changed with 5 insertions and 5 deletions:
0 comments (0 inline, 0 general)
src/map_func.h
Show inline comments
 
@@ -405,59 +405,59 @@ static inline TileIndexDiff TileDiffXY(i
 
	 * Typically x and y are constants, and then this doesn't result
 
	 * in any actual multiplication in the assembly code.. */
 
	return (y * Map::SizeX()) + x;
 
}
 

	
 
/**
 
 * Get a tile from the virtual XY-coordinate.
 
 * @param x The virtual x coordinate of the tile.
 
 * @param y The virtual y coordinate of the tile.
 
 * @return The TileIndex calculated by the coordinate.
 
 */
 
debug_inline static TileIndex TileVirtXY(uint x, uint y)
 
{
 
	return (y >> 4 << Map::LogX()) + (x >> 4);
 
}
 

	
 

	
 
/**
 
 * Get the X component of a tile
 
 * @param tile the tile to get the X component of
 
 * @return the X component
 
 */
 
debug_inline static uint TileX(TileIndex tile)
 
{
 
	return tile.value & Map::MaxX();
 
	return static_cast<uint32_t>(tile) & Map::MaxX();
 
}
 

	
 
/**
 
 * Get the Y component of a tile
 
 * @param tile the tile to get the Y component of
 
 * @return the Y component
 
 */
 
debug_inline static uint TileY(TileIndex tile)
 
{
 
	return tile.value >> Map::LogX();
 
	return static_cast<uint32_t>(tile) >> Map::LogX();
 
}
 

	
 
/**
 
 * Return the offset between two tiles from a TileIndexDiffC struct.
 
 *
 
 * This function works like #TileDiffXY(int, int) and returns the
 
 * difference between two tiles.
 
 *
 
 * @param tidc The coordinate of the offset as TileIndexDiffC
 
 * @return The difference between two tiles.
 
 * @see TileDiffXY(int, int)
 
 */
 
static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
 
{
 
	return (tidc.y << Map::LogX()) + tidc.x;
 
}
 

	
 

	
 
#ifndef _DEBUG
 
	/**
 
	 * Adds two tiles together.
 
	 *
 
	 * @param x One tile
 
	 * @param y Another tile to add
src/misc/endian_buffer.hpp
Show inline comments
 
@@ -32,49 +32,49 @@ public:
 
	EndianBufferWriter(Titer buffer) : buffer(buffer) {}
 
	EndianBufferWriter(typename Titer::container_type &container) : buffer(std::back_inserter(container)) {}
 

	
 
	EndianBufferWriter &operator <<(const std::string &data) { return *this << std::string_view{ data }; }
 
	EndianBufferWriter &operator <<(const char *data) { return *this << std::string_view{ data }; }
 
	EndianBufferWriter &operator <<(std::string_view data) { this->Write(data); return *this; }
 
	EndianBufferWriter &operator <<(bool data) { return *this << static_cast<byte>(data ? 1 : 0); }
 

	
 
	template <typename T>
 
	EndianBufferWriter &operator <<(const OverflowSafeInt<T> &data) { return *this << static_cast<T>(data); };
 

	
 
	template <typename... Targs>
 
	EndianBufferWriter &operator <<(const std::tuple<Targs...> &data)
 
	{
 
		this->WriteTuple(data, std::index_sequence_for<Targs...>{});
 
		return *this;
 
	}
 

	
 
	template <class T, std::enable_if_t<std::disjunction_v<std::negation<std::is_class<T>>, std::is_base_of<StrongTypedefBase, T>>, int> = 0>
 
	EndianBufferWriter &operator <<(const T data)
 
	{
 
		if constexpr (std::is_enum_v<T>) {
 
			this->Write(static_cast<std::underlying_type_t<const T>>(data));
 
		} else if constexpr (std::is_base_of_v<StrongTypedefBase, T>) {
 
			this->Write(data.value);
 
			this->Write(static_cast<typename T::Type>(data));
 
		} else {
 
			this->Write(data);
 
		}
 
		return *this;
 
	}
 

	
 
	template <typename Tvalue, typename Tbuf = std::vector<byte>>
 
	static Tbuf FromValue(const Tvalue &data)
 
	{
 
		Tbuf buffer;
 
		EndianBufferWriter writer{ buffer };
 
		writer << data;
 
		return buffer;
 
	}
 

	
 
private:
 
	/** Helper function to write a tuple to the buffer. */
 
	template<class Ttuple, size_t... Tindices>
 
	void WriteTuple(const Ttuple &values, std::index_sequence<Tindices...>) {
 
		((*this << std::get<Tindices>(values)), ...);
 
	}
 

	
 
	/** Write overload for string values. */
 
	void Write(std::string_view value)
 
@@ -125,49 +125,49 @@ class EndianBufferReader {
 
public:
 
	EndianBufferReader(span<const byte> buffer) : buffer(buffer) {}
 

	
 
	void rewind() { this->read_pos = 0; }
 

	
 
	EndianBufferReader &operator >>(std::string &data) { data = this->ReadStr(); return *this; }
 
	EndianBufferReader &operator >>(bool &data) { data = this->Read<byte>() != 0; return *this; }
 

	
 
	template <typename T>
 
	EndianBufferReader &operator >>(OverflowSafeInt<T> &data) { data = this->Read<T>(); return *this; };
 

	
 
	template <typename... Targs>
 
	EndianBufferReader &operator >>(std::tuple<Targs...> &data)
 
	{
 
		this->ReadTuple(data, std::index_sequence_for<Targs...>{});
 
		return *this;
 
	}
 

	
 
	template <class T, std::enable_if_t<std::disjunction_v<std::negation<std::is_class<T>>, std::is_base_of<StrongTypedefBase, T>>, int> = 0>
 
	EndianBufferReader &operator >>(T &data)
 
	{
 
		if constexpr (std::is_enum_v<T>) {
 
			data = static_cast<T>(this->Read<std::underlying_type_t<T>>());
 
		} else if constexpr (std::is_base_of_v<StrongTypedefBase, T>) {
 
			data.value = this->Read<decltype(data.value)>();
 
			data = this->Read<typename T::Type>();
 
		} else {
 
			data = this->Read<T>();
 
		}
 
		return *this;
 
	}
 

	
 
	template <typename Tvalue>
 
	static Tvalue ToValue(span<const byte> buffer)
 
	{
 
		Tvalue result{};
 
		EndianBufferReader reader{ buffer };
 
		reader >> result;
 
		return result;
 
	}
 

	
 
private:
 
	/** Helper function to read a tuple from the buffer. */
 
	template<class Ttuple, size_t... Tindices>
 
	void ReadTuple(Ttuple &values, std::index_sequence<Tindices...>) {
 
		((*this >> std::get<Tindices>(values)), ...);
 
	}
 

	
 
	/** Read overload for string data. */
 
	std::string ReadStr()
src/script/squirrel_helper.hpp
Show inline comments
 
@@ -16,49 +16,49 @@
 
#include "../string_func.h"
 
#include "../tile_type.h"
 
#include "squirrel_helper_type.hpp"
 

	
 
template <class CL, ScriptType ST> const char *GetClassName();
 

	
 
/**
 
 * The Squirrel convert routines
 
 */
 
namespace SQConvert {
 
	/**
 
	 * To return a value to squirrel, we use this helper class. It converts to the right format.
 
	 * We use a class instead of a plain function to allow us to use partial template specializations.
 
	 */
 
	template <typename T> struct Return;
 

	
 
	template <> struct Return<uint8_t>        { static inline int Set(HSQUIRRELVM vm, uint8_t res)       { sq_pushinteger(vm, (int32_t)res); return 1; } };
 
	template <> struct Return<uint16_t>       { static inline int Set(HSQUIRRELVM vm, uint16_t res)      { sq_pushinteger(vm, (int32_t)res); return 1; } };
 
	template <> struct Return<uint32_t>       { static inline int Set(HSQUIRRELVM vm, uint32_t res)      { sq_pushinteger(vm, (int32_t)res); return 1; } };
 
	template <> struct Return<int8_t>         { static inline int Set(HSQUIRRELVM vm, int8_t res)        { sq_pushinteger(vm, res); return 1; } };
 
	template <> struct Return<int16_t>        { static inline int Set(HSQUIRRELVM vm, int16_t res)       { sq_pushinteger(vm, res); return 1; } };
 
	template <> struct Return<int32_t>        { static inline int Set(HSQUIRRELVM vm, int32_t res)       { sq_pushinteger(vm, res); return 1; } };
 
	template <> struct Return<int64_t>        { static inline int Set(HSQUIRRELVM vm, int64_t res)       { sq_pushinteger(vm, res); return 1; } };
 
	template <> struct Return<Money>        { static inline int Set(HSQUIRRELVM vm, Money res)       { sq_pushinteger(vm, res); return 1; } };
 
	template <> struct Return<TileIndex>    { static inline int Set(HSQUIRRELVM vm, TileIndex res)   { sq_pushinteger(vm, (int32_t)res.value); return 1; } };
 
	template <> struct Return<TileIndex>    { static inline int Set(HSQUIRRELVM vm, TileIndex res)   { sq_pushinteger(vm, (int32_t)static_cast<uint32_t>(res)); return 1; } };
 
	template <> struct Return<bool>         { static inline int Set(HSQUIRRELVM vm, bool res)        { sq_pushbool   (vm, res); return 1; } };
 
	template <> struct Return<char *>       { /* Do not use char *, use std::optional<std::string> instead. */ };
 
	template <> struct Return<const char *> { /* Do not use const char *, use std::optional<std::string> instead. */ };
 
	template <> struct Return<void *>       { static inline int Set(HSQUIRRELVM vm, void *res)       { sq_pushuserpointer(vm, res); return 1; } };
 
	template <> struct Return<HSQOBJECT>    { static inline int Set(HSQUIRRELVM vm, HSQOBJECT res)   { sq_pushobject(vm, res); return 1; } };
 

	
 
	template <> struct Return<std::optional<std::string>> {
 
		static inline int Set(HSQUIRRELVM vm, std::optional<std::string> res) {
 
			if (res.has_value()) {
 
				sq_pushstring(vm, res.value(), -1);
 
			} else {
 
				sq_pushnull(vm);
 
			}
 
			return 1;
 
		}
 
	};
 

	
 
	/**
 
	 * To get a param from squirrel, we use this helper class. It converts to the right format.
 
	 * We use a class instead of a plain function to allow us to use partial template specializations.
 
	 */
 
	template <typename T> struct Param;
 

	
 
	template <> struct Param<uint8_t>        { static inline uint8_t       Get(HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; } };
0 comments (0 inline, 0 general)