diff options
author | Shauren <shauren.trinity@gmail.com> | 2025-06-28 19:43:01 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2025-06-28 19:43:01 +0200 |
commit | 68588dbb25d2cb45757764db187d5e66b7726305 (patch) | |
tree | 810d72f282d8d83131c753c1668394b3eb4b9c90 | |
parent | 4c92d3550b331aff6a22f753295388fa2a215e6c (diff) |
Core/Objects: Modernize updatefield internals - replace tag dispatch and std::enable if
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 16 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateField.h | 233 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.cpp | 80 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateMask.h | 4 |
4 files changed, 165 insertions, 168 deletions
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index fcbcedf77a5..b5940dc0b73 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -143,7 +143,7 @@ namespace UF }; template<typename T> - inline bool SetUpdateFieldValue(UpdateFieldSetter<T>& setter, typename UpdateFieldSetter<T>::value_type&& value) + inline bool SetUpdateFieldValue(UpdateFieldPrivateSetter<T>& setter, typename UpdateFieldPrivateSetter<T>::value_type&& value) { return setter.SetValue(std::move(value)); } @@ -304,7 +304,7 @@ class TC_GAME_API Object UF::UpdateField<UF::ObjectData, int32(WowCS::EntityFragment::CGObject), TYPEID_OBJECT> m_objectData; template<typename T> - void ForceUpdateFieldChange(UF::UpdateFieldSetter<T> const& /*setter*/) + void ForceUpdateFieldChange(UF::UpdateFieldPrivateSetter<T> const& /*setter*/) { AddToObjectUpdateIfNeeded(); } @@ -323,21 +323,21 @@ class TC_GAME_API Object void _Create(ObjectGuid const& guid); template<typename T> - void SetUpdateFieldValue(UF::UpdateFieldSetter<T> setter, typename UF::UpdateFieldSetter<T>::value_type value) + void SetUpdateFieldValue(UF::UpdateFieldPrivateSetter<T> setter, typename UF::UpdateFieldPrivateSetter<T>::value_type value) { if (UF::SetUpdateFieldValue(setter, std::move(value))) AddToObjectUpdateIfNeeded(); } template<typename T> - void SetUpdateFieldFlagValue(UF::UpdateFieldSetter<T> setter, typename UF::UpdateFieldSetter<T>::value_type flag) + void SetUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter<T> setter, typename UF::UpdateFieldPrivateSetter<T>::value_type flag) { static_assert(std::is_integral<T>::value, "SetUpdateFieldFlagValue must be used with integral types"); SetUpdateFieldValue(setter, setter.GetValue() | flag); } template<typename T> - void RemoveUpdateFieldFlagValue(UF::UpdateFieldSetter<T> setter, typename UF::UpdateFieldSetter<T>::value_type flag) + void RemoveUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter<T> setter, typename UF::UpdateFieldPrivateSetter<T>::value_type flag) { static_assert(std::is_integral<T>::value, "RemoveUpdateFieldFlagValue must be used with integral types"); SetUpdateFieldValue(setter, setter.GetValue() & ~flag); @@ -380,14 +380,14 @@ class TC_GAME_API Object // stat system helpers template<typename T> - void SetUpdateFieldStatValue(UF::UpdateFieldSetter<T> setter, typename UF::UpdateFieldSetter<T>::value_type value) + void SetUpdateFieldStatValue(UF::UpdateFieldPrivateSetter<T> setter, typename UF::UpdateFieldPrivateSetter<T>::value_type value) { static_assert(std::is_arithmetic<T>::value, "SetUpdateFieldStatValue must be used with arithmetic types"); SetUpdateFieldValue(setter, std::max(value, T(0))); } template<typename T> - void ApplyModUpdateFieldValue(UF::UpdateFieldSetter<T> setter, typename UF::UpdateFieldSetter<T>::value_type mod, bool apply) + void ApplyModUpdateFieldValue(UF::UpdateFieldPrivateSetter<T> setter, typename UF::UpdateFieldPrivateSetter<T>::value_type mod, bool apply) { static_assert(std::is_arithmetic<T>::value, "SetUpdateFieldStatValue must be used with arithmetic types"); @@ -401,7 +401,7 @@ class TC_GAME_API Object } template<typename T> - void ApplyPercentModUpdateFieldValue(UF::UpdateFieldSetter<T> setter, float percent, bool apply) + void ApplyPercentModUpdateFieldValue(UF::UpdateFieldPrivateSetter<T> setter, float percent, bool apply) { static_assert(std::is_arithmetic<T>::value, "SetUpdateFieldStatValue must be used with arithmetic types"); diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h index 930f055c655..2e2b40ac8b1 100644 --- a/src/server/game/Entities/Object/Updates/UpdateField.h +++ b/src/server/game/Entities/Object/Updates/UpdateField.h @@ -69,7 +69,10 @@ namespace UF class OptionalUpdateField; template<typename T, bool PublicSet> - struct MutableFieldReference; + struct MutableFieldReferenceWithChangesMask; + + template<typename T, bool PublicSet> + struct MutableFieldReferenceNoChangesMask; template<typename T, bool PublicSet> struct MutableNestedFieldReference; @@ -85,14 +88,14 @@ namespace UF }; template<typename T> - struct UpdateFieldSetter + struct UpdateFieldPrivateSetter { using value_type = T; template<typename F> - friend bool SetUpdateFieldValue(UpdateFieldSetter<F>& setter, typename UpdateFieldSetter<F>::value_type&& value); + friend bool SetUpdateFieldValue(UpdateFieldPrivateSetter<F>& setter, typename UpdateFieldPrivateSetter<F>::value_type&& value); - UpdateFieldSetter(T& value) : _value(value) + UpdateFieldPrivateSetter(T& value) : _value(value) { } @@ -139,6 +142,14 @@ namespace UF T& _value; }; + template<typename T, bool PublicSet> + using UpdateFieldSetter = std::conditional_t<PublicSet, UpdateFieldPublicSetter<T>, UpdateFieldPrivateSetter<T>>; + + template<typename T, bool PublicSet> + using MutableFieldReference = std::conditional_t<std::is_base_of_v<HasChangesMaskTag, T>, + MutableFieldReferenceWithChangesMask<T, PublicSet>, + MutableFieldReferenceNoChangesMask<T, PublicSet>>; + template<typename T> struct DynamicUpdateFieldSetter { @@ -165,9 +176,9 @@ namespace UF insert_result AddValue() { MarkChanged(_values.size()); - _values.emplace_back(); - T& value = _values.back(); - MarkNewValue(value, std::is_base_of<HasChangesMaskTag, T>{}); + T& value = _values.emplace_back(); + if constexpr (std::is_base_of_v<HasChangesMaskTag, T>) + value._changesMask.SetAll(); return { value }; } @@ -178,7 +189,8 @@ namespace UF { MarkChanged(i); // also mark all fields of value as changed - MarkNewValue(_values[i], std::is_base_of<HasChangesMaskTag, T>{}); + if constexpr (std::is_base_of_v<HasChangesMaskTag, T>) + _values[i]._changesMask.SetAll(); } return { _values[index] }; } @@ -191,7 +203,8 @@ namespace UF { MarkChanged(i); // also mark all fields of value as changed - MarkNewValue(_values[i], std::is_base_of<HasChangesMaskTag, T>{}); + if constexpr (std::is_base_of_v<HasChangesMaskTag, T>) + _values[i]._changesMask.SetAll(); } if (_values.size() % 32) _updateMask[UpdateMaskHelpers::GetBlockIndex(_values.size())] &= ~UpdateMaskHelpers::GetBlockFlag(_values.size()); @@ -214,15 +227,6 @@ namespace UF _updateMask[block] |= UpdateMaskHelpers::GetBlockFlag(index); } - static void MarkNewValue(T&, std::false_type) - { - } - - static void MarkNewValue(T& value, std::true_type) - { - value._changesMask.SetAll(); - } - std::vector<T>& _values; std::vector<uint32>& _updateMask; }; @@ -246,19 +250,18 @@ namespace UF }; template<typename T, bool PublicSet> - struct MutableFieldReference + struct MutableFieldReferenceWithChangesMask { - MutableFieldReference(T& value) : _value(value) + MutableFieldReferenceWithChangesMask(T& value) : _value(value) { } - template<typename V, int32 BlockBit, uint32 Bit, typename U = T> - std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, - std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, + template<typename V, int32 BlockBit, uint32 Bit> + std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, MutableFieldReference<V, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>, MutableNestedFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> + UpdateFieldSetter<V, PublicSet>>> ModifyValue(UpdateField<V, BlockBit, Bit>(T::* field)) { if constexpr (BlockBit >= 0) @@ -268,13 +271,12 @@ namespace UF return { (_value.*field)._value }; } - template<typename V, std::size_t Size, uint32 Bit, int32 FirstElementBit, typename U = T> - std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, - std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, + template<typename V, std::size_t Size, uint32 Bit, int32 FirstElementBit> + std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, MutableFieldReference<V, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>, MutableNestedFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> + UpdateFieldSetter<V, PublicSet>>> ModifyValue(UpdateFieldArray<V, Size, Bit, FirstElementBit>(T::* field), uint32 index) { _value._changesMask.Set(Bit); @@ -289,9 +291,8 @@ namespace UF return { (_value.*field)._values[index] }; } - template<typename V, int32 BlockBit, uint32 Bit, typename U = T> - std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, DynamicUpdateFieldSetter<V>> - ModifyValue(DynamicUpdateField<V, BlockBit, Bit>(T::* field)) + template<typename V, int32 BlockBit, uint32 Bit> + DynamicUpdateFieldSetter<V> ModifyValue(DynamicUpdateField<V, BlockBit, Bit>(T::* field)) { if constexpr (BlockBit >= 0) _value._changesMask.Set(BlockBit); @@ -300,20 +301,19 @@ namespace UF return { (_value.*field)._values, (_value.*field)._updateMask }; } - template<typename V, int32 BlockBit, uint32 Bit, typename U = T> - std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, - std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, + template<typename V, int32 BlockBit, uint32 Bit> + std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, MutableFieldReference<V, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>, MutableNestedFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> + UpdateFieldSetter<V, PublicSet>>> ModifyValue(DynamicUpdateField<V, BlockBit, Bit>(T::* field), uint32 index) { if (index >= (_value.*field).size()) { // fill with zeros until reaching desired slot (_value.*field)._values.resize(index + 1); - (_value.*field)._updateMask.resize(((_value.*field)._values.size() + 31) / 32); + (_value.*field)._updateMask.resize((index + 1 + 31) / 32); } if constexpr (BlockBit >= 0) @@ -324,9 +324,8 @@ namespace UF return { (_value.*field)._values[index] }; } - template<typename V, int32 BlockBit, uint32 Bit, typename U = T> - std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, OptionalUpdateFieldSetter<V>> - ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field)) + template<typename V, int32 BlockBit, uint32 Bit> + OptionalUpdateFieldSetter<V> ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field)) { if constexpr (BlockBit >= 0) _value._changesMask.Set(BlockBit); @@ -335,13 +334,12 @@ namespace UF return { _value.*field }; } - template<typename V, int32 BlockBit, uint32 Bit, typename U = T> - std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, - std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, + template<typename V, int32 BlockBit, uint32 Bit> + std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, MutableFieldReference<V, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>, MutableNestedFieldReference<V, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>> + UpdateFieldSetter<V, PublicSet>>> ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field), uint32 /*dummy*/) { if (!(_value.*field).has_value()) @@ -354,18 +352,25 @@ namespace UF return { *((_value.*field)._value) }; } - template<typename V, typename U = T> - std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U> && !std::is_array_v<V>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>> - ModifyValue(V(T::* field)) + private: + T& _value; + }; + + template<typename T, bool PublicSet> + struct MutableFieldReferenceNoChangesMask + { + MutableFieldReferenceNoChangesMask(T& value) : _value(value) + { + } + + template<typename V> + UpdateFieldSetter<V, PublicSet> ModifyValue(V(T::* field)) { return { _value.*field }; } - template<typename V, std::size_t Size, typename U = T> - std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>> - ModifyValue(V(T::* field)[Size], uint32 index) + template<typename V, std::size_t Size> + UpdateFieldSetter<V, PublicSet> ModifyValue(V(T::* field)[Size], uint32 index) { return { (_value.*field)[index] }; } @@ -389,7 +394,7 @@ namespace UF MutableFieldReference<value_type, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>, MutableNestedFieldReference<value_type, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>> + UpdateFieldSetter<value_type, PublicSet>>>> ModifyValue() { return { _value._value }; @@ -401,7 +406,7 @@ namespace UF MutableFieldReference<value_type, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>, MutableNestedFieldReference<value_type, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>> + UpdateFieldSetter<value_type, PublicSet>>>> ModifyValue(uint32 index) { return { _value._values[index] }; @@ -420,14 +425,14 @@ namespace UF MutableFieldReference<value_type, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>, MutableNestedFieldReference<value_type, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>> + UpdateFieldSetter<value_type, PublicSet>>>> 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._updateMask.resize((index + 1 + 31) / 32); } _value.MarkChanged(index); @@ -447,7 +452,7 @@ namespace UF MutableFieldReference<value_type, PublicSet>, std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>, MutableNestedFieldReference<value_type, PublicSet>, - std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>> + UpdateFieldSetter<value_type, PublicSet>>>> ModifyValue(uint32 /*dummy*/) { if (!_value.has_value()) @@ -467,7 +472,10 @@ namespace UF friend struct DynamicUpdateFieldSetter; template<typename T, bool PublicSet> - friend struct MutableFieldReference; + friend struct MutableFieldReferenceWithChangesMask; + + template<typename T, bool PublicSet> + friend struct MutableFieldReferenceNoChangesMask; template<typename T, int32 BlockBit, uint32 Bit> friend class UpdateField; @@ -511,7 +519,7 @@ namespace UF { // fill with zeros until reaching desired slot uf._values.resize(index + 1); - uf._updateMask.resize((uf._values.size() + 31) / 32); + uf._updateMask.resize((index + 1 + 31) / 32); } MarkChanged(field); @@ -600,7 +608,10 @@ namespace UF void ClearChanged(DynamicUpdateField<T, BlockBit, Bit>(Derived::* field), uint32 index) { _changesMask.Reset(Bit); - (static_cast<Derived*>(this)->*field).ClearChanged(index); + + DynamicUpdateField<T, BlockBit, Bit>& uf = (static_cast<Derived*>(this)->*field); + if (index < uf.size()) + uf.ClearChanged(index); } template<typename Derived, typename T, int32 BlockBit, uint32 Bit> @@ -617,65 +628,34 @@ namespace UF template<typename T, int32 BlockBit, uint32 Bit> static void ClearChangesMask(UpdateField<T, BlockBit, Bit>& field) { - ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{}); - } - - template<typename T, int32 BlockBit, uint32 Bit> - static void ClearChangesMask(UpdateField<T, BlockBit, Bit>&, std::false_type) { } - - template<typename T, int32 BlockBit, uint32 Bit> - static void ClearChangesMask(UpdateField<T, BlockBit, Bit>& field, std::true_type) - { - field._value.ClearChangesMask(); + if constexpr (std::is_base_of_v<HasChangesMaskTag, T>) + field._value.ClearChangesMask(); } template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit> static void ClearChangesMask(UpdateFieldArray<T, Size, Bit, FirstElementBit>& field) { - ClearChangesMask(field, std::disjunction<std::is_base_of<HasChangesMaskTag, T>, std::is_base_of<IsUpdateFieldHolderTag, T>>{}); - } - - template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit> - static void ClearChangesMask(UpdateFieldArray<T, Size, Bit, FirstElementBit>&, std::false_type) { } - - template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit> - static void ClearChangesMask(UpdateFieldArray<T, Size, Bit, FirstElementBit>& field, std::true_type) - { - for (uint32 i = 0; i < Size; ++i) - field._values[i].ClearChangesMask(); + if constexpr (std::disjunction_v<std::is_base_of<HasChangesMaskTag, T>, std::is_base_of<IsUpdateFieldHolderTag, T>>) + for (T& value : field._values) + value.ClearChangesMask(); } template<typename T, int32 BlockBit, uint32 Bit> static void ClearChangesMask(DynamicUpdateField<T, BlockBit, Bit>& field) { - ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{}); - field.ClearChangesMask(); - } - - template<typename T, int32 BlockBit, uint32 Bit> - static void ClearChangesMask(DynamicUpdateField<T, BlockBit, Bit>&, std::false_type) { } + if constexpr (std::is_base_of_v<HasChangesMaskTag, T>) + for (T& value : field._values) + value.ClearChangesMask(); - template<typename T, int32 BlockBit, uint32 Bit> - static void ClearChangesMask(DynamicUpdateField<T, BlockBit, Bit>& field, std::true_type) - { - for (uint32 i = 0; i < field._values.size(); ++i) - field._values[i].ClearChangesMask(); + field.ClearChangesMask(); } template<typename T, int32 BlockBit, uint32 Bit> static void ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit>& field) { - ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{}); - } - - template<typename T, int32 BlockBit, uint32 Bit> - static void ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit>&, std::false_type) { } - - template<typename T, int32 BlockBit, uint32 Bit> - static void ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit>& field, std::true_type) - { - if (field.has_value()) - field._value->ClearChangesMask(); + if constexpr (std::is_base_of_v<HasChangesMaskTag, T>) + if (field.has_value()) + field._value->ClearChangesMask(); } Mask _changesMask; @@ -685,7 +665,10 @@ namespace UF class UpdateFieldBase : public IsUpdateFieldHolderTag { template<typename F, bool PublicSet> - friend struct MutableFieldReference; + friend struct MutableFieldReferenceWithChangesMask; + + template<typename F, bool PublicSet> + friend struct MutableFieldReferenceNoChangesMask; template<typename F, bool PublicSet> friend struct MutableNestedFieldReference; @@ -729,7 +712,10 @@ namespace UF class UpdateFieldArrayBase : public UpdateFieldArrayBaseWithoutSize<T> { template<typename F, bool PublicSet> - friend struct MutableFieldReference; + friend struct MutableFieldReferenceWithChangesMask; + + template<typename F, bool PublicSet> + friend struct MutableFieldReferenceNoChangesMask; template<typename F, bool PublicSet> friend struct MutableNestedFieldReference; @@ -789,7 +775,10 @@ namespace UF class DynamicUpdateFieldBase : public IsUpdateFieldHolderTag { template<typename F, bool PublicSet> - friend struct MutableFieldReference; + friend struct MutableFieldReferenceWithChangesMask; + + template<typename F, bool PublicSet> + friend struct MutableFieldReferenceNoChangesMask; template<typename F, bool PublicSet> friend struct MutableNestedFieldReference; @@ -862,25 +851,17 @@ namespace UF private: void MarkChanged(std::size_t index) { - std::size_t block = UpdateMaskHelpers::GetBlockIndex(index); - if (block >= _updateMask.size()) - _updateMask.emplace_back(0); - - _updateMask[block] |= UpdateMaskHelpers::GetBlockFlag(index); + _updateMask[UpdateMaskHelpers::GetBlockIndex(index)] |= UpdateMaskHelpers::GetBlockFlag(index); } void ClearChanged(std::size_t index) { - std::size_t block = UpdateMaskHelpers::GetBlockIndex(index); - if (block >= _updateMask.size()) - _updateMask.emplace_back(0); - - _updateMask[block] &= ~UpdateMaskHelpers::GetBlockFlag(index); + _updateMask[UpdateMaskHelpers::GetBlockIndex(index)] &= ~UpdateMaskHelpers::GetBlockFlag(index); } void ClearChangesMask() { - std::fill(_updateMask.begin(), _updateMask.end(), 0); + std::memset(_updateMask.data(), 0, _updateMask.size() * sizeof(uint32)); } std::vector<T> _values; @@ -896,7 +877,10 @@ namespace UF class OptionalUpdateFieldBase : public IsUpdateFieldHolderTag { template<typename F, bool PublicSet> - friend struct MutableFieldReference; + friend struct MutableFieldReferenceWithChangesMask; + + template<typename F, bool PublicSet> + friend struct MutableFieldReferenceNoChangesMask; template<typename F, bool PublicSet> friend struct MutableNestedFieldReference; @@ -940,17 +924,10 @@ namespace UF private: void ConstructValue() { - ConstructValue(IsLarge{}); - } - - void ConstructValue(std::false_type) - { - _value.emplace(); - } - - void ConstructValue(std::true_type) - { - _value = std::make_unique<T>(); + if constexpr (IsLarge::value) + _value = std::make_unique<T>(); + else + _value.emplace(); } void DestroyValue() diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index 419e2eca445..23079db0c41 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -315,26 +315,31 @@ void ItemData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi Modifiers->WriteCreate(data, owner, receiver); } -void ItemData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const +static constexpr void ItemDataAppendAllowedFieldsMaskForFlag(ItemData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array<uint32, 2>{ 0x07F58D80u, 0x00000000u }; } void ItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array<uint32, 2>{ 0x07F58D80u, 0x00000000u }; + ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); } void ItemData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } +void ItemData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const +{ + Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu }); + ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); +} + void ItemData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Item const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlocksMask(0), 2); @@ -697,26 +702,31 @@ void AzeriteItemData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fi data.FlushBits(); } -void AzeriteItemData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const +static constexpr void AzeriteItemDataAppendAllowedFieldsMaskForFlag(AzeriteItemData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0x0000001Du }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array<uint32, 1>{ 0x000003E2u }; } void AzeriteItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array<uint32, 1>{ 0x000003E2u }; + AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); } void AzeriteItemData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { Mask allowedMaskForTarget({ 0x0000001Du }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } +void AzeriteItemData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const +{ + Mask allowedMaskForTarget({ 0x0000001Du }); + AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); +} + void AzeriteItemData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AzeriteItem const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlock(0), 10); @@ -1142,14 +1152,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi data.FlushBits(); } -void UnitData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const -{ - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x0FFFFFFFu, 0x007F0000u, 0x00000000u }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); -} - -void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) +static constexpr void UnitDataAppendAllowedFieldsMaskForFlag(UnitData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) allowedMaskForTarget |= std::array<uint32, 7>{ 0x00010000u, 0xF0040000u, 0xFF080000u, 0x000007FEu, 0xF0000080u, 0xFF80FFFFu, 0x3FFFFFFFu }; @@ -1159,13 +1162,25 @@ void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFl allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0xF0000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0000FF00u }; } +void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) +{ + UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); +} + void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x0FFFFFFFu, 0x007F0000u, 0x00000000u }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } +void UnitData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const +{ + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x0FFFFFFFu, 0x007F0000u, 0x00000000u }); + UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); +} + void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Unit const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlocksMask(0), 7); @@ -2461,26 +2476,31 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi data.FlushBits(); } -void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const +static constexpr void PlayerDataAppendAllowedFieldsMaskForFlag(PlayerData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) + allowedMaskForTarget |= std::array<uint32, 11>{ 0x00000022u, 0xFFFE0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u }; } void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) - allowedMaskForTarget |= std::array<uint32, 11>{ 0x00000022u, 0xFFFE0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u }; + PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); } void PlayerData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u }); - AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } +void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const +{ + Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u }); + PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); +} + void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlocksMask(0), 11); diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h index a79b5c038ab..4ccb7af8fbb 100644 --- a/src/server/game/Entities/Object/Updates/UpdateMask.h +++ b/src/server/game/Entities/Object/Updates/UpdateMask.h @@ -139,7 +139,7 @@ private: }; template<uint32 Bits> -UpdateMask<Bits> operator&(UpdateMask<Bits> const& left, UpdateMask<Bits> const& right) +constexpr UpdateMask<Bits> operator&(UpdateMask<Bits> const& left, UpdateMask<Bits> const& right) { UpdateMask<Bits> result = left; result &= right; @@ -147,7 +147,7 @@ UpdateMask<Bits> operator&(UpdateMask<Bits> const& left, UpdateMask<Bits> const& } template<uint32 Bits> -UpdateMask<Bits> operator|(UpdateMask<Bits> const& left, UpdateMask<Bits> const& right) +constexpr UpdateMask<Bits> operator|(UpdateMask<Bits> const& left, UpdateMask<Bits> const& right) { UpdateMask<Bits> result = left; result |= right; |