mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 16:38:42 +01:00
Core/Entities: Support setting nested updatefield types like ActivePlayerData::Research
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user