mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-08-20 09:57:10 +00:00
Merge branch 'rubicon' of https://github.com/4jcraft/4jcraft into rubicon
This commit is contained in:
commit
6aed95749f
|
|
@ -40,7 +40,6 @@ endif
|
||||||
add_project_arguments(global_cpp_defs, language: ['cpp', 'c'])
|
add_project_arguments(global_cpp_defs, language: ['cpp', 'c'])
|
||||||
|
|
||||||
global_cpp_args = [
|
global_cpp_args = [
|
||||||
'-fpermissive',
|
|
||||||
'-Wshift-count-overflow',
|
'-Wshift-count-overflow',
|
||||||
'-pipe',
|
'-pipe',
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,9 @@ void FallingTile::tick() {
|
||||||
if (tileEntity != nullptr) {
|
if (tileEntity != nullptr) {
|
||||||
CompoundTag* swap = new CompoundTag();
|
CompoundTag* swap = new CompoundTag();
|
||||||
tileEntity->save(swap);
|
tileEntity->save(swap);
|
||||||
std::vector<Tag*>* allTags = tileData->getAllTags();
|
std::vector<Tag*> allTags = tileData->getAllTags();
|
||||||
for (auto it = allTags->begin();
|
for (auto it = allTags.begin();
|
||||||
it != allTags->end(); ++it) {
|
it != allTags.end(); ++it) {
|
||||||
Tag* tag = *it;
|
Tag* tag = *it;
|
||||||
if (tag->getName().compare(L"x") == 0 ||
|
if (tag->getName().compare(L"x") == 0 ||
|
||||||
tag->getName().compare(L"y") == 0 ||
|
tag->getName().compare(L"y") == 0 ||
|
||||||
|
|
@ -132,7 +132,6 @@ void FallingTile::tick() {
|
||||||
continue;
|
continue;
|
||||||
swap->put(tag->getName(), tag->copy());
|
swap->put(tag->getName(), tag->copy());
|
||||||
}
|
}
|
||||||
delete allTags;
|
|
||||||
tileEntity->load(swap);
|
tileEntity->load(swap);
|
||||||
tileEntity->setChanged();
|
tileEntity->setChanged();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,12 +133,11 @@ std::shared_ptr<Entity> BaseMobSpawner::loadDataAndAddEntity(
|
||||||
CompoundTag* data = new CompoundTag();
|
CompoundTag* data = new CompoundTag();
|
||||||
entity->save(data);
|
entity->save(data);
|
||||||
|
|
||||||
std::vector<Tag*>* tags = getNextSpawnData()->tag->getAllTags();
|
std::vector<Tag*> tags = getNextSpawnData()->tag->getAllTags();
|
||||||
for (auto it = tags->begin(); it != tags->end(); ++it) {
|
for (auto it = tags.begin(); it != tags.end(); ++it) {
|
||||||
Tag* tag = *it;
|
Tag* tag = *it;
|
||||||
data->put(tag->getName(), tag->copy());
|
data->put(tag->getName(), tag->copy());
|
||||||
}
|
}
|
||||||
delete tags;
|
|
||||||
|
|
||||||
entity->load(data);
|
entity->load(data);
|
||||||
if (entity->level != nullptr) entity->level->addEntity(entity);
|
if (entity->level != nullptr) entity->level->addEntity(entity);
|
||||||
|
|
@ -153,13 +152,12 @@ std::shared_ptr<Entity> BaseMobSpawner::loadDataAndAddEntity(
|
||||||
CompoundTag* mountData = new CompoundTag();
|
CompoundTag* mountData = new CompoundTag();
|
||||||
mount->save(mountData);
|
mount->save(mountData);
|
||||||
|
|
||||||
std::vector<Tag*>* ridingTags = ridingTag->getAllTags();
|
std::vector<Tag*> ridingTags = ridingTag->getAllTags();
|
||||||
for (auto it = ridingTags->begin(); it != ridingTags->end();
|
for (auto it = ridingTags.begin(); it != ridingTags.end();
|
||||||
++it) {
|
++it) {
|
||||||
Tag* tag = *it;
|
Tag* tag = *it;
|
||||||
mountData->put(tag->getName(), tag->copy());
|
mountData->put(tag->getName(), tag->copy());
|
||||||
}
|
}
|
||||||
delete ridingTags;
|
|
||||||
mount->load(mountData);
|
mount->load(mountData);
|
||||||
mount->moveTo(rider->x, rider->y, rider->z, rider->yRot,
|
mount->moveTo(rider->x, rider->y, rider->z, rider->yRot,
|
||||||
rider->xRot);
|
rider->xRot);
|
||||||
|
|
|
||||||
|
|
@ -127,8 +127,8 @@ CompoundTag *GameRules::createTag()
|
||||||
|
|
||||||
void GameRules::loadFromTag(CompoundTag *tag)
|
void GameRules::loadFromTag(CompoundTag *tag)
|
||||||
{
|
{
|
||||||
vector<Tag *> *allTags = tag->getAllTags();
|
vector<Tag *> allTags = tag->getAllTags();
|
||||||
for (auto it = allTags->begin(); it != allTags->end(); ++it)
|
for (auto it = allTags.begin(); it != allTags.end(); ++it)
|
||||||
{
|
{
|
||||||
Tag *ruleTag = *it;
|
Tag *ruleTag = *it;
|
||||||
std::wstring ruleName = ruleTag->getName();
|
std::wstring ruleName = ruleTag->getName();
|
||||||
|
|
@ -136,7 +136,6 @@ void GameRules::loadFromTag(CompoundTag *tag)
|
||||||
|
|
||||||
set(ruleName, value);
|
set(ruleName, value);
|
||||||
}
|
}
|
||||||
delete allTags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to delete returned vector.
|
// Need to delete returned vector.
|
||||||
|
|
|
||||||
|
|
@ -252,8 +252,8 @@ void StructureFeature::restoreSavedData(Level* level) {
|
||||||
} else {
|
} else {
|
||||||
CompoundTag* fullTag = savedData->getFullTag();
|
CompoundTag* fullTag = savedData->getFullTag();
|
||||||
|
|
||||||
std::vector<Tag*>* allTags = fullTag->getAllTags();
|
std::vector<Tag*> allTags = fullTag->getAllTags();
|
||||||
for (auto it = allTags->begin(); it != allTags->end(); ++it) {
|
for (auto it = allTags.begin(); it != allTags.end(); ++it) {
|
||||||
Tag* featureTag = *it;
|
Tag* featureTag = *it;
|
||||||
if (featureTag->getId() == Tag::TAG_Compound) {
|
if (featureTag->getId() == Tag::TAG_Compound) {
|
||||||
CompoundTag* ct = (CompoundTag*)featureTag;
|
CompoundTag* ct = (CompoundTag*)featureTag;
|
||||||
|
|
|
||||||
|
|
@ -134,10 +134,10 @@ void SavedDataStorage::loadAuxValues() {
|
||||||
dis.close();
|
dis.close();
|
||||||
|
|
||||||
Tag* tag;
|
Tag* tag;
|
||||||
std::vector<Tag*>* allTags = tags->getAllTags();
|
std::vector<Tag*> allTags = tags->getAllTags();
|
||||||
auto itEnd = allTags->end();
|
auto itEnd = allTags.end();
|
||||||
for (auto it = allTags->begin(); it != itEnd; it++) {
|
for (auto it = allTags.begin(); it != itEnd; it++) {
|
||||||
tag = *it; // tags->getAllTags()->at(i);
|
tag = *it;
|
||||||
|
|
||||||
if (dynamic_cast<ShortTag*>(tag) != nullptr) {
|
if (dynamic_cast<ShortTag*>(tag) != nullptr) {
|
||||||
ShortTag* sTag = (ShortTag*)tag;
|
ShortTag* sTag = (ShortTag*)tag;
|
||||||
|
|
@ -146,7 +146,6 @@ void SavedDataStorage::loadAuxValues() {
|
||||||
usedAuxIds.insert(uaiMapType::value_type(id, val));
|
usedAuxIds.insert(uaiMapType::value_type(id, val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete allTags;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,21 +11,20 @@
|
||||||
#include "ByteArrayTag.h"
|
#include "ByteArrayTag.h"
|
||||||
#include "IntArrayTag.h"
|
#include "IntArrayTag.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
class CompoundTag : public Tag {
|
class CompoundTag : public Tag {
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::wstring, Tag*> tags;
|
std::unordered_map<std::wstring, std::unique_ptr<Tag>> tags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompoundTag() : Tag(L"") {}
|
CompoundTag() : Tag(L"") {}
|
||||||
CompoundTag(const std::wstring& name) : Tag(name) {}
|
CompoundTag(const std::wstring& name) : Tag(name) {}
|
||||||
|
|
||||||
void write(DataOutput* dos) {
|
void write(DataOutput* dos) {
|
||||||
auto itEnd = tags.end();
|
for (auto& [key, value] : tags) {
|
||||||
for (std::unordered_map<std::wstring, Tag*>::iterator it = tags.begin();
|
Tag::writeNamedTag(value.get(), dos);
|
||||||
it != itEnd; it++) {
|
|
||||||
Tag::writeNamedTag(it->second, dos);
|
|
||||||
}
|
}
|
||||||
dos->writeByte(Tag::TAG_End);
|
dos->writeByte(Tag::TAG_End);
|
||||||
}
|
}
|
||||||
|
|
@ -39,22 +38,19 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tags.clear();
|
tags.clear();
|
||||||
Tag* tag;
|
for (;;) {
|
||||||
while ((tag = Tag::readNamedTag(dis))->getId() != Tag::TAG_End) {
|
std::unique_ptr<Tag> tag(Tag::readNamedTag(dis));
|
||||||
tags[tag->getName()] = tag;
|
if (tag->getId() == Tag::TAG_End) break;
|
||||||
|
auto name = tag->getName();
|
||||||
|
tags[name] = std::move(tag);
|
||||||
}
|
}
|
||||||
delete tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Tag*>* getAllTags() // 4J - was collection
|
std::vector<Tag*> getAllTags() {
|
||||||
{
|
std::vector<Tag*> ret;
|
||||||
// 4J - was return tags.values();
|
ret.reserve(tags.size());
|
||||||
std::vector<Tag*>* ret = new std::vector<Tag*>;
|
for (auto& [key, value] : tags) {
|
||||||
|
ret.push_back(value.get());
|
||||||
auto itEnd = tags.end();
|
|
||||||
for (std::unordered_map<std::wstring, Tag*>::iterator it = tags.begin();
|
|
||||||
it != itEnd; it++) {
|
|
||||||
ret->push_back(it->second);
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -62,47 +58,49 @@ public:
|
||||||
uint8_t getId() { return TAG_Compound; }
|
uint8_t getId() { return TAG_Compound; }
|
||||||
|
|
||||||
void put(const std::wstring& name, Tag* tag) {
|
void put(const std::wstring& name, Tag* tag) {
|
||||||
tags[name] = tag->setName(name);
|
tag->setName(name);
|
||||||
|
tags[name] = std::unique_ptr<Tag>(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putByte(const std::wstring& name, uint8_t value) {
|
void putByte(const std::wstring& name, uint8_t value) {
|
||||||
tags[name] = (new ByteTag(name, value));
|
tags[name] = std::make_unique<ByteTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putShort(const std::wstring& name, short value) {
|
void putShort(const std::wstring& name, short value) {
|
||||||
tags[name] = (new ShortTag(name, value));
|
tags[name] = std::make_unique<ShortTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putInt(const std::wstring& name, int value) {
|
void putInt(const std::wstring& name, int value) {
|
||||||
tags[name] = (new IntTag(name, value));
|
tags[name] = std::make_unique<IntTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putLong(const std::wstring& name, int64_t value) {
|
void putLong(const std::wstring& name, int64_t value) {
|
||||||
tags[name] = (new LongTag(name, value));
|
tags[name] = std::make_unique<LongTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putFloat(const std::wstring& name, float value) {
|
void putFloat(const std::wstring& name, float value) {
|
||||||
tags[name] = (new FloatTag(name, value));
|
tags[name] = std::make_unique<FloatTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putDouble(const std::wstring& name, double value) {
|
void putDouble(const std::wstring& name, double value) {
|
||||||
tags[name] = (new DoubleTag(name, value));
|
tags[name] = std::make_unique<DoubleTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putString(const std::wstring& name, const std::wstring& value) {
|
void putString(const std::wstring& name, const std::wstring& value) {
|
||||||
tags[name] = (new StringTag(name, value));
|
tags[name] = std::make_unique<StringTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putByteArray(const std::wstring& name, std::vector<uint8_t>& value) {
|
void putByteArray(const std::wstring& name, std::vector<uint8_t>& value) {
|
||||||
tags[name] = (new ByteArrayTag(name, value));
|
tags[name] = std::make_unique<ByteArrayTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putIntArray(const std::wstring& name, std::vector<int>& value) {
|
void putIntArray(const std::wstring& name, std::vector<int>& value) {
|
||||||
tags[name] = (new IntArrayTag(name, value));
|
tags[name] = std::make_unique<IntArrayTag>(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putCompound(const std::wstring& name, CompoundTag* value) {
|
void putCompound(const std::wstring& name, CompoundTag* value) {
|
||||||
tags[name] = value->setName(std::wstring(name));
|
value->setName(name);
|
||||||
|
tags[name] = std::unique_ptr<Tag>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putBoolean(const std::wstring& name, bool val) {
|
void putBoolean(const std::wstring& name, bool val) {
|
||||||
|
|
@ -111,7 +109,7 @@ public:
|
||||||
|
|
||||||
Tag* get(const std::wstring& name) {
|
Tag* get(const std::wstring& name) {
|
||||||
auto it = tags.find(name);
|
auto it = tags.find(name);
|
||||||
if (it != tags.end()) return it->second;
|
if (it != tags.end()) return it->second.get();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,72 +118,87 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getByte(const std::wstring& name) {
|
uint8_t getByte(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return (uint8_t)0;
|
auto it = tags.find(name);
|
||||||
return ((ByteTag*)tags[name])->data;
|
if (it == tags.end()) return 0;
|
||||||
|
return static_cast<ByteTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
short getShort(const std::wstring& name) {
|
short getShort(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return (short)0;
|
auto it = tags.find(name);
|
||||||
return ((ShortTag*)tags[name])->data;
|
if (it == tags.end()) return 0;
|
||||||
|
return static_cast<ShortTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getInt(const std::wstring& name) {
|
int getInt(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return (int)0;
|
auto it = tags.find(name);
|
||||||
return ((IntTag*)tags[name])->data;
|
if (it == tags.end()) return 0;
|
||||||
|
return static_cast<IntTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t getLong(const std::wstring& name) {
|
int64_t getLong(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return (int64_t)0;
|
auto it = tags.find(name);
|
||||||
return ((LongTag*)tags[name])->data;
|
if (it == tags.end()) return 0;
|
||||||
|
return static_cast<LongTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getFloat(const std::wstring& name) {
|
float getFloat(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return (float)0;
|
auto it = tags.find(name);
|
||||||
return ((FloatTag*)tags[name])->data;
|
if (it == tags.end()) return 0;
|
||||||
|
return static_cast<FloatTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getDouble(const std::wstring& name) {
|
double getDouble(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return (double)0;
|
auto it = tags.find(name);
|
||||||
return ((DoubleTag*)tags[name])->data;
|
if (it == tags.end()) return 0;
|
||||||
|
return static_cast<DoubleTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring getString(const std::wstring& name) {
|
std::wstring getString(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return std::wstring(L"");
|
auto it = tags.find(name);
|
||||||
return ((StringTag*)tags[name])->data;
|
if (it == tags.end()) return std::wstring(L"");
|
||||||
|
return static_cast<StringTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> getByteArray(const std::wstring& name) {
|
std::vector<uint8_t> getByteArray(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return std::vector<uint8_t>();
|
auto it = tags.find(name);
|
||||||
return ((ByteArrayTag*)tags[name])->data;
|
if (it == tags.end()) return std::vector<uint8_t>();
|
||||||
|
return static_cast<ByteArrayTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> getIntArray(const std::wstring& name) {
|
std::vector<int> getIntArray(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return std::vector<int>();
|
auto it = tags.find(name);
|
||||||
return ((IntArrayTag*)tags[name])->data;
|
if (it == tags.end()) return std::vector<int>();
|
||||||
|
return static_cast<IntArrayTag*>(it->second.get())->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompoundTag* getCompound(const std::wstring& name) {
|
CompoundTag* getCompound(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return new CompoundTag(name);
|
auto it = tags.find(name);
|
||||||
return (CompoundTag*)tags[name];
|
if (it == tags.end()) {
|
||||||
|
auto [it2, inserted] = tags.emplace(name, std::make_unique<CompoundTag>(name));
|
||||||
|
return static_cast<CompoundTag*>(it2->second.get());
|
||||||
|
}
|
||||||
|
return static_cast<CompoundTag*>(it->second.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
ListTag<Tag>* getList(const std::wstring& name) {
|
ListTag<Tag>* getList(const std::wstring& name) {
|
||||||
if (tags.find(name) == tags.end()) return new ListTag<Tag>(name);
|
auto it = tags.find(name);
|
||||||
return (ListTag<Tag>*)tags[name];
|
if (it == tags.end()) {
|
||||||
|
auto [it2, inserted] = tags.emplace(name, std::make_unique<ListTag<Tag>>(name));
|
||||||
|
return static_cast<ListTag<Tag>*>(it2->second.get());
|
||||||
|
}
|
||||||
|
return static_cast<ListTag<Tag>*>(it->second.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getBoolean(const std::wstring& string) { return getByte(string) != 0; }
|
bool getBoolean(const std::wstring& string) { return getByte(string) != 0; }
|
||||||
|
|
||||||
void remove(const std::wstring& name) {
|
void remove(const std::wstring& name) {
|
||||||
auto it = tags.find(name);
|
tags.erase(name);
|
||||||
if (it != tags.end()) tags.erase(it);
|
|
||||||
// tags.remove(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring toString() {
|
std::wstring toString() {
|
||||||
static const int bufSize = 32;
|
static const int bufSize = 32;
|
||||||
static wchar_t buf[bufSize];
|
static wchar_t buf[bufSize];
|
||||||
swprintf(buf, bufSize, L"%d entries", tags.size());
|
swprintf(buf, bufSize, L"%zu entries", tags.size());
|
||||||
return std::wstring(buf);
|
return std::wstring(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,19 +224,12 @@ public:
|
||||||
|
|
||||||
bool isEmpty() { return tags.empty(); }
|
bool isEmpty() { return tags.empty(); }
|
||||||
|
|
||||||
virtual ~CompoundTag() {
|
virtual ~CompoundTag() = default;
|
||||||
auto itEnd = tags.end();
|
|
||||||
for (auto it = tags.begin(); it != itEnd; it++) {
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Tag* copy() {
|
Tag* copy() {
|
||||||
CompoundTag* tag = new CompoundTag(getName());
|
CompoundTag* tag = new CompoundTag(getName());
|
||||||
|
for (auto& [key, value] : tags) {
|
||||||
auto itEnd = tags.end();
|
tag->put(key, value->copy());
|
||||||
for (auto it = tags.begin(); it != itEnd; it++) {
|
|
||||||
tag->put((wchar_t*)it->first.c_str(), it->second->copy());
|
|
||||||
}
|
}
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
@ -233,18 +239,14 @@ public:
|
||||||
CompoundTag* o = (CompoundTag*)obj;
|
CompoundTag* o = (CompoundTag*)obj;
|
||||||
|
|
||||||
if (tags.size() == o->tags.size()) {
|
if (tags.size() == o->tags.size()) {
|
||||||
bool equal = true;
|
for (auto& [key, value] : tags) {
|
||||||
auto itEnd = tags.end();
|
auto itFind = o->tags.find(key);
|
||||||
for (auto it = tags.begin(); it != itEnd; it++) {
|
|
||||||
auto itFind = o->tags.find(it->first);
|
|
||||||
if (itFind == o->tags.end() ||
|
if (itFind == o->tags.end() ||
|
||||||
!it->second->equals(itFind->second)) {
|
!value->equals(itFind->second.get())) {
|
||||||
equal = false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return equal;
|
return true;
|
||||||
// return tags.entrySet().equals(o.tags.entrySet());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Tag.h"
|
#include "Tag.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class ListTag : public Tag {
|
class ListTag : public Tag {
|
||||||
private:
|
private:
|
||||||
std::vector<Tag*> list;
|
std::vector<std::unique_ptr<Tag>> list;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -15,15 +16,14 @@ public:
|
||||||
|
|
||||||
void write(DataOutput* dos) {
|
void write(DataOutput* dos) {
|
||||||
if (list.size() > 0)
|
if (list.size() > 0)
|
||||||
type = (list[0])->getId();
|
type = list[0]->getId();
|
||||||
else
|
else
|
||||||
type = static_cast<uint8_t>(1);
|
type = static_cast<uint8_t>(1);
|
||||||
|
|
||||||
dos->writeByte(type);
|
dos->writeByte(type);
|
||||||
dos->writeInt((int)list.size());
|
dos->writeInt((int)list.size());
|
||||||
|
|
||||||
auto itEnd = list.end();
|
for (auto& tag : list) tag->write(dos);
|
||||||
for (auto it = list.begin(); it != itEnd; it++) (*it)->write(dos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(DataInput* dis, int tagDepth) {
|
void load(DataInput* dis, int tagDepth) {
|
||||||
|
|
@ -39,9 +39,9 @@ public:
|
||||||
|
|
||||||
list.clear();
|
list.clear();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
Tag* tag = Tag::newTag(type, L"");
|
std::unique_ptr<Tag> tag(Tag::newTag(type, L""));
|
||||||
tag->load(dis, tagDepth);
|
tag->load(dis, tagDepth);
|
||||||
list.push_back(tag);
|
list.push_back(std::move(tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ public:
|
||||||
|
|
||||||
std::wstring toString() {
|
std::wstring toString() {
|
||||||
static wchar_t buf[64];
|
static wchar_t buf[64];
|
||||||
swprintf(buf, 64, L"%d entries of type %ls", list.size(),
|
swprintf(buf, 64, L"%zu entries of type %ls", list.size(),
|
||||||
Tag::getTagName(type));
|
Tag::getTagName(type));
|
||||||
return std::wstring(buf);
|
return std::wstring(buf);
|
||||||
}
|
}
|
||||||
|
|
@ -62,9 +62,8 @@ public:
|
||||||
char* newPrefix = new char[strlen(prefix) + 4];
|
char* newPrefix = new char[strlen(prefix) + 4];
|
||||||
strcpy(newPrefix, prefix);
|
strcpy(newPrefix, prefix);
|
||||||
strcat(newPrefix, " ");
|
strcat(newPrefix, " ");
|
||||||
auto itEnd = list.end();
|
for (auto& tag : list) {
|
||||||
for (auto it = list.begin(); it != itEnd; it++) {
|
tag->print(newPrefix, out);
|
||||||
(*it)->print(newPrefix, out);
|
|
||||||
}
|
}
|
||||||
delete[] newPrefix;
|
delete[] newPrefix;
|
||||||
out << prefix << "}" << std::endl;
|
out << prefix << "}" << std::endl;
|
||||||
|
|
@ -78,27 +77,20 @@ public:
|
||||||
// other items that also use list tags and require equality checks to
|
// other items that also use list tags and require equality checks to
|
||||||
// work) considering we can't change the write/load functions.
|
// work) considering we can't change the write/load functions.
|
||||||
tag->setName(L"");
|
tag->setName(L"");
|
||||||
list.push_back(tag);
|
list.push_back(std::unique_ptr<Tag>(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get(int index) { return (T*)list[index]; }
|
T* get(int index) { return static_cast<T*>(list[index].get()); }
|
||||||
|
|
||||||
int size() { return (int)list.size(); }
|
int size() { return (int)list.size(); }
|
||||||
|
|
||||||
virtual ~ListTag() {
|
virtual ~ListTag() = default;
|
||||||
auto itEnd = list.end();
|
|
||||||
for (auto it = list.begin(); it != itEnd; it++) {
|
|
||||||
delete *it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Tag* copy() {
|
virtual Tag* copy() {
|
||||||
ListTag<T>* res = new ListTag<T>(getName());
|
ListTag<T>* res = new ListTag<T>(getName());
|
||||||
res->type = type;
|
res->type = type;
|
||||||
auto itEnd = list.end();
|
for (auto& tag : list) {
|
||||||
for (auto it = list.begin(); it != itEnd; it++) {
|
res->list.push_back(std::unique_ptr<Tag>(tag->copy()));
|
||||||
T* copy = (T*)(*it)->copy();
|
|
||||||
res->list.push_back(copy);
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -110,15 +102,13 @@ public:
|
||||||
bool equal = false;
|
bool equal = false;
|
||||||
if (list.size() == o->list.size()) {
|
if (list.size() == o->list.size()) {
|
||||||
equal = true;
|
equal = true;
|
||||||
auto itEnd = list.end();
|
|
||||||
// 4J Stu - Pretty inefficient method, but I think we can
|
// 4J Stu - Pretty inefficient method, but I think we can
|
||||||
// live with it give how often it will happen, and the small
|
// live with it give how often it will happen, and the small
|
||||||
// sizes of the data sets
|
// sizes of the data sets
|
||||||
for (auto it = list.begin(); it != itEnd; ++it) {
|
for (auto& tag : list) {
|
||||||
bool thisMatches = false;
|
bool thisMatches = false;
|
||||||
for (auto it2 = o->list.begin(); it2 != o->list.end();
|
for (auto& otherTag : o->list) {
|
||||||
++it2) {
|
if (tag->equals(otherTag.get())) {
|
||||||
if ((*it)->equals(*it2)) {
|
|
||||||
thisMatches = true;
|
thisMatches = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -135,4 +125,4 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue