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, int32 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, 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>,
277 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
279 {
280 _value._changesMask.Set(Bit);
281 if constexpr (FirstElementBit >= 0)
282 {
283 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, V>)
284 _value._changesMask.Set(FirstElementBit + index);
285 else
286 _value._changesMask.Set(FirstElementBit);
287 }
288
289 return { (_value.*field)._values[index] };
290 }
291
292 template<typename V, int32 BlockBit, uint32 Bit, typename U = T>
293 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, DynamicUpdateFieldSetter<V>>
295 {
296 if constexpr (BlockBit >= 0)
297 _value._changesMask.Set(BlockBit);
298
299 _value._changesMask.Set(Bit);
300 return { (_value.*field)._values, (_value.*field)._updateMask };
301 }
302
303 template<typename V, int32 BlockBit, uint32 Bit, typename U = T>
304 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>,
305 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
307 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
309 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
311 {
312 if (index >= (_value.*field).size())
313 {
314 // fill with zeros until reaching desired slot
315 (_value.*field)._values.resize(index + 1);
316 (_value.*field)._updateMask.resize(((_value.*field)._values.size() + 31) / 32);
317 }
318
319 if constexpr (BlockBit >= 0)
320 _value._changesMask.Set(BlockBit);
321
322 _value._changesMask.Set(Bit);
323 (_value.*field).MarkChanged(index);
324 return { (_value.*field)._values[index] };
325 }
326
327 template<typename V, int32 BlockBit, uint32 Bit, typename U = T>
328 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>, OptionalUpdateFieldSetter<V>>
330 {
331 if constexpr (BlockBit >= 0)
332 _value._changesMask.Set(BlockBit);
333
334 _value._changesMask.Set(Bit);
335 return { _value.*field };
336 }
337
338 template<typename V, int32 BlockBit, uint32 Bit, typename U = T>
339 std::enable_if_t<std::is_base_of_v<HasChangesMaskTag, U>,
340 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
342 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
344 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>>>
346 {
347 if (!(_value.*field).has_value())
348 (_value.*field).ConstructValue();
349
350 if constexpr (BlockBit >= 0)
351 _value._changesMask.Set(BlockBit);
352
353 _value._changesMask.Set(Bit);
354 return { *((_value.*field)._value) };
355 }
356
357 template<typename V, typename U = T>
358 std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U> && !std::is_array_v<V>,
359 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>
360 ModifyValue(V(T::* field))
361 {
362 return { _value.*field };
363 }
364
365 template<typename V, std::size_t Size, typename U = T>
366 std::enable_if_t<!std::is_base_of_v<HasChangesMaskTag, U>,
367 std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>
368 ModifyValue(V(T::* field)[Size], uint32 index)
369 {
370 return { (_value.*field)[index] };
371 }
372
373 private:
375 };
376
377 template<typename T, bool PublicSet>
379 {
380 using value_type = typename T::value_type;
381
383 {
384 }
385
386 template<typename U = T>
387 std::enable_if_t<std::is_base_of_v<UpdateFieldBase<value_type>, U>,
388 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
390 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
392 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
394 {
395 return { _value._value };
396 }
397
398 template<typename U = T>
399 std::enable_if_t<std::is_base_of_v<UpdateFieldArrayBaseWithoutSize<value_type>, U>,
400 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
402 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
404 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
406 {
407 return { _value._values[index] };
408 }
409
410 template<typename U = T>
411 std::enable_if_t<std::is_base_of_v<DynamicUpdateFieldBase<value_type>, U>, DynamicUpdateFieldSetter<value_type>>
413 {
414 return { _value._values, _value._updateMask };
415 }
416
417 template<typename U = T>
418 std::enable_if_t<std::is_base_of_v<DynamicUpdateFieldBase<value_type>, U>,
419 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
421 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
423 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
425 {
426 if (index >= _value.size())
427 {
428 // fill with zeros until reaching desired slot
429 _value._values.resize(index + 1);
430 _value._updateMask.resize((_value._values.size() + 31) / 32);
431 }
432
433 _value.MarkChanged(index);
434 return { _value._values[index] };
435 }
436
437 template<typename U = T>
438 std::enable_if_t<std::is_base_of_v<OptionalUpdateFieldBase<value_type>, U>, OptionalUpdateFieldSetter<value_type>>
440 {
441 return { _value };
442 }
443
444 template<typename U = T>
445 std::enable_if_t<std::is_base_of_v<OptionalUpdateFieldBase<value_type>, U>,
446 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
448 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
450 std::conditional_t<PublicSet, UpdateFieldPublicSetter<value_type>, UpdateFieldSetter<value_type>>>>>
452 {
453 if (!_value.has_value())
454 _value.ConstructValue();
455
456 return { *(_value._value) };
457 }
458
459 private:
461 };
462
463 template<std::size_t Bits>
465 {
466 template<typename T>
468
469 template<typename T, bool PublicSet>
471
472 template<typename T, int32 BlockBit, uint32 Bit>
473 friend class UpdateField;
474
475 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
476 friend class UpdateFieldArray;
477
478 template<typename T, int32 BlockBit, uint32 Bit>
479 friend class DynamicUpdateField;
480
481 public:
484
485 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
487 {
488 MarkChanged(field);
489 return { (static_cast<Derived*>(this)->*field)._value };
490 }
491
492 template<typename Derived, typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
494 {
495 MarkChanged(field, index);
496 return { (static_cast<Derived*>(this)->*field)._values[index] };
497 }
498
499 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
501 {
502 MarkChanged(field);
503 return { (static_cast<Derived*>(this)->*field)._values };
504 }
505
506 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
508 {
509 DynamicUpdateField<T, BlockBit, Bit>& uf = (static_cast<Derived*>(this)->*field);
510 if (index >= uf.size())
511 {
512 // fill with zeros until reaching desired slot
513 uf._values.resize(index + 1);
514 uf._updateMask.resize((uf._values.size() + 31) / 32);
515 }
516
517 MarkChanged(field);
518 (static_cast<Derived*>(this)->*field).MarkChanged(index);
519 return { uf._values[index] };
520 }
521
522 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
524 {
525 MarkChanged(field);
526 return { *((static_cast<Derived*>(this)->*field)._value) };
527 }
528
529 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
531 {
532 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
533
534 if constexpr (BlockBit >= 0)
535 _changesMask.Set(BlockBit);
536
537 _changesMask.Set(Bit);
538 }
539
540 template<typename Derived, typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
542 {
543 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
544
545 _changesMask.Set(Bit);
546 if constexpr (FirstElementBit >= 0)
547 {
548 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
549 _changesMask.Set(FirstElementBit + index);
550 else
551 _changesMask.Set(FirstElementBit);
552 }
553 }
554
555 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
557 {
558 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
559
560 if constexpr (BlockBit >= 0)
561 _changesMask.Set(BlockBit);
562
563 _changesMask.Set(Bit);
564 }
565
566 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
568 {
569 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
570
571 if constexpr (BlockBit >= 0)
572 _changesMask.Set(BlockBit);
573
574 _changesMask.Set(Bit);
575 }
576
577 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
579 {
580 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
581
582 _changesMask.Reset(Bit);
583 }
584
585 template<typename Derived, typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
587 {
588 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
589
590 if constexpr (FirstElementBit >= 0)
591 {
592 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
593 _changesMask.Reset(FirstElementBit + index);
594 else
595 _changesMask.Reset(FirstElementBit);
596 }
597 }
598
599 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
601 {
602 _changesMask.Reset(Bit);
603 (static_cast<Derived*>(this)->*field).ClearChanged(index);
604 }
605
606 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
608 {
609 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
610
611 _changesMask.Reset(Bit);
612 }
613
614 Mask const& GetChangesMask() const { return _changesMask; }
615
616 protected:
617 template<typename T, int32 BlockBit, uint32 Bit>
619 {
620 ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{});
621 }
622
623 template<typename T, int32 BlockBit, uint32 Bit>
624 static void ClearChangesMask(UpdateField<T, BlockBit, Bit>&, std::false_type) { }
625
626 template<typename T, int32 BlockBit, uint32 Bit>
627 static void ClearChangesMask(UpdateField<T, BlockBit, Bit>& field, std::true_type)
628 {
629 field._value.ClearChangesMask();
630 }
631
632 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
634 {
635 ClearChangesMask(field, std::disjunction<std::is_base_of<HasChangesMaskTag, T>, std::is_base_of<IsUpdateFieldHolderTag, T>>{});
636 }
637
638 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
640
641 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
643 {
644 for (uint32 i = 0; i < Size; ++i)
645 field._values[i].ClearChangesMask();
646 }
647
648 template<typename T, int32 BlockBit, uint32 Bit>
650 {
651 ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{});
652 field.ClearChangesMask();
653 }
654
655 template<typename T, int32 BlockBit, uint32 Bit>
657
658 template<typename T, int32 BlockBit, uint32 Bit>
659 static void ClearChangesMask(DynamicUpdateField<T, BlockBit, Bit>& field, std::true_type)
660 {
661 for (uint32 i = 0; i < field._values.size(); ++i)
662 field._values[i].ClearChangesMask();
663 }
664
665 template<typename T, int32 BlockBit, uint32 Bit>
667 {
668 ClearChangesMask(field, std::is_base_of<HasChangesMaskTag, T>{});
669 }
670
671 template<typename T, int32 BlockBit, uint32 Bit>
673
674 template<typename T, int32 BlockBit, uint32 Bit>
675 static void ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit>& field, std::true_type)
676 {
677 if (field.has_value())
678 field._value->ClearChangesMask();
679 }
680
682 };
683
685 {
686 public:
687 explicit UpdateFieldHolder(Object* owner) : _owner(owner)
688 {
689 }
690
691 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
693 {
694 _changesMask.Set(Bit);
695 return { (static_cast<Derived*>(_owner)->*field)._value };
696 }
697
698 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
700 {
701 _changesMask.Reset(Bit);
702 (static_cast<Derived*>(_owner)->*field)._value.ClearChangesMask();
703 }
704
706 {
707 return _changesMask.GetBlock(0);
708 }
709
710 bool HasChanged(uint32 index) const
711 {
712 return _changesMask[index];
713 }
714
715 private:
718 };
719
720 template<typename T>
722 {
723 template<typename F, bool PublicSet>
725
726 template<typename F, bool PublicSet>
728
729 template<std::size_t Bits>
730 friend class HasChangesMask;
731
732 friend class UpdateFieldHolder;
733
734 public:
735 using value_type = T;
736
737 operator T const& () const
738 {
739 return _value;
740 }
741 T const* operator->() const
742 {
743 return &_value;
744 }
745 T const& operator*() const
746 {
747 return _value;
748 }
749
750 private:
751 T _value = {};
752 };
753
754 template<typename T, int32 BlockBit, uint32 Bit>
755 class UpdateField : public UpdateFieldBase<T>
756 {
757 };
758
759 template<typename T>
761 {
762 };
763
764 template<typename T, std::size_t Size>
766 {
767 template<typename F, bool PublicSet>
769
770 template<typename F, bool PublicSet>
772
773 template<std::size_t Bits>
774 friend class HasChangesMask;
775
776 public:
777 using value_type = T;
778
779 T const* begin() const
780 {
781 return std::begin(_values);
782 }
783
784 T const* end() const
785 {
786 return std::end(_values);
787 }
788
789 static constexpr std::size_t size()
790 {
791 return Size;
792 }
793
794 T const& operator[](std::size_t index) const
795 {
796 return _values[index];
797 }
798
799 private:
800 T _values[Size] = {};
801 };
802
803 // workaround functions for internal compiler errors in msvc 19.33.31629
804 template<typename T>
805 constexpr std::size_t size()
806 {
807 return T::size();
808 }
809
810 template<typename T>
811 constexpr std::size_t size_of_value_type()
812 {
813 return sizeof(typename T::value_type);
814 }
815
816 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
818 {
819 };
820
821 void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data, int32 bitsForSize = 32);
822 void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data, int32 bitsForSize = 32);
823
824 template<typename T>
826 {
827 template<typename F, bool PublicSet>
829
830 template<typename F, bool PublicSet>
832
833 template<std::size_t Bits>
834 friend class HasChangesMask;
835
836 public:
837 using value_type = T;
838
839 T const* data() const
840 {
841 return _values.data();
842 }
843
844 typename std::vector<T>::const_iterator begin() const
845 {
846 return _values.begin();
847 }
848
849 typename std::vector<T>::const_iterator end() const
850 {
851 return _values.end();
852 }
853
854 bool empty() const
855 {
856 return _values.empty();
857 }
858
859 std::size_t size() const
860 {
861 return _values.size();
862 }
863
864 T const& operator[](std::size_t index) const
865 {
866 return _values[index];
867 }
868
869 int32 FindIndex(T const& value) const
870 {
871 auto itr = std::find(_values.begin(), _values.end(), value);
872 if (itr != _values.end())
873 return int32(std::distance(_values.begin(), itr));
874
875 return -1;
876 }
877
878 template<typename Pred>
879 int32 FindIndexIf(Pred pred) const
880 {
881 auto itr = std::find_if(_values.begin(), _values.end(), std::ref(pred));
882 if (itr != _values.end())
883 return int32(std::distance(_values.begin(), itr));
884
885 return -1;
886 }
887
888 bool HasChanged(uint32 index) const
889 {
890 return (_updateMask[index / 32] & (1 << (index % 32))) != 0;
891 }
892
893 void WriteUpdateMask(ByteBuffer& data, int32 bitsForSize = 32) const
894 {
896 }
897
898 private:
899 void MarkChanged(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
908 void ClearChanged(std::size_t index)
909 {
910 std::size_t block = UpdateMaskHelpers::GetBlockIndex(index);
911 if (block >= _updateMask.size())
912 _updateMask.emplace_back(0);
913
915 }
916
918 {
919 std::fill(_updateMask.begin(), _updateMask.end(), 0);
920 }
921
922 std::vector<T> _values;
923 std::vector<uint32> _updateMask;
924 };
925
926 template<typename T, int32 BlockBit, uint32 Bit>
928 {
929 };
930
931 template<typename T>
933 {
934 template<typename F, bool PublicSet>
936
937 template<typename F, bool PublicSet>
939
940 template<std::size_t Bits>
941 friend class HasChangesMask;
942
943 template<typename F>
945
946 public:
947 using value_type = T;
948 using IsLarge = std::integral_constant<bool, sizeof(void*) * 3 < sizeof(T)>;
949 using StorageType = std::conditional_t<IsLarge::value, std::unique_ptr<T>, Optional<T>>;
950
952 {
953 DestroyValue();
954 }
955
956 bool has_value() const
957 {
958 return !!_value;
959 }
960
961 operator T const& () const
962 {
963 return *_value;
964 }
965 T const* operator->() const
966 {
967 return &(*_value);
968 }
969 T const& operator*() const
970 {
971 return *_value;
972 }
973
974 private:
976 {
978 }
979
980 void ConstructValue(std::false_type)
981 {
982 _value.emplace();
983 }
984
985 void ConstructValue(std::true_type)
986 {
987 _value = std::make_unique<T>();
988 }
989
991 {
992 _value.reset();
993 }
994
996 };
997
998 template<typename T, int32 BlockBit, uint32 Bit>
1000 {
1001 };
1002
1003 template<typename T>
1005 {
1006 using value_type = T;
1007 };
1008}
1009
1010#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:151
std::vector< T >::const_iterator begin() const
Definition: UpdateField.h:844
void ClearChanged(std::size_t index)
Definition: UpdateField.h:908
std::vector< T >::const_iterator end() const
Definition: UpdateField.h:849
bool HasChanged(uint32 index) const
Definition: UpdateField.h:888
void MarkChanged(std::size_t index)
Definition: UpdateField.h:899
std::vector< T > _values
Definition: UpdateField.h:922
T const & operator[](std::size_t index) const
Definition: UpdateField.h:864
void WriteUpdateMask(ByteBuffer &data, int32 bitsForSize=32) const
Definition: UpdateField.h:893
std::vector< uint32 > _updateMask
Definition: UpdateField.h:923
std::size_t size() const
Definition: UpdateField.h:859
T const * data() const
Definition: UpdateField.h:839
int32 FindIndexIf(Pred pred) const
Definition: UpdateField.h:879
int32 FindIndex(T const &value) const
Definition: UpdateField.h:869
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &, std::false_type)
Definition: UpdateField.h:672
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:486
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &field)
Definition: UpdateField.h:666
MutableFieldReference< T, false > ModifyValue(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:500
void ClearChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:578
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &field, std::true_type)
Definition: UpdateField.h:627
MutableFieldReference< T, false > ModifyValue(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*field), uint32 index)
Definition: UpdateField.h:493
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &field, std::true_type)
Definition: UpdateField.h:642
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &, std::false_type)
Definition: UpdateField.h:656
void ClearChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field), uint32 index)
Definition: UpdateField.h:600
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &field, std::true_type)
Definition: UpdateField.h:659
MutableFieldReference< T, false > ModifyValue(DynamicUpdateField< T, BlockBit, Bit >(Derived::*field), uint32 index)
Definition: UpdateField.h:507
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &field)
Definition: UpdateField.h:633
static void ClearChangesMask(UpdateFieldArray< T, Size, Bit, FirstElementBit > &, std::false_type)
Definition: UpdateField.h:639
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &field)
Definition: UpdateField.h:618
void ClearChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:607
void MarkChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:567
Mask const & GetChangesMask() const
Definition: UpdateField.h:614
void MarkChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*), uint32)
Definition: UpdateField.h:556
void ClearChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
Definition: UpdateField.h:586
MutableFieldReference< T, false > ModifyValue(OptionalUpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:523
static void ClearChangesMask(DynamicUpdateField< T, BlockBit, Bit > &field)
Definition: UpdateField.h:649
void MarkChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
Definition: UpdateField.h:541
static void ClearChangesMask(OptionalUpdateField< T, BlockBit, Bit > &field, std::true_type)
Definition: UpdateField.h:675
void MarkChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
Definition: UpdateField.h:530
static void ClearChangesMask(UpdateField< T, BlockBit, Bit > &, std::false_type)
Definition: UpdateField.h:624
T const & operator*() const
Definition: UpdateField.h:969
std::integral_constant< bool, sizeof(void *) *3< sizeof(T)> IsLarge
Definition: UpdateField.h:948
void ConstructValue(std::false_type)
Definition: UpdateField.h:980
std::conditional_t< IsLarge::value, std::unique_ptr< T >, Optional< T > > StorageType
Definition: UpdateField.h:949
T const * operator->() const
Definition: UpdateField.h:965
void ConstructValue(std::true_type)
Definition: UpdateField.h:985
T const * begin() const
Definition: UpdateField.h:779
static constexpr std::size_t size()
Definition: UpdateField.h:789
T const & operator[](std::size_t index) const
Definition: UpdateField.h:794
T const * end() const
Definition: UpdateField.h:784
T const & operator*() const
Definition: UpdateField.h:745
T const * operator->() const
Definition: UpdateField.h:741
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:692
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:699
UpdateMask< NUM_CLIENT_OBJECT_TYPES > _changesMask
Definition: UpdateField.h:716
bool HasChanged(uint32 index) const
Definition: UpdateField.h:710
UpdateFieldHolder(Object *owner)
Definition: UpdateField.h:687
uint32 GetChangedObjectTypeMask() const
Definition: UpdateField.h:705
constexpr uint32 GetBlock(uint32 index) const
Definition: UpdateMask.h:59
constexpr void Reset(uint32 index)
Definition: UpdateMask.h:77
constexpr void Set(uint32 index)
Definition: UpdateMask.h:90
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:805
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:811
DEFINE_ENUM_FLAG(UpdateFieldFlag)
constexpr std::size_t GetBlockIndex(std::size_t bit)
Definition: UpdateMask.h:27
constexpr uint32 GetBlockFlag(std::size_t bit)
Definition: UpdateMask.h:28
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:360
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:345
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:310
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, DynamicUpdateFieldSetter< V > > ModifyValue(DynamicUpdateField< V, BlockBit, Bit >(T::*field))
Definition: UpdateField.h:294
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:368
std::enable_if_t< std::is_base_of_v< HasChangesMaskTag, U >, OptionalUpdateFieldSetter< V > > ModifyValue(OptionalUpdateField< V, BlockBit, Bit >(T::*field))
Definition: UpdateField.h:329
typename T::value_type value_type
Definition: UpdateField.h:380
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:424
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:393
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:451
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:405
std::enable_if_t< std::is_base_of_v< DynamicUpdateFieldBase< value_type >, U >, DynamicUpdateFieldSetter< value_type > > ModifyValue()
Definition: UpdateField.h:412
std::enable_if_t< std::is_base_of_v< OptionalUpdateFieldBase< value_type >, U >, OptionalUpdateFieldSetter< value_type > > ModifyValue()
Definition: UpdateField.h:439
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