From 742e27ad2f037205285e475be487ec9ed874ca91 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 8 Sep 2020 09:46:16 +0100 Subject: Remove unused Temporary namespace - Remove unused temporary mapping generation at startup --- src/Bindings/BlockTypePalette.h | 138 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/Bindings/BlockTypePalette.h (limited to 'src/Bindings/BlockTypePalette.h') diff --git a/src/Bindings/BlockTypePalette.h b/src/Bindings/BlockTypePalette.h new file mode 100644 index 000000000..2aade422b --- /dev/null +++ b/src/Bindings/BlockTypePalette.h @@ -0,0 +1,138 @@ +#pragma once + +#include +#include "BlockState.h" + + + + + +/** Holds a palette that maps between block type + state and numbers. +Used primarily by PalettedBlockArea to map from stringular block representation to numeric, +and by protocols to map from stringular block representation to protocol-numeric. +The object itself provides no thread safety, users of this class need to handle locking, if required. +Note that the palette itself doesn't support erasing; +to erase, create a new instance and re-add only the wanted items. + +Internally, the object uses two synced maps, one for each translation direction. + +The palette can be loaded from a string (file). The loader supports either the blocks.json file exported by +the vanilla server itself (https://wiki.vg/Data_Generators), or a processed text file generated by +our tool $/Tools/BlockTypePaletteGenerator/, or a hand-written text file describing the upgrade from +1.12 BlockType + BlockMeta to 1.13 string representations. +The text file is a TSV (tab-separated values), which basically means the data is generally structured as +..., where eol is the platform's CR / CRLF / LF lineend. +The file starts with a single value on the first line, "BlockTypePalette" or "UpgradeBlockTypePalette", which +is used to detect the file format. The following lines are "headers", simple entries +that contain the metadata about the file. "FileVersion" is a compulsory key, "CommonPrefix" is supported, others +are ignored. +The headers are followed by an empty line (that signalizes the end of headers) and then the actual data. +For regular BlockTypePalette TSV file of version 1, the data is in the format: + ... +For the UpgradeBlockTypePalette TSV file of version 1, the data is in the format: + ... +If a CommonPrefix header is present, its value is pre-pended to each blockTypeName loaded (thus allowing +the file to be overall smaller). */ +class BlockTypePalette +{ +public: + + /** Exception that is thrown if requiesting an index not present in the palette. */ + class NoSuchIndexException: + public std::runtime_error + { + using Super = std::runtime_error; + + public: + NoSuchIndexException(UInt32 aIndex): + Super(Printf("No such palette index: %u", aIndex)) + { + } + }; + + + /** Exception that is thrown when loading the palette fails hard (bad format). */ + class LoadFailedException: + public std::runtime_error + { + using Super = std::runtime_error; + + public: + LoadFailedException(const AString & aReason): + Super(aReason) + { + } + }; + + + + /** Create a new empty instance. */ + BlockTypePalette(); + + /** Returns the index of the specified block type name and state. + If the combination is not found, it is added to the palette and the new index is returned. */ + UInt32 index(const AString & aBlockTypeName, const BlockState & aBlockState); + + /** Returns the of the specified block type name and state, if it exists. + If the combination is not found, returns . */ + std::pair maybeIndex(const AString & aBlockTypeName, const BlockState & aBlockState) const; + + /** Returns the total number of entries in the palette. */ + UInt32 count() const; + + /** Returns the blockspec represented by the specified palette index. + If the index is not valid, throws a NoSuchIndexException. */ + const std::pair & entry(UInt32 aIndex) const; + + /** Returns an index-transform map from aFrom to this (this.entry(idx) == aFrom.entry(res[idx])). + Entries from aFrom that are not present in this are added. + Used when pasting two areas, to transform the src palette to dst palette. */ + std::map createTransformMapAddMissing(const BlockTypePalette & aFrom); + + /** Returns an index-transform map from aFrom to this (this.entry(idx) == aFrom.entry(res[idx])). + Entries from aFrom that are not present in this are assigned the fallback index. + Used for protocol block type mapping. */ + std::map createTransformMapWithFallback(const BlockTypePalette & aFrom, UInt32 aFallbackIndex) const; + + /** Loads the palette from the string representation. + Throws a LoadFailedException if the loading fails hard (bad string format); + but still a part of the data may already be loaded at that point. + If the string specifies duplicate entries (either to already existing entries, or to itself), + the duplicates replace the current values silently (this allows us to chain multiple files as "overrides". + Auto-detects the string format (json / tsv, normal / upgrade palette) and calls the appropriate load function. */ + void loadFromString(const AString & aString); + + +protected: + + /** The mapping from numeric to stringular representation. + mNumberToBlock[index] = {"blockTypeName", blockState}. */ + std::map> mNumberToBlock; + + /** The mapping from stringular to numeric representation. + mStringToNumber["blockTypeName"][blockState] = index. */ + std::unordered_map> mBlockToNumber; + + /** The maximum index ever used in the maps. + Used when adding new entries through the index() call. */ + UInt32 mMaxIndex; + + + /** Loads the palette from the JSON representation, https://wiki.vg/Data_Generators + Throws a LoadFailedException if the loading fails hard (bad string format); + but still a part of the data may already be loaded at that point. + See also: loadFromString(). */ + void loadFromJsonString(const AString & aJsonPalette); + + /** Loads the palette from the regular or upgrade TSV representation. + aIsUpgrade specifies whether the format is an upgrade TSV (true) or a regular one (false) + Throws a LoadFailedException if the loading fails hard (bad string format); + but still a part of the data may already be loaded at that point. + See also: loadFromString(). */ + void loadFromTsv(const AString & aTsvPalette, bool aIsUpgrade); + + /** Adds a mapping between the numeric and stringular representation into both maps, + updates the mMaxIndex, if appropriate. + Silently overwrites any previous mapping for the ID, if present, but keeps the old string->id mapping. */ + void addMapping(UInt32 aID, const AString & aBlockTypeName, const BlockState & aBlockState); +}; -- cgit v1.2.3