Core/Objects: Move UF::UpdateFieldHolder to Object.h and remove owner object pointer since it can be calculated dynamically

(cherry picked from commit 42042504fa)
This commit is contained in:
Shauren
2024-10-28 18:44:41 +01:00
committed by Ovahlord
parent 56ada5b873
commit 80a37787c6
3 changed files with 59 additions and 40 deletions

View File

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

View File

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

View File

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