diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-07-26 12:44:44 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-07-26 12:44:44 +0200 |
commit | 588dce6bb0497e349fb6aac68c0a67a6560cb8a8 (patch) | |
tree | ab13af39319605a8852e261420d3f522e1968259 /src | |
parent | 64120b53a8d194b6595e5c7fb8d29aa5bde76b9e (diff) |
Core/Entities: Support setting nested updatefield types like ActivePlayerData::Research
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateField.h | 168 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.h | 2 |
2 files changed, 157 insertions, 13 deletions
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<typename T> + class UpdateFieldBase; + template<typename T, uint32 BlockBit, uint32 Bit> class UpdateField; + template<typename T> + class UpdateFieldArrayBaseWithoutSize; + + template<typename T, std::size_t Size> + class UpdateFieldArrayBase; + template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit> class UpdateFieldArray; + template<typename T> + class DynamicUpdateFieldBase; + template<typename T, uint32 BlockBit, uint32 Bit> class DynamicUpdateField; @@ -58,12 +70,18 @@ namespace UF template<typename T, bool PublicSet> struct MutableFieldReference; + template<typename T, bool PublicSet> + struct MutableNestedFieldReference; + struct IsUpdateFieldStructureTag { }; struct HasChangesMaskTag { }; + struct IsUpdateFieldHolderTag + { + }; template<typename T> struct UpdateFieldSetter @@ -237,7 +255,9 @@ namespace UF std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value, std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value, MutableFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>> + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value, + MutableNestedFieldReference<V, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> ModifyValue(UpdateField<V, BlockBit, Bit>(T::* field)) { _value._changesMask.Set(BlockBit); @@ -249,7 +269,9 @@ namespace UF std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value, std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value, MutableFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>> + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value, + MutableNestedFieldReference<V, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> ModifyValue(UpdateFieldArray<V, Size, Bit, FirstElementBit>(T::* field), uint32 index) { _value._changesMask.Set(Bit); @@ -270,7 +292,9 @@ namespace UF std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value, std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value, MutableFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>> + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value, + MutableNestedFieldReference<V, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> ModifyValue(DynamicUpdateField<V, BlockBit, Bit>(T::* field), uint32 index) { if (index >= (_value.*field).size()) @@ -299,8 +323,10 @@ namespace UF std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value, std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value, MutableFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>> - ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field), uint32) + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value, + MutableNestedFieldReference<V, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> + ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field), uint32 /*dummy*/) { if (!(_value.*field).is_initialized()) (_value.*field).ConstructValue(); @@ -330,6 +356,92 @@ namespace UF T& _value; }; + template<typename T, bool PublicSet> + struct MutableNestedFieldReference + { + using ValueType = typename T::ValueType; + + MutableNestedFieldReference(T& value) : _value(value) + { + } + + template<typename U = T> + std::enable_if_t<std::is_base_of<UpdateFieldBase<ValueType>, U>::value, + std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value, + MutableFieldReference<ValueType, PublicSet>, + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value, + MutableNestedFieldReference<ValueType, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>> + ModifyValue() + { + return { _value._value }; + } + + template<typename U = T> + std::enable_if_t<std::is_base_of<UpdateFieldArrayBaseWithoutSize<ValueType>, U>::value, + std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value, + MutableFieldReference<ValueType, PublicSet>, + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value, + MutableNestedFieldReference<ValueType, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>> + ModifyValue(uint32 index) + { + return { _value._values[index] }; + } + + template<typename U = T> + std::enable_if_t<std::is_base_of<DynamicUpdateFieldBase<ValueType>, U>::value, DynamicUpdateFieldSetter<ValueType>> + ModifyValue() + { + return { _value._values, _value._updateMask }; + } + + template<typename U = T> + std::enable_if_t<std::is_base_of<DynamicUpdateFieldBase<ValueType>, U>::value, + std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value, + MutableFieldReference<ValueType, PublicSet>, + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value, + MutableNestedFieldReference<ValueType, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>> + 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<typename U = T> + std::enable_if_t<std::is_base_of<OptionalUpdateFieldBase<ValueType>, U>::value, OptionalUpdateFieldSetter<ValueType>> + ModifyValue() + { + return { _value }; + } + + template<typename U = T> + std::enable_if_t<std::is_base_of<OptionalUpdateFieldBase<ValueType>, U>::value, + std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value, + MutableFieldReference<ValueType, PublicSet>, + std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value, + MutableNestedFieldReference<ValueType, PublicSet>, + std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>> + ModifyValue(uint32 /*dummy*/) + { + if (!_value.is_initialized()) + _value.ConstructValue(); + + return { *(_value._value) }; + } + + private: + T& _value; + }; + template<std::size_t Bits> class HasChangesMask : public HasChangesMaskTag { @@ -570,12 +682,15 @@ namespace UF Object* _owner; }; - template<typename T, uint32 BlockBit, uint32 Bit> - class UpdateField + template<typename T> + class UpdateFieldBase : public IsUpdateFieldHolderTag { template<typename F, bool PublicSet> friend struct MutableFieldReference; + template<typename F, bool PublicSet> + friend struct MutableNestedFieldReference; + template<std::size_t Bits> friend class HasChangesMask; @@ -601,12 +716,25 @@ namespace UF T _value = {}; }; - template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit> - class UpdateFieldArray + template<typename T, uint32 BlockBit, uint32 Bit> + class UpdateField : public UpdateFieldBase<T> + { + }; + + template<typename T> + class UpdateFieldArrayBaseWithoutSize : public IsUpdateFieldHolderTag + { + }; + + template<typename T, std::size_t Size> + class UpdateFieldArrayBase : public UpdateFieldArrayBaseWithoutSize<T> { template<typename F, bool PublicSet> friend struct MutableFieldReference; + template<typename F, bool PublicSet> + friend struct MutableNestedFieldReference; + template<std::size_t Bits> friend class HasChangesMask; @@ -637,15 +765,23 @@ namespace UF T _values[Size] = {}; }; + template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit> + class UpdateFieldArray : public UpdateFieldArrayBase<T, Size> + { + }; + void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data); void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data); - template<typename T, uint32 BlockBit, uint32 Bit> - class DynamicUpdateField + template<typename T> + class DynamicUpdateFieldBase : public IsUpdateFieldHolderTag { template<typename F, bool PublicSet> friend struct MutableFieldReference; + template<typename F, bool PublicSet> + friend struct MutableNestedFieldReference; + template<std::size_t Bits> friend class HasChangesMask; @@ -734,12 +870,20 @@ namespace UF std::vector<uint32> _updateMask; }; + template<typename T, uint32 BlockBit, uint32 Bit> + class DynamicUpdateField : public DynamicUpdateFieldBase<T> + { + }; + template<typename T> - class OptionalUpdateFieldBase + class OptionalUpdateFieldBase : public IsUpdateFieldHolderTag { template<typename F, bool PublicSet> friend struct MutableFieldReference; + template<typename F, bool PublicSet> + friend struct MutableNestedFieldReference; + template<std::size_t Bits> 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<bool, 0, 2> BankAutoSortDisabled; UpdateField<bool, 0, 3> SortBagsRightToLeft; UpdateField<bool, 0, 4> InsertItemsLeftToRight; - UpdateFieldArray<DynamicUpdateField<UF::Research, 4294967295, 4294967295>, 1, 22, 23> Research; + UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 22, 23> Research; DynamicUpdateField<uint64, 0, 5> KnownTitles; DynamicUpdateField<uint16, 0, 6> ResearchSites; DynamicUpdateField<uint32, 0, 7> ResearchSiteProgress; |