TrinityCore
UpdateField.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef UpdateField_h__
19#define UpdateField_h__
20
21#include "ObjectGuid.h"
22#include "Optional.h"
23#include "UpdateMask.h"
24#include <algorithm>
25#include <memory>
26#include <vector>
27
28class ByteBuffer;
29class Object;
30
31namespace UF
32{
34 {
35 None = 0,
36 Owner = 0x01,
37 PartyMember = 0x02,
38 UnitAll = 0x04,
39 Empath = 0x08
40 };
41
43
44 template<typename T>
45 class UpdateFieldBase;
46
47 template<typename T, int32 BlockBit, uint32 Bit>
48 class UpdateField;
49
50 template<typename T>
52
53 template<typename T, std::size_t Size>
55
56 template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
57 class UpdateFieldArray;
58
59 template<typename T>
61
62 template<typename T, int32 BlockBit, uint32 Bit>
64
65 template<typename T>
67
68 template<typename T, int32 BlockBit, uint32 Bit>
70
71 template<typename T, bool PublicSet>
73
74 template<typename T, bool PublicSet>
76
78 {
79 };
81 {
82 };
84 {
85 };
86
87 template<typename T>
89 {
90 using value_type = T;
91
92 template<typename F>
94
95 UpdateFieldSetter(T& value) : _value(value)
96 {
97 }
98
99 T GetValue() const
100 {
101 return _value;
102 }
103
104 private:
105 bool SetValue(T value)
106 {
107 if (_value != value)
108 {
109 _value = std::move(value);
110 return true;
111 }
112 return false;
113 }
114
116 };
117
118 // Same as UpdateFieldSetter but with public setter, used to set member fields for values added to dynamic fields
119 template<typename T>
121 {
122 using value_type = T;
123
125 {
126 }
127
128 T GetValue() const
129 {
130 return _value;
131 }
132
133 void SetValue(T value)
134 {
135 _value = std::move(value);
136 }
137
138 private:
140 };
141
142 template<typename T>
144 {
145 using value_type = T;
146 using insert_result = std::conditional_t<std::is_base_of_v<HasChangesMaskTag, T>, MutableFieldReference<T, true>, T&>;
147
148 template<typename F>
150
151 template<typename F>
153
154 template<typename F>
156
157 template<typename F>
159
160 DynamicUpdateFieldSetter(std::vector<T>& values, std::vector<uint32>& updateMask) : _values(values), _updateMask(updateMask)
161 {
162 }
163
164 private:
166 {
167 MarkChanged(_values.size());
168 _values.emplace_back();
169 T& value = _values.back();
170 MarkNewValue(value, std::is_base_of<HasChangesMaskTag, T>{});
171 return { value };
172 }
173
174 insert_result InsertValue(std::size_t index)
175 {
176 _values.emplace(_values.begin() + index);
177 for (std::size_t i = index; i < _values.size(); ++i)
178 {
179 MarkChanged(i);
180 // also mark all fields of value as changed
181 MarkNewValue(_values[i], std::is_base_of<HasChangesMaskTag, T>{});
182 }
183 return { _values[index] };
184 }
185
186 void RemoveValue(std::size_t index)
187 {
188 // remove by shifting entire container - client might rely on values being sorted for certain fields
189 _values.erase(_values.begin() + index);
190 for (std::size_t i = index; i < _values.size(); ++i)
191 {
192 MarkChanged(i);
193 // also mark all fields of value as changed
194 MarkNewValue(_values[i], std::is_base_of<HasChangesMaskTag, T>{});
195 }
196 if (_values.size() % 32)
198 else
199 _updateMask.pop_back();
200 }
201
202 void Clear()
203 {
204 _values.clear();
205 _updateMask.clear();
206 }
207
208 void MarkChanged(std::size_t index)
209 {
210 std::size_t block = UpdateMaskHelpers::GetBlockIndex(index);
211 if (block >= _updateMask.size())
212 _updateMask.resize(block + 1);
213
215 }
216
217 static void MarkNewValue(T&, std::false_type)
218 {
219 }
220
221 static void MarkNewValue(T& value, std::true_type)
222 {
223 value._changesMask.SetAll();
224 }
225
226 std::vector<T>& _values;
227 std::vector<uint32>& _updateMask;
228 };
229
230 template<typename T>
232 {
233 template<typename F>
235
237
238 private:
240 {
241 if (_field.has_value())
242 _field.DestroyValue();
243 }
244
246 };
247
248 template<typename T, bool PublicSet>
250 {
251 MutableFieldReference(T& value) : _value(value)
252 {
253 }
254
255 template<typename V, int32 BlockBit, uint32 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>,
261 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
263 {
264 if constexpr (BlockBit >= 0)
265 _value._changesMask.Set(BlockBit);
266
267 _value._changesMask.Set(Bit);
268 return { (_value.*field)._value };
269 }
270
271 template<typename V, std::size_t Size, uint32 Bit, uint32 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>,
277 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
279 {
280 _value._changesMask.Set(Bit);
281 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, V>)
282 _value._changesMask.Set(FirstElementBit + index);
283 else
284 _value._changesMask.Set(FirstElementBit);
285
286 return { (_value.*field)._values[index] };
287 }
288
289 template<typename V, int32 BlockBit, uint32 Bit, typename U = T>
290 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, DynamicUpdateFieldSetter<V>>
292 {
293 if constexpr (BlockBit >= 0)
294 _value._changesMask.Set(BlockBit);
295
296 _value._changesMask.Set(Bit);
297 return { (_value.*field)._values, (_value.*field)._updateMask };
298 }
299
300 template<typename V, int32 BlockBit, uint32 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>,
306 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
308 {
309 if (index >= (_value.*field).size())
310 {
311 // fill with zeros until reaching desired slot
312 (_value.*field)._values.resize(index + 1);
313 (_value.*field)._updateMask.resize(((_value.*field)._values.size() + 31) / 32);
314 }
315
316 if constexpr (BlockBit >= 0)
317 _value._changesMask.Set(BlockBit);
318
319 _value._changesMask.Set(Bit);
320 (_value.*field).MarkChanged(index);
321 return { (_value.*field)._values[index] };
322 }
323
324 template<typename V, int32 BlockBit, uint32 Bit, typename U = T>
325 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, OptionalUpdateFieldSetter<V>>
327 {
328 if constexpr (BlockBit >= 0)
329 _value._changesMask.Set(BlockBit);
330
331 _value._changesMask.Set(Bit);
332 return { _value.*field };
333 }
334
335 template<typename V, int32 BlockBit, uint32 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>,
341 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
343 {
344 if (!(_value.*field).has_value())
345 (_value.*field).ConstructValue();
346
347 if constexpr (BlockBit >= 0)
348 _value._changesMask.Set(BlockBit);
349
350 _value._changesMask.Set(Bit);
351 return { *((_value.*field)._value) };
352 }
353
354 template<typename V, typename U = T>
355 std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U> && !std::is_array_v<V>,
356 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>
357 ModifyValue(V(T::* field))
358 {
359 return { _value.*field };
360 }
361
362 template<typename V, std::size_t Size, typename U = T>
363 std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U>,
364 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>
365 ModifyValue(V(T::* field)[Size], uint32 index)
366 {
367 return { (_value.*field)[index] };
368 }
369
370 private:
372 };
373
374 template<typename T, bool PublicSet>
376 {
377 using value_type = typename T::value_type;
378
380 {
381 }
382
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>,
389 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
391 {
392 return { _value._value };
393 }
394
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>,
401 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
403 {
404 return { _value._values[index] };
405 }
406
407 template<typename U = T>
408 std::enable_if_t<std::is_base_of_v<DynamicUpdateFieldBase<value_type>, U>, DynamicUpdateFieldSetter<value_type>>
410 {
411 return { _value._values, _value._updateMask };
412 }
413
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>,
420 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
422 {
423 if (index >= _value.size())
424 {
425 // fill with zeros until reaching desired slot
426 _value._values.resize(index + 1);
427 _value._updateMask.resize((_value._values.size() + 31) / 32);
428 }
429
430 _value.MarkChanged(index);
431 return { _value._values[index] };
432 }
433
434 template<typename U = T>
435 std::enable_if_t<std::is_base_of_v<OptionalUpdateFieldBase<value_type>, U>, OptionalUpdateFieldSetter<value_type>>
437 {
438 return { _value };
439 }
440
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>,
447 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
449 {
450 if (!_value.has_value())
451 _value.ConstructValue();
452
453 return { *(_value._value) };
454 }
455
456 private:
458 };
459
460 template<std::size_t Bits>
462 {
463 template<typename T>
465
466 template<typename T, bool PublicSet>
468
469 template<typename T, int32 BlockBit, uint32 Bit>
470 friend class UpdateField;
471
472 template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
473 friend class UpdateFieldArray;
474
475 template<typename T, int32 BlockBit, uint32 Bit>
476 friend class DynamicUpdateField;
477
478 public:
481
482 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
484 {
485 MarkChanged(field);
486 return { (static_cast<Derived*>(this)->*field)._value };
487 }
488
489 template<typename Derived, typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
491 {
492 MarkChanged(field, index);
493 return { (static_cast<Derived*>(this)->*field)._values[index] };
494 }
495
496 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
498 {
499 MarkChanged(field);
500 return { (static_cast<Derived*>(this)->*field)._values };
501 }
502
503 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
505 {
506 DynamicUpdateField<T, BlockBit, Bit>& uf = (static_cast<Derived*>(this)->*field);
507 if (index >= uf.size())
508 {
509 // fill with zeros until reaching desired slot
510 uf._values.resize(index + 1);
511 uf._updateMask.resize((uf._values.size() + 31) / 32);
512 }
513
514 MarkChanged(field);
515 (static_cast<Derived*>(this)->*field).MarkChanged(index);
516 return { uf._values[index] };
517 }
518
519 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
521 {
522 MarkChanged(field);
523 return { *((static_cast<Derived*>(this)->*field)._value) };
524 }
525
526 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
528 {
529 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
530
531 if constexpr (BlockBit >= 0)
532 _changesMask.Set(BlockBit);
533
534 _changesMask.Set(Bit);
535 }
536
537 template<typename Derived, typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
539 {
540 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
541
542 _changesMask.Set(Bit);
543 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
544 _changesMask.Set(FirstElementBit + index);
545 else
546 _changesMask.Set(FirstElementBit);
547 }
548
549 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
551 {
552 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
553
554 if constexpr (BlockBit >= 0)
555 _changesMask.Set(BlockBit);
556
557 _changesMask.Set(Bit);
558 }
559
560 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
562 {
563 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
564
565 if constexpr (BlockBit >= 0)
566 _changesMask.Set(BlockBit);
567
568 _changesMask.Set(Bit);
569 }
570
571 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
573 {
574 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
575
576 _changesMask.Reset(Bit);
577 }
578
579 template<typename Derived, typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
581 {
582 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
583
584 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
585 _changesMask.Reset(FirstElementBit + index);
586 else
587 _changesMask.Reset(FirstElementBit);
588 }
589
590 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
592 {
593 _changesMask.Reset(Bit);
594 (static_cast<Derived*>(this)->*field).ClearChanged(index);
595 }
596
597 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
599 {
600 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
601
602 _changesMask.Reset(Bit);
603 }
604
605 Mask const& GetChangesMask() const { return _changesMask; }
606
607 protected:
608 template<typename T, int32 BlockBit, uint32 Bit>
610 {
611 ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{});
612 }
613
614 template<typename T, int32 BlockBit, uint32 Bit>
615 static void ClearChangesMask(UpdateField<T, BlockBit, Bit>&, std::false_type) { }
616
617 template<typename T, int32 BlockBit, uint32 Bit>
618 static void ClearChangesMask(UpdateField<T, BlockBit, Bit>& field, std::true_type)
619 {
620 field._value.ClearChangesMask();
621 }
622
623 template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
625 {
626 ClearChangesMask(field, std::disjunction<std::is_base_of<HasChangesMaskTag, T>, std::is_base_of<IsUpdateFieldHolderTag, T>>{});
627 }
628
629 template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
631
632 template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
634 {
635 for (uint32 i = 0; i < Size; ++i)
636 field._values[i].ClearChangesMask();
637 }
638
639 template<typename T, int32 BlockBit, uint32 Bit>
641 {
642 ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{});
643 field.ClearChangesMask();
644 }
645
646 template<typename T, int32 BlockBit, uint32 Bit>
648
649 template<typename T, int32 BlockBit, uint32 Bit>
650 static void ClearChangesMask(DynamicUpdateField<T, BlockBit, Bit>& field, std::true_type)
651 {
652 for (uint32 i = 0; i < field._values.size(); ++i)
653 field._values[i].ClearChangesMask();
654 }
655
656 template<typename T, int32 BlockBit, uint32 Bit>
658 {
659 ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{});
660 }
661
662 template<typename T, int32 BlockBit, uint32 Bit>
664
665 template<typename T, int32 BlockBit, uint32 Bit>
666 static void ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit>& field, std::true_type)
667 {
668 if (field.has_value())
669 field._value->ClearChangesMask();
670 }
671
673 };
674
676 {
677 public:
678 explicit UpdateFieldHolder(Object* owner) : _owner(owner)
679 {
680 }
681
682 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
684 {
685 _changesMask.Set(Bit);
686 return { (static_cast<Derived*>(_owner)->*field)._value };
687 }
688
689 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
691 {
692 _changesMask.Reset(Bit);
693 (static_cast<Derived*>(_owner)->*field)._value.ClearChangesMask();
694 }
695
697 {
698 return _changesMask.GetBlock(0);
699 }
700
701 bool HasChanged(uint32 index) const
702 {
703 return _changesMask[index];
704 }
705
706 private:
709 };
710
711 template<typename T>
713 {
714 template<typename F, bool PublicSet>
716
717 template<typename F, bool PublicSet>
719
720 template<std::size_t Bits>
721 friend class HasChangesMask;
722
723 friend class UpdateFieldHolder;
724
725 public:
726 using value_type = T;
727
728 operator T const& () const
729 {
730 return _value;
731 }
732 T const* operator->() const
733 {
734 return &_value;
735 }
736 T const& operator*() const
737 {
738 return _value;
739 }
740
741 private:
742 T _value = {};
743 };
744
745 template<typename T, int32 BlockBit, uint32 Bit>
746 class UpdateField : public UpdateFieldBase<T>
747 {
748 };
749
750 template<typename T>
752 {
753 };
754
755 template<typename T, std::size_t Size>
757 {
758 template<typename F, bool PublicSet>
760
761 template<typename F, bool PublicSet>
763
764 template<std::size_t Bits>
765 friend class HasChangesMask;
766
767 public:
768 using value_type = T;
769
770 T const* begin() const
771 {
772 return std::begin(_values);
773 }
774
775 T const* end() const
776 {
777 return std::end(_values);
778 }
779
780 static constexpr std::size_t size()
781 {
782 return Size;
783 }
784
785 T const& operator[](std::size_t index) const
786 {
787 return _values[index];
788 }
789
790 private:
791 T _values[Size] = {};
792 };
793
794 // workaround functions for internal compiler errors in msvc 19.33.31629
795 template<typename T>
796 constexpr std::size_t size()
797 {
798 return T::size();
799 }
800
801 template<typename T>
802 constexpr std::size_t size_of_value_type()
803 {
804 return sizeof(typename T::value_type);
805 }
806
807 template<typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit>
809 {
810 };
811
812 void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data, int32 bitsForSize = 32);
813 void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data, int32 bitsForSize = 32);
814
815 template<typename T>
817 {
818 template<typename F, bool PublicSet>
820
821 template<typename F, bool PublicSet>
823
824 template<std::size_t Bits>
825 friend class HasChangesMask;
826
827 public:
828 using value_type = T;
829
830 T const* data() const
831 {
832 return _values.data();
833 }
834
835 typename std::vector<T>::const_iterator begin() const
836 {
837 return _values.begin();
838 }
839
840 typename std::vector<T>::const_iterator end() const
841 {
842 return _values.end();
843 }
844
845 bool empty() const
846 {
847 return _values.empty();
848 }
849
850 std::size_t size() const
851 {
852 return _values.size();
853 }
854
855 T const& operator[](std::size_t index) const
856 {
857 return _values[index];
858 }
859
860 int32 FindIndex(T const& value) const
861 {
862 auto itr = std::find(_values.begin(), _values.end(), value);
863 if (itr != _values.end())
864 return int32(std::distance(_values.begin(), itr));
865
866 return -1;
867 }
868
869 template<typename Pred>
870 int32 FindIndexIf(Pred pred) const
871 {
872 auto itr = std::find_if(_values.begin(), _values.end(), std::ref(pred));
873 if (itr != _values.end())
874 return int32(std::distance(_values.begin(), itr));
875
876 return -1;
877 }
878
879 bool HasChanged(uint32 index) const
880 {
881 return (_updateMask[index / 32] & (1 << (index % 32))) != 0;
882 }
883
884 void WriteUpdateMask(ByteBuffer& data, int32 bitsForSize = 32) const
885 {
887 }
888
889 private:
890 void MarkChanged(std::size_t index)
891 {
892 std::size_t block = UpdateMaskHelpers::GetBlockIndex(index);
893 if (block >= _updateMask.size())
894 _updateMask.emplace_back(0);
895
897 }
898
899 void ClearChanged(std::size_t index)
900 {
901 std::size_t block = UpdateMaskHelpers::GetBlockIndex(index);
902 if (block >= _updateMask.size())
903 _updateMask.emplace_back(0);
904
906 }
907
909 {
910 std::fill(_updateMask.begin(), _updateMask.end(), 0);
911 }
912
913 std::vector<T> _values;
914 std::vector<uint32> _updateMask;
915 };
916
917 template<typename T, int32 BlockBit, uint32 Bit>
919 {
920 };
921
922 template<typename T>
924 {
925 template<typename F, bool PublicSet>
927
928 template<typename F, bool PublicSet>
930
931 template<std::size_t Bits>
932 friend class HasChangesMask;
933
934 template<typename F>
936
937 public:
938 using value_type = T;
939 using IsLarge = std::integral_constant<bool, sizeof(void*) * 3 < sizeof(T)>;
940 using StorageType = std::conditional_t<IsLarge::value, std::unique_ptr<T>, Optional<T>>;
941
943 {
944 DestroyValue();
945 }
946
947 bool has_value() const
948 {
949 return !!_value;
950 }
951
952 operator T const& () const
953 {
954 return *_value;
955 }
956 T const* operator->() const
957 {
958 return &(*_value);
959 }
960 T const& operator*() const
961 {
962 return *_value;
963 }
964
965 private:
967 {
969 }
970
971 void ConstructValue(std::false_type)
972 {
973 _value.emplace();
974 }
975
976 void ConstructValue(std::true_type)
977 {
978 _value = std::make_unique<T>();
979 }
980
982 {
983 _value.reset();
984 }
985
987 };
988
989 template<typename T, int32 BlockBit, uint32 Bit>
991 {
992 };
993
994 template<typename T>
996 {
997 using value_type = T;
998 };
999}
1000
1001#endif // UpdateField_h__
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
Definition: Object.h:150
std::vector< T >::const_iterator begin() const
Definition: UpdateField.h:835
void ClearChanged(std::size_t index)
Definition: UpdateField.h:899
std::vector< T >::const_iterator end() const
Definition: UpdateField.h:840
bool HasChanged(uint32 index) const
Definition: UpdateField.h:879
void MarkChanged(std::size_t index)
Definition: UpdateField.h:890
std::vector< T > _values
Definition: UpdateField.h:913
T const & operator[](std::size_t index) const
Definition: UpdateField.h:855
void WriteUpdateMask(ByteBuffer &data, int32 bitsForSize=32) const
Definition: UpdateField.h:884
std::vector< uint32 > _updateMask
Definition: UpdateField.h:914
std::size_t size() const
Definition: UpdateField.h:850
T const * data() const
Definition: UpdateField.h:830
int32 FindIndexIf(Pred pred) const
Definition: UpdateField.h:870
int32 FindIndex(T const &value) const
Definition: UpdateField.h:860
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &, std::false_type)
Definition: UpdateField.h:663
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:483
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &field)
Definition: UpdateField.h:657
MutableFieldReference< T, false > ModifyValue(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:497
void ClearChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:572
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &field, std::true_type)
Definition: UpdateField.h:618
MutableFieldReference< T, false > ModifyValue(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*field), uint32 index)
Definition: UpdateField.h:490
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &field, std::true_type)
Definition: UpdateField.h:633
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &, std::false_type)
Definition: UpdateField.h:647
void ClearChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field), uint32 index)
Definition: UpdateField.h:591
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &field, std::true_type)
Definition: UpdateField.h:650
MutableFieldReference< T, false > ModifyValue(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field), uint32 index)
Definition: UpdateField.h:504
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &field)
Definition: UpdateField.h:624
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &, std::false_type)
Definition: UpdateField.h:630
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &field)
Definition: UpdateField.h:609
void ClearChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:598
void MarkChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:561
Mask const & GetChangesMask() const
Definition: UpdateField.h:605
void MarkChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*), uint32)
Definition: UpdateField.h:550
void ClearChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
Definition: UpdateField.h:580
MutableFieldReference< T, false > ModifyValue(OptionalUpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:520
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &field)
Definition: UpdateField.h:640
void MarkChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
Definition: UpdateField.h:538
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &field, std::true_type)
Definition: UpdateField.h:666
void MarkChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:527
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &, std::false_type)
Definition: UpdateField.h:615
T const & operator*() const
Definition: UpdateField.h:960
std::integral_constant< bool, sizeof(void *) *3< sizeof(T)> IsLarge
Definition: UpdateField.h:939
void ConstructValue(std::false_type)
Definition: UpdateField.h:971
std::conditional_t< IsLarge::value, std::unique_ptr< T >, Optional< T > > StorageType
Definition: UpdateField.h:940
T const * operator->() const
Definition: UpdateField.h:956
void ConstructValue(std::true_type)
Definition: UpdateField.h:976
T const * begin() const
Definition: UpdateField.h:770
static constexpr std::size_t size()
Definition: UpdateField.h:780
T const & operator[](std::size_t index) const
Definition: UpdateField.h:785
T const * end() const
Definition: UpdateField.h:775
T const & operator*() const
Definition: UpdateField.h:736
T const * operator->() const
Definition: UpdateField.h:732
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:683
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:690
UpdateMask< NUM_CLIENT_OBJECT_TYPES > _changesMask
Definition: UpdateField.h:707
bool HasChanged(uint32 index) const
Definition: UpdateField.h:701
UpdateFieldHolder(Object *owner)
Definition: UpdateField.h:678
uint32 GetChangedObjectTypeMask() const
Definition: UpdateField.h:696
uint32 GetBlock(uint32 index) const
Definition: UpdateMask.h:53
void Reset(uint32 index)
Definition: UpdateMask.h:71
void Set(uint32 index)
Definition: UpdateMask.h:84
bool Size(ContainerUnorderedMap< TypeList< H, T >, KEY_TYPE > const &elements, std::size_t *size, SPECIFIC_TYPE *obj)
Definition: Object.h:109
constexpr std::size_t size()
Definition: UpdateField.h:796
UpdateFieldFlag
Definition: UpdateField.h:34
void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer &data, int32 bitsForSize=32)
Definition: UpdateField.cpp:43
void WriteDynamicFieldUpdateMask(std::size_t size, std::vector< uint32 > const &updateMask, ByteBuffer &data, int32 bitsForSize=32)
Definition: UpdateField.cpp:21
constexpr std::size_t size_of_value_type()
Definition: UpdateField.h:802
DEFINE_ENUM_FLAG(UpdateFieldFlag)
constexpr std::size_t GetBlockIndex(std::size_t bit)
Definition: UpdateMask.h:26
constexpr uint32 GetBlockFlag(std::size_t bit)
Definition: UpdateMask.h:27
DynamicUpdateFieldSetter(std::vector< T > &values, std::vector< uint32 > &updateMask)
Definition: UpdateField.h:160
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
Definition: UpdateField.h:146
void RemoveValue(std::size_t index)
Definition: UpdateField.h:186
std::vector< T > & _values
Definition: UpdateField.h:226
static void MarkNewValue(T &, std::false_type)
Definition: UpdateField.h:217
static void MarkNewValue(T &value, std::true_type)
Definition: UpdateField.h:221
void MarkChanged(std::size_t index)
Definition: UpdateField.h:208
std::vector< uint32 > & _updateMask
Definition: UpdateField.h:227
insert_result InsertValue(std::size_t index)
Definition: UpdateField.h:174
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))
Definition: UpdateField.h:357
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)
Definition: UpdateField.h:342
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)
Definition: UpdateField.h:278
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)
Definition: UpdateField.h:307
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, DynamicUpdateFieldSetter< V > > ModifyValue(DynamicUpdateField< V, BlockBit, Bit >(T::*field))
Definition: UpdateField.h:291
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))
Definition: UpdateField.h:262
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)
Definition: UpdateField.h:365
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, OptionalUpdateFieldSetter< V > > ModifyValue(OptionalUpdateField< V, BlockBit, Bit >(T::*field))
Definition: UpdateField.h:326
typename T::value_type value_type
Definition: UpdateField.h:377
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)
Definition: UpdateField.h:421
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()
Definition: UpdateField.h:390
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)
Definition: UpdateField.h:448
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)
Definition: UpdateField.h:402
std::enable_if_t< std::is_base_of_v< DynamicUpdateFieldBase< value_type >, U >, DynamicUpdateFieldSetter< value_type > > ModifyValue()
Definition: UpdateField.h:409
std::enable_if_t< std::is_base_of_v< OptionalUpdateFieldBase< value_type >, U >, OptionalUpdateFieldSetter< value_type > > ModifyValue()
Definition: UpdateField.h:436
OptionalUpdateFieldSetter(OptionalUpdateFieldBase< T > &field)
Definition: UpdateField.h:236
OptionalUpdateFieldBase< T > & _field
Definition: UpdateField.h:245
friend void RemoveOptionalUpdateFieldValue(OptionalUpdateFieldSetter< F > &setter)
bool SetValue(T value)
Definition: UpdateField.h:105
friend bool SetUpdateFieldValue(UpdateFieldSetter< F > &setter, typename UpdateFieldSetter< F >::value_type &&value)
UpdateFieldSetter(T &value)
Definition: UpdateField.h:95