From 588dce6bb0497e349fb6aac68c0a67a6560cb8a8 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 26 Jul 2020 12:44:44 +0200 Subject: Core/Entities: Support setting nested updatefield types like ActivePlayerData::Research --- .../game/Entities/Object/Updates/UpdateField.h | 168 +++++++++++++++++++-- .../game/Entities/Object/Updates/UpdateFields.h | 2 +- 2 files changed, 157 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h index 4dd17a01497..33fbfa07a67 100644 --- a/src/server/game/Entities/Object/Updates/UpdateField.h +++ b/src/server/game/Entities/Object/Updates/UpdateField.h @@ -40,12 +40,24 @@ namespace UF DEFINE_ENUM_FLAG(UpdateFieldFlag); + template + class UpdateFieldBase; + template class UpdateField; + template + class UpdateFieldArrayBaseWithoutSize; + + template + class UpdateFieldArrayBase; + template class UpdateFieldArray; + template + class DynamicUpdateFieldBase; + template class DynamicUpdateField; @@ -58,12 +70,18 @@ namespace UF template struct MutableFieldReference; + template + struct MutableNestedFieldReference; + struct IsUpdateFieldStructureTag { }; struct HasChangesMaskTag { }; + struct IsUpdateFieldHolderTag + { + }; template struct UpdateFieldSetter @@ -237,7 +255,9 @@ namespace UF std::enable_if_t::value, std::conditional_t::value, MutableFieldReference, - std::conditional_t, UpdateFieldSetter>>> + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> ModifyValue(UpdateField(T::* field)) { _value._changesMask.Set(BlockBit); @@ -249,7 +269,9 @@ namespace UF std::enable_if_t::value, std::conditional_t::value, MutableFieldReference, - std::conditional_t, UpdateFieldSetter>>> + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> ModifyValue(UpdateFieldArray(T::* field), uint32 index) { _value._changesMask.Set(Bit); @@ -270,7 +292,9 @@ namespace UF std::enable_if_t::value, std::conditional_t::value, MutableFieldReference, - std::conditional_t, UpdateFieldSetter>>> + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> ModifyValue(DynamicUpdateField(T::* field), uint32 index) { if (index >= (_value.*field).size()) @@ -299,8 +323,10 @@ namespace UF std::enable_if_t::value, std::conditional_t::value, MutableFieldReference, - std::conditional_t, UpdateFieldSetter>>> - ModifyValue(OptionalUpdateField(T::* field), uint32) + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> + ModifyValue(OptionalUpdateField(T::* field), uint32 /*dummy*/) { if (!(_value.*field).is_initialized()) (_value.*field).ConstructValue(); @@ -330,6 +356,92 @@ namespace UF T& _value; }; + template + struct MutableNestedFieldReference + { + using ValueType = typename T::ValueType; + + MutableNestedFieldReference(T& value) : _value(value) + { + } + + template + std::enable_if_t, U>::value, + std::conditional_t::value, + MutableFieldReference, + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> + ModifyValue() + { + return { _value._value }; + } + + template + std::enable_if_t, U>::value, + std::conditional_t::value, + MutableFieldReference, + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> + ModifyValue(uint32 index) + { + return { _value._values[index] }; + } + + template + std::enable_if_t, U>::value, DynamicUpdateFieldSetter> + ModifyValue() + { + return { _value._values, _value._updateMask }; + } + + template + std::enable_if_t, U>::value, + std::conditional_t::value, + MutableFieldReference, + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> + ModifyValue(uint32 index) + { + if (index >= _value.size()) + { + // fill with zeros until reaching desired slot + _value._values.resize(index + 1); + _value._updateMask.resize((_value._values.size() + 31) / 32); + } + + _value.MarkChanged(index); + return { _value._values[index] }; + } + + template + std::enable_if_t, U>::value, OptionalUpdateFieldSetter> + ModifyValue() + { + return { _value }; + } + + template + std::enable_if_t, U>::value, + std::conditional_t::value, + MutableFieldReference, + std::conditional_t::value, + MutableNestedFieldReference, + std::conditional_t, UpdateFieldSetter>>>> + ModifyValue(uint32 /*dummy*/) + { + if (!_value.is_initialized()) + _value.ConstructValue(); + + return { *(_value._value) }; + } + + private: + T& _value; + }; + template class HasChangesMask : public HasChangesMaskTag { @@ -570,12 +682,15 @@ namespace UF Object* _owner; }; - template - class UpdateField + template + class UpdateFieldBase : public IsUpdateFieldHolderTag { template friend struct MutableFieldReference; + template + friend struct MutableNestedFieldReference; + template friend class HasChangesMask; @@ -601,12 +716,25 @@ namespace UF T _value = {}; }; - template - class UpdateFieldArray + template + class UpdateField : public UpdateFieldBase + { + }; + + template + class UpdateFieldArrayBaseWithoutSize : public IsUpdateFieldHolderTag + { + }; + + template + class UpdateFieldArrayBase : public UpdateFieldArrayBaseWithoutSize { template friend struct MutableFieldReference; + template + friend struct MutableNestedFieldReference; + template friend class HasChangesMask; @@ -637,15 +765,23 @@ namespace UF T _values[Size] = {}; }; + template + class UpdateFieldArray : public UpdateFieldArrayBase + { + }; + void WriteDynamicFieldUpdateMask(std::size_t size, std::vector const& updateMask, ByteBuffer& data); void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data); - template - class DynamicUpdateField + template + class DynamicUpdateFieldBase : public IsUpdateFieldHolderTag { template friend struct MutableFieldReference; + template + friend struct MutableNestedFieldReference; + template friend class HasChangesMask; @@ -734,12 +870,20 @@ namespace UF std::vector _updateMask; }; + template + class DynamicUpdateField : public DynamicUpdateFieldBase + { + }; + template - class OptionalUpdateFieldBase + class OptionalUpdateFieldBase : public IsUpdateFieldHolderTag { template friend struct MutableFieldReference; + template + friend struct MutableNestedFieldReference; + template friend class HasChangesMask; diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index a1fb875fcc6..f2faeffd2c5 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -537,7 +537,7 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas UpdateField BankAutoSortDisabled; UpdateField SortBagsRightToLeft; UpdateField InsertItemsLeftToRight; - UpdateFieldArray, 1, 22, 23> Research; + UpdateFieldArray, 1, 22, 23> Research; DynamicUpdateField KnownTitles; DynamicUpdateField ResearchSites; DynamicUpdateField ResearchSiteProgress; -- cgit v1.2.3