aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-06-28 19:43:01 +0200
committerShauren <shauren.trinity@gmail.com>2025-06-28 19:43:01 +0200
commit68588dbb25d2cb45757764db187d5e66b7726305 (patch)
tree810d72f282d8d83131c753c1668394b3eb4b9c90
parent4c92d3550b331aff6a22f753295388fa2a215e6c (diff)
Core/Objects: Modernize updatefield internals - replace tag dispatch and std::enable if
-rw-r--r--src/server/game/Entities/Object/Object.h16
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateField.h233
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.cpp80
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateMask.h4
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;