Core/Entities: Support setting nested updatefield types like ActivePlayerData::Research

This commit is contained in:
Shauren
2020-07-26 12:44:44 +02:00
parent 64120b53a8
commit 588dce6bb0
2 changed files with 157 additions and 13 deletions

View File

@@ -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;

View File

@@ -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;