18#ifndef UpdateField_h__
19#define UpdateField_h__
47 template<
typename T,
int32 BlockBit, u
int32 Bit>
53 template<
typename T, std::
size_t Size>
56 template<
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
62 template<
typename T,
int32 BlockBit, u
int32 Bit>
68 template<
typename T,
int32 BlockBit, u
int32 Bit>
71 template<
typename T,
bool PublicSet>
74 template<
typename T,
bool PublicSet>
109 _value = std::move(value);
135 _value = std::move(value);
170 MarkNewValue(value, std::is_base_of<HasChangesMaskTag, T>{});
177 for (std::size_t i = index; i <
_values.size(); ++i)
190 for (std::size_t i = index; i <
_values.size(); ++i)
223 value._changesMask.SetAll();
248 template<
typename T,
bool PublicSet>
255 template<
typename V,
int32 BlockBit, u
int32 Bit,
typename U = T>
256 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>,
257 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
259 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
264 if constexpr (BlockBit >= 0)
265 _value._changesMask.Set(BlockBit);
267 _value._changesMask.Set(Bit);
271 template<
typename V, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit,
typename U = T>
272 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>,
273 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
275 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
280 _value._changesMask.Set(Bit);
281 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, V>)
282 _value._changesMask.Set(FirstElementBit + index);
284 _value._changesMask.Set(FirstElementBit);
286 return { (
_value.*field)._values[index] };
289 template<
typename V,
int32 BlockBit, u
int32 Bit,
typename U = T>
293 if constexpr (BlockBit >= 0)
294 _value._changesMask.Set(BlockBit);
296 _value._changesMask.Set(Bit);
297 return { (
_value.*field)._values, (
_value.*field)._updateMask };
300 template<
typename V,
int32 BlockBit, u
int32 Bit,
typename U = T>
301 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>,
302 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
304 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
309 if (index >= (
_value.*field).size())
312 (
_value.*field)._values.resize(index + 1);
313 (
_value.*field)._updateMask.resize(((
_value.*field)._values.size() + 31) / 32);
316 if constexpr (BlockBit >= 0)
317 _value._changesMask.Set(BlockBit);
319 _value._changesMask.Set(Bit);
320 (
_value.*field).MarkChanged(index);
321 return { (
_value.*field)._values[index] };
324 template<
typename V,
int32 BlockBit, u
int32 Bit,
typename U = T>
328 if constexpr (BlockBit >= 0)
329 _value._changesMask.Set(BlockBit);
331 _value._changesMask.Set(Bit);
335 template<
typename V,
int32 BlockBit, u
int32 Bit,
typename U = T>
336 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>,
337 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
339 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
344 if (!(
_value.*field).has_value())
345 (
_value.*field).ConstructValue();
347 if constexpr (BlockBit >= 0)
348 _value._changesMask.Set(BlockBit);
350 _value._changesMask.Set(Bit);
354 template<
typename V,
typename U = T>
355 std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U> && !std::is_array_v<V>,
362 template<
typename V, std::
size_t Size,
typename U = T>
363 std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U>,
367 return { (
_value.*field)[index] };
374 template<
typename T,
bool PublicSet>
383 template<
typename U = T>
384 std::enable_if_t<std::is_base_of_v<UpdateFieldBase<value_type>, U>,
385 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
387 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
395 template<
typename U = T>
396 std::enable_if_t<std::is_base_of_v<UpdateFieldArrayBaseWithoutSize<value_type>, U>,
397 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
399 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
404 return {
_value._values[index] };
407 template<
typename U = T>
414 template<
typename U = T>
415 std::enable_if_t<std::is_base_of_v<DynamicUpdateFieldBase<value_type>, U>,
416 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
418 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
423 if (index >=
_value.size())
426 _value._values.resize(index + 1);
427 _value._updateMask.resize((
_value._values.size() + 31) / 32);
430 _value.MarkChanged(index);
431 return {
_value._values[index] };
434 template<
typename U = T>
441 template<
typename U = T>
442 std::enable_if_t<std::is_base_of_v<OptionalUpdateFieldBase<value_type>, U>,
443 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
445 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
453 return { *(
_value._value) };
460 template<std::
size_t Bits>
466 template<
typename T,
bool PublicSet>
469 template<
typename T,
int32 BlockBit, u
int32 Bit>
472 template<
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
475 template<
typename T,
int32 BlockBit, u
int32 Bit>
482 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
486 return { (
static_cast<Derived*
>(
this)->*field)._value };
489 template<
typename Derived,
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
493 return { (
static_cast<Derived*
>(
this)->*field)._values[index] };
496 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
500 return { (
static_cast<Derived*
>(
this)->*field)._values };
503 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
507 if (index >= uf.
size())
515 (
static_cast<Derived*
>(
this)->*field).MarkChanged(index);
519 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
523 return { *((
static_cast<Derived*
>(
this)->*field)._value) };
526 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
529 static_assert(std::is_base_of_v<Base, Derived>,
"Given field argument must belong to the same structure as this HasChangesMask");
531 if constexpr (BlockBit >= 0)
537 template<
typename Derived,
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
540 static_assert(std::is_base_of_v<Base, Derived>,
"Given field argument must belong to the same structure as this HasChangesMask");
543 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
549 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
552 static_assert(std::is_base_of_v<Base, Derived>,
"Given field argument must belong to the same structure as this HasChangesMask");
554 if constexpr (BlockBit >= 0)
560 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
563 static_assert(std::is_base_of_v<Base, Derived>,
"Given field argument must belong to the same structure as this HasChangesMask");
565 if constexpr (BlockBit >= 0)
571 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
574 static_assert(std::is_base_of_v<Base, Derived>,
"Given field argument must belong to the same structure as this HasChangesMask");
579 template<
typename Derived,
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
582 static_assert(std::is_base_of_v<Base, Derived>,
"Given field argument must belong to the same structure as this HasChangesMask");
584 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
590 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
594 (
static_cast<Derived*
>(
this)->*field).ClearChanged(index);
597 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
600 static_assert(std::is_base_of_v<Base, Derived>,
"Given field argument must belong to the same structure as this HasChangesMask");
608 template<
typename T,
int32 BlockBit, u
int32 Bit>
614 template<
typename T,
int32 BlockBit, u
int32 Bit>
617 template<
typename T,
int32 BlockBit, u
int32 Bit>
620 field.
_value.ClearChangesMask();
623 template<
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
626 ClearChangesMask(field, std::disjunction<std::is_base_of<HasChangesMaskTag, T>, std::is_base_of<IsUpdateFieldHolderTag, T>>{});
629 template<
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
632 template<
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
636 field.
_values[i].ClearChangesMask();
639 template<
typename T,
int32 BlockBit, u
int32 Bit>
646 template<
typename T,
int32 BlockBit, u
int32 Bit>
649 template<
typename T,
int32 BlockBit, u
int32 Bit>
653 field.
_values[i].ClearChangesMask();
656 template<
typename T,
int32 BlockBit, u
int32 Bit>
662 template<
typename T,
int32 BlockBit, u
int32 Bit>
665 template<
typename T,
int32 BlockBit, u
int32 Bit>
669 field.
_value->ClearChangesMask();
682 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
686 return { (
static_cast<Derived*
>(
_owner)->*field)._value };
689 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
693 (
static_cast<Derived*
>(
_owner)->*field)._value.ClearChangesMask();
714 template<
typename F,
bool PublicSet>
717 template<
typename F,
bool PublicSet>
720 template<std::
size_t Bits>
728 operator T
const& ()
const
745 template<
typename T,
int32 BlockBit, u
int32 Bit>
755 template<
typename T, std::
size_t Size>
758 template<
typename F,
bool PublicSet>
761 template<
typename F,
bool PublicSet>
764 template<std::
size_t Bits>
780 static constexpr std::size_t
size()
804 return sizeof(
typename T::value_type);
807 template<
typename T, std::
size_t Size, u
int32 Bit, u
int32 FirstElementBit>
818 template<
typename F,
bool PublicSet>
821 template<
typename F,
bool PublicSet>
824 template<std::
size_t Bits>
835 typename std::vector<T>::const_iterator
begin()
const
840 typename std::vector<T>::const_iterator
end()
const
869 template<
typename Pred>
872 auto itr = std::find_if(
_values.begin(),
_values.end(), std::ref(pred));
881 return (
_updateMask[index / 32] & (1 << (index % 32))) != 0;
917 template<
typename T,
int32 BlockBit, u
int32 Bit>
925 template<
typename F,
bool PublicSet>
928 template<
typename F,
bool PublicSet>
931 template<std::
size_t Bits>
939 using IsLarge = std::integral_constant<bool,
sizeof(
void*) * 3 <
sizeof(T)>;
952 operator T
const& ()
const
978 _value = std::make_unique<T>();
989 template<
typename T,
int32 BlockBit, u
int32 Bit>
std::optional< T > Optional
Optional helper class to wrap optional values within.
std::vector< T >::const_iterator begin() const
void ClearChanged(std::size_t index)
std::vector< T >::const_iterator end() const
bool HasChanged(uint32 index) const
void MarkChanged(std::size_t index)
T const & operator[](std::size_t index) const
void WriteUpdateMask(ByteBuffer &data, int32 bitsForSize=32) const
std::vector< uint32 > _updateMask
int32 FindIndexIf(Pred pred) const
int32 FindIndex(T const &value) const
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &, std::false_type)
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &field)
MutableFieldReference< T, false > ModifyValue(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field))
void ClearChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &field, std::true_type)
MutableFieldReference< T, false > ModifyValue(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*field), uint32 index)
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &field, std::true_type)
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &, std::false_type)
void ClearChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field), uint32 index)
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &field, std::true_type)
MutableFieldReference< T, false > ModifyValue(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field), uint32 index)
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &field)
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &, std::false_type)
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &field)
void ClearChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
void MarkChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
Mask const & GetChangesMask() const
void MarkChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*), uint32)
void ClearChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
MutableFieldReference< T, false > ModifyValue(OptionalUpdateField< T, BlockBit, Bit >(Derived::*field))
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &field)
void MarkChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &field, std::true_type)
void MarkChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &, std::false_type)
T const & operator*() const
std::integral_constant< bool, sizeof(void *) *3< sizeof(T)> IsLarge
void ConstructValue(std::false_type)
std::conditional_t< IsLarge::value, std::unique_ptr< T >, Optional< T > > StorageType
T const * operator->() const
void ConstructValue(std::true_type)
~OptionalUpdateFieldBase()
static constexpr std::size_t size()
T const & operator[](std::size_t index) const
T const & operator*() const
T const * operator->() const
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
UpdateMask< NUM_CLIENT_OBJECT_TYPES > _changesMask
bool HasChanged(uint32 index) const
UpdateFieldHolder(Object *owner)
uint32 GetChangedObjectTypeMask() const
uint32 GetBlock(uint32 index) const
bool Size(ContainerUnorderedMap< TypeList< H, T >, KEY_TYPE > const &elements, std::size_t *size, SPECIFIC_TYPE *obj)
constexpr std::size_t size()
void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer &data, int32 bitsForSize=32)
void WriteDynamicFieldUpdateMask(std::size_t size, std::vector< uint32 > const &updateMask, ByteBuffer &data, int32 bitsForSize=32)
constexpr std::size_t size_of_value_type()
DEFINE_ENUM_FLAG(UpdateFieldFlag)
constexpr std::size_t GetBlockIndex(std::size_t bit)
constexpr uint32 GetBlockFlag(std::size_t bit)
DynamicUpdateFieldSetter(std::vector< T > &values, std::vector< uint32 > &updateMask)
friend void ClearDynamicUpdateFieldValues(DynamicUpdateFieldSetter< F > &setter)
friend DynamicUpdateFieldSetter< F >::insert_result InsertDynamicUpdateFieldValue(DynamicUpdateFieldSetter< F > &setter, uint32 index)
friend DynamicUpdateFieldSetter< F >::insert_result AddDynamicUpdateFieldValue(DynamicUpdateFieldSetter< F > &setter)
friend void RemoveDynamicUpdateFieldValue(DynamicUpdateFieldSetter< F > &setter, uint32 index)
std::conditional_t< std::is_base_of_v< HasChangesMaskTag, T >, MutableFieldReference< T, true >, T & > insert_result
void RemoveValue(std::size_t index)
std::vector< T > & _values
static void MarkNewValue(T &, std::false_type)
static void MarkNewValue(T &value, std::true_type)
void MarkChanged(std::size_t index)
std::vector< uint32 > & _updateMask
insert_result InsertValue(std::size_t index)
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))
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, 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 > > > > > ModifyValue(OptionalUpdateField< V, BlockBit, Bit >(T::*field), uint32)
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, 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 > > > > > ModifyValue(UpdateFieldArray< V, Size, Bit, FirstElementBit >(T::*field), uint32 index)
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, 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 > > > > > ModifyValue(DynamicUpdateField< V, BlockBit, Bit >(T::*field), uint32 index)
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, DynamicUpdateFieldSetter< V > > ModifyValue(DynamicUpdateField< V, BlockBit, Bit >(T::*field))
MutableFieldReference(T &value)
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, 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 > > > > > ModifyValue(UpdateField< V, BlockBit, Bit >(T::*field))
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)
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, OptionalUpdateFieldSetter< V > > ModifyValue(OptionalUpdateField< V, BlockBit, Bit >(T::*field))
typename T::value_type value_type
std::enable_if_t< std::is_base_of_v< DynamicUpdateFieldBase< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, 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 > > > > > ModifyValue(uint32 index)
std::enable_if_t< std::is_base_of_v< UpdateFieldBase< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, 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 > > > > > ModifyValue()
MutableNestedFieldReference(T &value)
std::enable_if_t< std::is_base_of_v< OptionalUpdateFieldBase< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, 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 > > > > > ModifyValue(uint32)
std::enable_if_t< std::is_base_of_v< UpdateFieldArrayBaseWithoutSize< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, 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 > > > > > ModifyValue(uint32 index)
std::enable_if_t< std::is_base_of_v< DynamicUpdateFieldBase< value_type >, U >, DynamicUpdateFieldSetter< value_type > > ModifyValue()
std::enable_if_t< std::is_base_of_v< OptionalUpdateFieldBase< value_type >, U >, OptionalUpdateFieldSetter< value_type > > ModifyValue()
OptionalUpdateFieldSetter(OptionalUpdateFieldBase< T > &field)
OptionalUpdateFieldBase< T > & _field
friend void RemoveOptionalUpdateFieldValue(OptionalUpdateFieldSetter< F > &setter)
UpdateFieldPublicSetter(T &value)
friend bool SetUpdateFieldValue(UpdateFieldSetter< F > &setter, typename UpdateFieldSetter< F >::value_type &&value)
UpdateFieldSetter(T &value)