aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Object/Object.cpp2
-rw-r--r--src/server/game/Entities/Object/Object.h55
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateField.h42
3 files changed, 59 insertions, 40 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 86e742426e0..66a9124befd 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -70,7 +70,7 @@ constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max
MAX_VISIBILITY_DISTANCE
};
-Object::Object() : m_values(this), m_scriptRef(this, NoopObjectDeleter())
+Object::Object() : m_scriptRef(this, NoopObjectDeleter())
{
m_objectTypeId = TYPEID_OBJECT;
m_objectType = TYPEMASK_OBJECT;
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 55d6e2e1d18..0fdeed66e7d 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -107,6 +107,30 @@ struct CreateObjectBits
namespace UF
{
+ class UpdateFieldHolder
+ {
+ public:
+ template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
+ inline MutableFieldReference<T, false> ModifyValue(UpdateField<T, BlockBit, Bit>(Derived::* field));
+
+ template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
+ inline void ClearChangesMask(UpdateField<T, BlockBit, Bit>(Derived::* field));
+
+ uint32 GetChangedObjectTypeMask() const { return _changesMask; }
+
+ bool HasChanged(uint32 index) const { return (_changesMask & UpdateMaskHelpers::GetBlockFlag(index)) != 0; }
+
+ inline Object* GetOwner();
+
+ private:
+ friend Object;
+
+ // This class is tightly tied to Object::m_values member, do not construct elsewhere
+ UpdateFieldHolder() : _changesMask(0) { }
+
+ uint32 _changesMask;
+ };
+
template<typename T>
inline bool SetUpdateFieldValue(UpdateFieldSetter<T>& setter, typename UpdateFieldSetter<T>::value_type&& value)
{
@@ -264,6 +288,7 @@ class TC_GAME_API Object
Conversation* ToConversation() { if (IsConversation()) return reinterpret_cast<Conversation*>(this); else return nullptr; }
Conversation const* ToConversation() const { if (IsConversation()) return reinterpret_cast<Conversation const*>(this); else return nullptr; }
+ friend UF::UpdateFieldHolder;
UF::UpdateFieldHolder m_values;
UF::UpdateField<UF::ObjectData, 0, TYPEID_OBJECT> m_objectData;
@@ -425,6 +450,36 @@ class TC_GAME_API Object
Object& operator=(Object&& right) = delete;
};
+inline Object* UF::UpdateFieldHolder::GetOwner()
+{
+#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winvalid-offsetof"
+#endif
+
+ return reinterpret_cast<Object*>(reinterpret_cast<std::byte*>(this) - offsetof(Object, m_values));
+
+#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
+#pragma GCC diagnostic pop
+#endif
+}
+
+template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
+inline UF::MutableFieldReference<T, false> UF::UpdateFieldHolder::ModifyValue(UpdateField<T, BlockBit, Bit> Derived::* field)
+{
+ Object* owner = GetOwner();
+ _changesMask |= UpdateMaskHelpers::GetBlockFlag(Bit);
+ return { (static_cast<Derived*>(owner)->*field)._value };
+}
+
+template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
+inline void UF::UpdateFieldHolder::ClearChangesMask(UpdateField<T, BlockBit, Bit> Derived::* field)
+{
+ Object* owner = GetOwner();
+ _changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit);
+ (static_cast<Derived*>(owner)->*field)._value.ClearChangesMask();
+}
+
template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, size_t ARRAY_SIZE>
class FlaggedValuesArray32
{
diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h
index fdad7e0d18e..ebf07df9c28 100644
--- a/src/server/game/Entities/Object/Updates/UpdateField.h
+++ b/src/server/game/Entities/Object/Updates/UpdateField.h
@@ -672,42 +672,6 @@ namespace UF
Mask _changesMask;
};
- class UpdateFieldHolder
- {
- public:
- explicit UpdateFieldHolder(Object* owner) : _owner(owner)
- {
- }
-
- template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
- MutableFieldReference<T, false> ModifyValue(UpdateField<T, BlockBit, Bit>(Derived::* field))
- {
- _changesMask.Set(Bit);
- return { (static_cast<Derived*>(_owner)->*field)._value };
- }
-
- template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
- void ClearChangesMask(UpdateField<T, BlockBit, Bit>(Derived::* field))
- {
- _changesMask.Reset(Bit);
- (static_cast<Derived*>(_owner)->*field)._value.ClearChangesMask();
- }
-
- uint32 GetChangedObjectTypeMask() const
- {
- return _changesMask.GetBlock(0);
- }
-
- bool HasChanged(uint32 index) const
- {
- return _changesMask[index];
- }
-
- private:
- UpdateMask<NUM_CLIENT_OBJECT_TYPES> _changesMask;
- Object* _owner;
- };
-
template<typename T>
class UpdateFieldBase : public IsUpdateFieldHolderTag
{
@@ -878,7 +842,7 @@ namespace UF
bool HasChanged(uint32 index) const
{
- return (_updateMask[index / 32] & (1 << (index % 32))) != 0;
+ return (_updateMask[UpdateMaskHelpers::GetBlockIndex(index)] & UpdateMaskHelpers::GetBlockFlag(index)) != 0;
}
void WriteUpdateMask(ByteBuffer& data, int32 bitsForSize = 32) const
@@ -949,9 +913,9 @@ namespace UF
return !!_value;
}
- operator T const& () const
+ operator bool const() const
{
- return *_value;
+ return has_value();
}
T const* operator->() const
{