From d1c95742ddd83899bb35051de9d731d38aba80a4 Mon Sep 17 00:00:00 2001 From: E14 <1640391+E14@users.noreply.github.com> Date: Sun, 22 Sep 2019 22:57:54 +0200 Subject: Add ProtocolBlockTypePalette (#4391) --- src/Protocol/ProtocolBlockTypePalette.cpp | 144 ++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/Protocol/ProtocolBlockTypePalette.cpp (limited to 'src/Protocol/ProtocolBlockTypePalette.cpp') diff --git a/src/Protocol/ProtocolBlockTypePalette.cpp b/src/Protocol/ProtocolBlockTypePalette.cpp new file mode 100644 index 000000000..86d05623b --- /dev/null +++ b/src/Protocol/ProtocolBlockTypePalette.cpp @@ -0,0 +1,144 @@ +#include "Globals.h" +#include "ProtocolBlockTypePalette.h" +#include +#include +#include "json/value.h" +#include "json/reader.h" + + + + + +ProtocolBlockTypePalette::ProtocolBlockTypePalette() +{ + // empty +} + + + + + +bool ProtocolBlockTypePalette::loadFromString(const AString & aMapping) +{ + std::stringstream stream; + stream << aMapping; + + return loadFromStream(stream); +} + + + + + +bool ProtocolBlockTypePalette::loadFromStream(std::istream & aInputStream) +{ + Json::Value root; + + try + { + aInputStream >> root; + } + #if defined _DEBUG + catch (const std::exception & e) + { + LOGD(e.what()); + return false; + } + #else + catch (const std::exception &) + { + return false; + } + #endif + + if (!root.isObject() || + !root.isMember("Metadata") || + !root["Metadata"].isMember("ProtocolBlockTypePaletteVersion") || + !root.isMember("Palette") || + !root["Palette"].isArray()) + { + LOGD("Incorrect palette format."); + return false; + } + + if (root["Metadata"]["ProtocolBlockTypePaletteVersion"].asUInt() != 1) + { + LOGD("Palette format version not supported."); + return false; + } + + auto len = root["Palette"].size(); + for (decltype(len) i = 0; i < len; ++i) + { + const auto & record = root["Palette"][i]; + if (!record.isObject()) + { + LOGD("Record #%u must be a JSON object.", i); + return false; + } + + auto blocktype = record["name"].asString(); + auto id = std::stoul(record["id"].asString()); + std::map state; + + if (id >= NOT_FOUND) + { + LOGD("`id` must be less than ProtocolBlockTypePalette::NOT_FOUND, but is %lu", id); + return false; + } + + if (record.isMember("props")) + { + const auto & props = record["props"]; + if (!props.isObject()) + { + LOGD("`props` key must be a JSON object."); + return false; + } + for (const auto & key: props.getMemberNames()) + { + state[key] = props[key].asString(); + } + } + + // Block type map entry already exists? + if (mIndex.count(blocktype) == 0) + { + mIndex.insert({blocktype, std::map()}); + } + + const auto & result = mIndex[blocktype].insert({BlockState(state), id}); + if (result.second == false) + { + LOGINFO("Duplicate block state encountered (Current ID: %lu, other: %lu)", result.first->second, id); + } + } + return true; +} + + + + + +UInt32 ProtocolBlockTypePalette::index(const AString & aBlockTypeName, const BlockState & aBlockState) const +{ + auto a = mIndex.find(aBlockTypeName); + if (a != mIndex.end()) + { + auto b = a->second.find(aBlockState); + if (b != a->second.end()) + { + return b->second; + } + } + return NOT_FOUND; +} + + + + + +void ProtocolBlockTypePalette::clear() +{ + return mIndex.clear(); +} -- cgit v1.2.3