aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2020-07-26 12:44:44 +0200
committerShauren <shauren.trinity@gmail.com>2020-07-26 12:44:44 +0200
commit588dce6bb0497e349fb6aac68c0a67a6560cb8a8 (patch)
treeab13af39319605a8852e261420d3f522e1968259 /src
parent64120b53a8d194b6595e5c7fb8d29aa5bde76b9e (diff)
Core/Entities: Support setting nested updatefield types like ActivePlayerData::Research
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateField.h168
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.h2
2 files changed, 157 insertions, 13 deletions
diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h
index 4dd17a01497..33fbfa07a67 100644
--- a/src/server/game/Entities/Object/Updates/UpdateField.h
+++ b/src/server/game/Entities/Object/Updates/UpdateField.h
@@ -40,12 +40,24 @@ namespace UF
DEFINE_ENUM_FLAG(UpdateFieldFlag);
+ template<typename T>
+ class UpdateFieldBase;
+
template<typename T, uint32 BlockBit, uint32 Bit>
class UpdateField;
+ template<typename T>
+ class UpdateFieldArrayBaseWithoutSize;
+
+ template<typename T, std::size_t Size>
+ class UpdateFieldArrayBase;
+
template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
class UpdateFieldArray;
+ template<typename T>
+ class DynamicUpdateFieldBase;
+
template<typename T, uint32 BlockBit, uint32 Bit>
class DynamicUpdateField;
@@ -58,12 +70,18 @@ namespace UF
template<typename T, bool PublicSet>
struct MutableFieldReference;
+ template<typename T, bool PublicSet>
+ struct MutableNestedFieldReference;
+
struct IsUpdateFieldStructureTag
{
};
struct HasChangesMaskTag
{
};
+ struct IsUpdateFieldHolderTag
+ {
+ };
template<typename T>
struct UpdateFieldSetter
@@ -237,7 +255,9 @@ namespace UF
std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value,
std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value,
MutableFieldReference<V, PublicSet>,
- std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value,
+ MutableNestedFieldReference<V, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
ModifyValue(UpdateField<V, BlockBit, Bit>(T::* field))
{
_value._changesMask.Set(BlockBit);
@@ -249,7 +269,9 @@ namespace UF
std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value,
std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value,
MutableFieldReference<V, PublicSet>,
- std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value,
+ MutableNestedFieldReference<V, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
ModifyValue(UpdateFieldArray<V, Size, Bit, FirstElementBit>(T::* field), uint32 index)
{
_value._changesMask.Set(Bit);
@@ -270,7 +292,9 @@ namespace UF
std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value,
std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value,
MutableFieldReference<V, PublicSet>,
- std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value,
+ MutableNestedFieldReference<V, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
ModifyValue(DynamicUpdateField<V, BlockBit, Bit>(T::* field), uint32 index)
{
if (index >= (_value.*field).size())
@@ -299,8 +323,10 @@ namespace UF
std::enable_if_t<std::is_base_of<HasChangesMaskTag, U>::value,
std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value,
MutableFieldReference<V, PublicSet>,
- std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>
- ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field), uint32)
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, V>::value,
+ MutableNestedFieldReference<V, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
+ ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field), uint32 /*dummy*/)
{
if (!(_value.*field).is_initialized())
(_value.*field).ConstructValue();
@@ -330,6 +356,92 @@ namespace UF
T& _value;
};
+ template<typename T, bool PublicSet>
+ struct MutableNestedFieldReference
+ {
+ using ValueType = typename T::ValueType;
+
+ MutableNestedFieldReference(T& value) : _value(value)
+ {
+ }
+
+ template<typename U = T>
+ std::enable_if_t<std::is_base_of<UpdateFieldBase<ValueType>, U>::value,
+ std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value,
+ MutableFieldReference<ValueType, PublicSet>,
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value,
+ MutableNestedFieldReference<ValueType, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>>
+ ModifyValue()
+ {
+ return { _value._value };
+ }
+
+ template<typename U = T>
+ std::enable_if_t<std::is_base_of<UpdateFieldArrayBaseWithoutSize<ValueType>, U>::value,
+ std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value,
+ MutableFieldReference<ValueType, PublicSet>,
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value,
+ MutableNestedFieldReference<ValueType, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>>
+ ModifyValue(uint32 index)
+ {
+ return { _value._values[index] };
+ }
+
+ template<typename U = T>
+ std::enable_if_t<std::is_base_of<DynamicUpdateFieldBase<ValueType>, U>::value, DynamicUpdateFieldSetter<ValueType>>
+ ModifyValue()
+ {
+ return { _value._values, _value._updateMask };
+ }
+
+ template<typename U = T>
+ std::enable_if_t<std::is_base_of<DynamicUpdateFieldBase<ValueType>, U>::value,
+ std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value,
+ MutableFieldReference<ValueType, PublicSet>,
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value,
+ MutableNestedFieldReference<ValueType, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>>
+ ModifyValue(uint32 index)
+ {
+ if (index >= _value.size())
+ {
+ // fill with zeros until reaching desired slot
+ _value._values.resize(index + 1);
+ _value._updateMask.resize((_value._values.size() + 31) / 32);
+ }
+
+ _value.MarkChanged(index);
+ return { _value._values[index] };
+ }
+
+ template<typename U = T>
+ std::enable_if_t<std::is_base_of<OptionalUpdateFieldBase<ValueType>, U>::value, OptionalUpdateFieldSetter<ValueType>>
+ ModifyValue()
+ {
+ return { _value };
+ }
+
+ template<typename U = T>
+ std::enable_if_t<std::is_base_of<OptionalUpdateFieldBase<ValueType>, U>::value,
+ std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, ValueType>::value,
+ MutableFieldReference<ValueType, PublicSet>,
+ std::conditional_t<std::is_base_of<IsUpdateFieldHolderTag, ValueType>::value,
+ MutableNestedFieldReference<ValueType, PublicSet>,
+ std::conditional_t<PublicSet, UpdateFieldPublicSetter<ValueType>, UpdateFieldSetter<ValueType>>>>>
+ ModifyValue(uint32 /*dummy*/)
+ {
+ if (!_value.is_initialized())
+ _value.ConstructValue();
+
+ return { *(_value._value) };
+ }
+
+ private:
+ T& _value;
+ };
+
template<std::size_t Bits>
class HasChangesMask : public HasChangesMaskTag
{
@@ -570,12 +682,15 @@ namespace UF
Object* _owner;
};
- template<typename T, uint32 BlockBit, uint32 Bit>
- class UpdateField
+ template<typename T>
+ class UpdateFieldBase : public IsUpdateFieldHolderTag
{
template<typename F, bool PublicSet>
friend struct MutableFieldReference;
+ template<typename F, bool PublicSet>
+ friend struct MutableNestedFieldReference;
+
template<std::size_t Bits>
friend class HasChangesMask;
@@ -601,12 +716,25 @@ namespace UF
T _value = {};
};
- template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
- class UpdateFieldArray
+ template<typename T, uint32 BlockBit, uint32 Bit>
+ class UpdateField : public UpdateFieldBase<T>
+ {
+ };
+
+ template<typename T>
+ class UpdateFieldArrayBaseWithoutSize : public IsUpdateFieldHolderTag
+ {
+ };
+
+ template<typename T, std::size_t Size>
+ class UpdateFieldArrayBase : public UpdateFieldArrayBaseWithoutSize<T>
{
template<typename F, bool PublicSet>
friend struct MutableFieldReference;
+ template<typename F, bool PublicSet>
+ friend struct MutableNestedFieldReference;
+
template<std::size_t Bits>
friend class HasChangesMask;
@@ -637,15 +765,23 @@ namespace UF
T _values[Size] = {};
};
+ template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
+ class UpdateFieldArray : public UpdateFieldArrayBase<T, Size>
+ {
+ };
+
void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data);
void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data);
- template<typename T, uint32 BlockBit, uint32 Bit>
- class DynamicUpdateField
+ template<typename T>
+ class DynamicUpdateFieldBase : public IsUpdateFieldHolderTag
{
template<typename F, bool PublicSet>
friend struct MutableFieldReference;
+ template<typename F, bool PublicSet>
+ friend struct MutableNestedFieldReference;
+
template<std::size_t Bits>
friend class HasChangesMask;
@@ -734,12 +870,20 @@ namespace UF
std::vector<uint32> _updateMask;
};
+ template<typename T, uint32 BlockBit, uint32 Bit>
+ class DynamicUpdateField : public DynamicUpdateFieldBase<T>
+ {
+ };
+
template<typename T>
- class OptionalUpdateFieldBase
+ class OptionalUpdateFieldBase : public IsUpdateFieldHolderTag
{
template<typename F, bool PublicSet>
friend struct MutableFieldReference;
+ template<typename F, bool PublicSet>
+ friend struct MutableNestedFieldReference;
+
template<std::size_t Bits>
friend class HasChangesMask;
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h
index a1fb875fcc6..f2faeffd2c5 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.h
@@ -537,7 +537,7 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas
UpdateField<bool, 0, 2> BankAutoSortDisabled;
UpdateField<bool, 0, 3> SortBagsRightToLeft;
UpdateField<bool, 0, 4> InsertItemsLeftToRight;
- UpdateFieldArray<DynamicUpdateField<UF::Research, 4294967295, 4294967295>, 1, 22, 23> Research;
+ UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 22, 23> Research;
DynamicUpdateField<uint64, 0, 5> KnownTitles;
DynamicUpdateField<uint16, 0, 6> ResearchSites;
DynamicUpdateField<uint32, 0, 7> ResearchSiteProgress;