mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Objects: Modernize updatefield internals - replace tag dispatch and std::enable if
This commit is contained in:
@@ -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");
|
||||
|
||||
|
||||
@@ -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>{});
|
||||
if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
|
||||
for (T& value : field._values)
|
||||
value.ClearChangesMask();
|
||||
|
||||
field.ClearChangesMask();
|
||||
}
|
||||
|
||||
template<typename T, int32 BlockBit, uint32 Bit>
|
||||
static void ClearChangesMask(DynamicUpdateField<T, BlockBit, Bit>&, std::false_type) { }
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
@@ -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
|
||||
{
|
||||
Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu });
|
||||
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
|
||||
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
|
||||
}
|
||||
|
||||
void ItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
static constexpr void ItemDataAppendAllowedFieldsMaskForFlag(ItemData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
{
|
||||
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner))
|
||||
allowedMaskForTarget |= std::array<uint32, 2>{ 0x07F58D80u, 0x00000000u };
|
||||
}
|
||||
|
||||
void ItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
{
|
||||
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
|
||||
{
|
||||
Mask allowedMaskForTarget({ 0x0000001Du });
|
||||
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
|
||||
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
|
||||
}
|
||||
|
||||
void AzeriteItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
static constexpr void AzeriteItemDataAppendAllowedFieldsMaskForFlag(AzeriteItemData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
{
|
||||
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner))
|
||||
allowedMaskForTarget |= std::array<uint32, 1>{ 0x000003E2u };
|
||||
}
|
||||
|
||||
void AzeriteItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
{
|
||||
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
|
||||
{
|
||||
Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u });
|
||||
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
|
||||
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
|
||||
}
|
||||
|
||||
void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
static constexpr void PlayerDataAppendAllowedFieldsMaskForFlag(PlayerData::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 };
|
||||
}
|
||||
|
||||
void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user