mirror of https://github.com/zeldaret/botw.git
Havok: Add hkClass and other reflection types
This commit is contained in:
parent
2359ce6fb4
commit
000ca1c6d9
|
@ -21,6 +21,11 @@ add_library(hkStubs OBJECT
|
||||||
Havok/Common/Base/Object/hkReferencedObject.cpp
|
Havok/Common/Base/Object/hkReferencedObject.cpp
|
||||||
Havok/Common/Base/Object/hkReferencedObject.h
|
Havok/Common/Base/Object/hkReferencedObject.h
|
||||||
|
|
||||||
|
Havok/Common/Base/Reflection/hkClass.h
|
||||||
|
Havok/Common/Base/Reflection/hkClassEnum.h
|
||||||
|
Havok/Common/Base/Reflection/hkClassMember.h
|
||||||
|
Havok/Common/Base/Reflection/hkTypeInfo.h
|
||||||
|
|
||||||
Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h
|
Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h
|
||||||
Havok/Common/Base/Thread/Thread/hkThreadLocalData.h
|
Havok/Common/Base/Thread/Thread/hkThreadLocalData.h
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Havok/Common/Base/hkBase.h>
|
||||||
|
|
||||||
|
class hkClassEnum;
|
||||||
|
class hkClassMember;
|
||||||
|
class hkCustomAttributes;
|
||||||
|
class hkStreamWriter;
|
||||||
|
class hkTypedUnion;
|
||||||
|
|
||||||
|
template <typename Key, typename Value>
|
||||||
|
class hkPointerMap;
|
||||||
|
|
||||||
|
class hkClass {
|
||||||
|
public:
|
||||||
|
HK_DECLARE_CLASS_ALLOCATOR(hkClass)
|
||||||
|
HK_DECLARE_REFLECTION()
|
||||||
|
|
||||||
|
enum SignatureFlags {
|
||||||
|
SIGNATURE_LOCAL = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FlagValues {
|
||||||
|
FLAGS_NONE = 0,
|
||||||
|
FLAGS_NOT_SERIALIZABLE = 1,
|
||||||
|
};
|
||||||
|
using Flags = hkFlags<FlagValues, hkUint32>;
|
||||||
|
|
||||||
|
// Note: this is not constexpr and this is the reason Havok code is littered with
|
||||||
|
// static constructor functions that call this hkClass constructor at runtime
|
||||||
|
// even though everything could have been initialised at compile time.
|
||||||
|
hkClass(const char* className, const hkClass* parentClass, int objectSizeInBytes,
|
||||||
|
const hkClass** implementedInterfaces, int numImplementedInterfaces,
|
||||||
|
const hkClassEnum* declaredEnums, int numDeclaredEnums,
|
||||||
|
const hkClassMember* declaredMembers, int numDeclaredMembers,
|
||||||
|
const void* defaults = nullptr, const hkCustomAttributes* attributes = nullptr,
|
||||||
|
hkUint32 flags = 0, hkUint32 version = 0);
|
||||||
|
|
||||||
|
const char* getName() const;
|
||||||
|
bool equals(const hkClass* other) const;
|
||||||
|
|
||||||
|
const hkClass* getParent() const;
|
||||||
|
hkClass* getParent();
|
||||||
|
int getInheritanceDepth() const;
|
||||||
|
hkBool isSuperClass(const hkClass& k) const;
|
||||||
|
const hkClass* getInterface(int i) const;
|
||||||
|
int getNumInterfaces() const;
|
||||||
|
const hkClass* getDeclaredInterface(int i) const;
|
||||||
|
int getNumDeclaredInterfaces() const;
|
||||||
|
|
||||||
|
const hkClassEnum& getEnum(int i) const;
|
||||||
|
const hkClassEnum* getEnumByName(const char* name) const;
|
||||||
|
int getNumEnums() const;
|
||||||
|
const hkClassEnum& getDeclaredEnum(int i) const;
|
||||||
|
const hkClassEnum* getDeclaredEnumByName(const char* name) const;
|
||||||
|
int getNumDeclaredEnums() const;
|
||||||
|
|
||||||
|
const hkClassMember& getMember(int i) const;
|
||||||
|
hkClassMember& getMember(int i);
|
||||||
|
const hkClassMember* getMemberByName(const char* name) const;
|
||||||
|
int getMemberIndexByName(const char* name) const;
|
||||||
|
int getMemberIndexByNameCaseInsensitive(const char* name) const;
|
||||||
|
int getNumMembers() const;
|
||||||
|
const hkClassMember& getDeclaredMember(int i) const;
|
||||||
|
const hkClassMember* getDeclaredMemberByName(const char* name) const;
|
||||||
|
int getDeclaredMemberIndexByName(const char* name) const;
|
||||||
|
int getNumDeclaredMembers() const;
|
||||||
|
|
||||||
|
int getObjectSize() const;
|
||||||
|
void setObjectSize(int size);
|
||||||
|
|
||||||
|
hkBool hasVtable() const;
|
||||||
|
|
||||||
|
hkBool32 hasDefault(int memberIndex) const;
|
||||||
|
hkBool32 hasDeclaredDefault(int declaredIndex) const;
|
||||||
|
hkResult getDefault(int memberIndex, hkStreamWriter* w) const;
|
||||||
|
const void* getDefault(int memberIndex) const;
|
||||||
|
hkResult getDeclaredDefault(int declaredIndex, hkStreamWriter* w) const;
|
||||||
|
hkResult getDefault(int memberIndex, hkTypedUnion& value) const;
|
||||||
|
const void* getDeclaredDefault(int memberIndex) const;
|
||||||
|
hkResult getDeclaredDefault(int declaredIndex, hkTypedUnion& value) const;
|
||||||
|
|
||||||
|
hkUint32 getSignature(int signatureFlags = 0) const;
|
||||||
|
int getDescribedVersion() const;
|
||||||
|
void writeSignature(hkStreamWriter* w) const;
|
||||||
|
|
||||||
|
const hkVariant* getAttribute(const char* id) const;
|
||||||
|
|
||||||
|
const Flags& getFlags() const;
|
||||||
|
Flags& getFlags();
|
||||||
|
|
||||||
|
using UpdateFlagFromClassMap = hkPointerMap<const hkClass*, hkInt32>;
|
||||||
|
static void updateMetadataInplace(hkClass** c, int sourceVersion);
|
||||||
|
static void updateMetadataInplace(hkClass* c, UpdateFlagFromClassMap& updatedAlready,
|
||||||
|
int sourceVersion);
|
||||||
|
|
||||||
|
private:
|
||||||
|
hkResult retrieveMember(int memberIndex, const void*& defaultOut,
|
||||||
|
const hkClassMember*& memberOut) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char* m_name;
|
||||||
|
const hkClass* m_parent;
|
||||||
|
int m_objectSize;
|
||||||
|
int m_numImplementedInterfaces;
|
||||||
|
const class hkClassEnum* m_declaredEnums;
|
||||||
|
int m_numDeclaredEnums;
|
||||||
|
const class hkClassMember* m_declaredMembers;
|
||||||
|
int m_numDeclaredMembers;
|
||||||
|
const void* m_defaults;
|
||||||
|
const hkCustomAttributes* m_attributes;
|
||||||
|
Flags m_flags;
|
||||||
|
int m_describedVersion;
|
||||||
|
};
|
|
@ -0,0 +1,79 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Havok/Common/Base/hkBase.h>
|
||||||
|
|
||||||
|
class hkCustomAttributes;
|
||||||
|
class hkStreamWriter;
|
||||||
|
|
||||||
|
class hkClassEnum {
|
||||||
|
public:
|
||||||
|
HK_DECLARE_CLASS_ALLOCATOR(hkClassEnum)
|
||||||
|
HK_DECLARE_REFLECTION()
|
||||||
|
|
||||||
|
class Item {
|
||||||
|
public:
|
||||||
|
HK_DECLARE_CLASS_ALLOCATOR(Item)
|
||||||
|
HK_DECLARE_REFLECTION()
|
||||||
|
|
||||||
|
constexpr Item(int v, const char* n) : m_value(v), m_name(n) {}
|
||||||
|
|
||||||
|
const char* getName() const { return m_name; }
|
||||||
|
int getValue() const { return m_value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_value;
|
||||||
|
const char* m_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FlagValues { FLAGS_NONE = 0 };
|
||||||
|
using Flags = hkFlags<FlagValues, hkUint32>;
|
||||||
|
|
||||||
|
hkClassEnum(const char* name, const Item* items, int numItems);
|
||||||
|
|
||||||
|
constexpr hkClassEnum(const char* name, const Item* items, int numItems,
|
||||||
|
hkCustomAttributes* attributes, hkUint32 flags)
|
||||||
|
: m_name(name), m_items(items), m_numItems(numItems), m_attributes(attributes),
|
||||||
|
m_flags(flags) {}
|
||||||
|
|
||||||
|
const char* getName() const;
|
||||||
|
int getNumItems() const;
|
||||||
|
const hkClassEnum::Item& getItem(int i) const;
|
||||||
|
hkResult getNameOfValue(int val, const char** name) const;
|
||||||
|
hkResult getValueOfName(const char* name, int* val) const;
|
||||||
|
hkResult decomposeFlags(int flagValue, hkArray<const char*>& bitsOut, int& bitsOver) const;
|
||||||
|
hkUint32 getSignature() const;
|
||||||
|
void writeSignature(hkStreamWriter* w) const;
|
||||||
|
const hkVariant* getAttribute(const char* name) const;
|
||||||
|
inline const Flags& getFlags() const;
|
||||||
|
inline Flags& getFlags();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* m_name;
|
||||||
|
const class Item* m_items;
|
||||||
|
int m_numItems;
|
||||||
|
hkCustomAttributes* m_attributes;
|
||||||
|
Flags m_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline hkClassEnum::hkClassEnum(const char* name, const hkClassEnum::Item* items, int numItems)
|
||||||
|
: m_name(name), m_items(items), m_numItems(numItems), m_attributes(nullptr), m_flags(0) {}
|
||||||
|
|
||||||
|
inline const char* hkClassEnum::getName() const {
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int hkClassEnum::getNumItems() const {
|
||||||
|
return m_numItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const hkClassEnum::Item& hkClassEnum::getItem(int i) const {
|
||||||
|
return m_items[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const hkClassEnum::Flags& hkClassEnum::getFlags() const {
|
||||||
|
return m_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hkClassEnum::Flags& hkClassEnum::getFlags() {
|
||||||
|
return m_flags;
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Havok/Common/Base/hkBase.h>
|
||||||
|
|
||||||
|
class hkClassEnum;
|
||||||
|
class hkCustomAttributes;
|
||||||
|
|
||||||
|
class hkClassMember {
|
||||||
|
public:
|
||||||
|
HK_DECLARE_CLASS_ALLOCATOR(hkClassMember)
|
||||||
|
HK_DECLARE_REFLECTION()
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
TYPE_VOID = 0,
|
||||||
|
TYPE_BOOL,
|
||||||
|
TYPE_CHAR,
|
||||||
|
TYPE_INT8,
|
||||||
|
TYPE_UINT8,
|
||||||
|
TYPE_INT16,
|
||||||
|
TYPE_UINT16,
|
||||||
|
TYPE_INT32,
|
||||||
|
TYPE_UINT32,
|
||||||
|
TYPE_INT64,
|
||||||
|
TYPE_UINT64,
|
||||||
|
TYPE_REAL,
|
||||||
|
TYPE_VECTOR4,
|
||||||
|
TYPE_QUATERNION,
|
||||||
|
TYPE_MATRIX3,
|
||||||
|
TYPE_ROTATION,
|
||||||
|
TYPE_QSTRANSFORM,
|
||||||
|
TYPE_MATRIX4,
|
||||||
|
TYPE_TRANSFORM,
|
||||||
|
TYPE_ZERO,
|
||||||
|
TYPE_POINTER,
|
||||||
|
TYPE_FUNCTIONPOINTER,
|
||||||
|
/// hkArray<T>
|
||||||
|
TYPE_ARRAY,
|
||||||
|
/// hkInplaceArray<T,N> or hkInplaceArrayAligned16<T,N>
|
||||||
|
TYPE_INPLACEARRAY,
|
||||||
|
/// hkEnum<ENUM,STORAGE>
|
||||||
|
TYPE_ENUM,
|
||||||
|
TYPE_STRUCT,
|
||||||
|
TYPE_SIMPLEARRAY,
|
||||||
|
TYPE_HOMOGENEOUSARRAY,
|
||||||
|
TYPE_VARIANT,
|
||||||
|
TYPE_CSTRING,
|
||||||
|
TYPE_ULONG,
|
||||||
|
TYPE_FLAGS,
|
||||||
|
TYPE_HALF,
|
||||||
|
/// hkStringPtr
|
||||||
|
TYPE_STRINGPTR,
|
||||||
|
/// hkRelArray
|
||||||
|
TYPE_RELARRAY,
|
||||||
|
TYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FlagValues {
|
||||||
|
FLAGS_NONE = 0,
|
||||||
|
ALIGN_8 = 1 << 7,
|
||||||
|
ALIGN_16 = 1 << 8,
|
||||||
|
NOT_OWNED = 1 << 9,
|
||||||
|
SERIALIZE_IGNORED = 1 << 10,
|
||||||
|
ALIGN_32 = 1 << 11,
|
||||||
|
#ifdef HK_REAL_IS_DOUBLE
|
||||||
|
ALIGN_REAL = ALIGN_32,
|
||||||
|
#else
|
||||||
|
ALIGN_REAL = ALIGN_16,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
using Flags = hkFlags<FlagValues, hkUint16>;
|
||||||
|
|
||||||
|
enum DeprecatedFlagValues {
|
||||||
|
DEPRECATED_SIZE_8 = 8,
|
||||||
|
DEPRECATED_ENUM_8 = 8,
|
||||||
|
DEPRECATED_SIZE_16 = 16,
|
||||||
|
DEPRECATED_ENUM_16 = 16,
|
||||||
|
DEPRECATED_SIZE_32 = 32,
|
||||||
|
DEPRECATED_ENUM_32 = 32,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HK_CLASS_ZERO_DEFAULT = -2,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr hkClassMember(const char* name, const hkClass* class_, const hkClassEnum* enum_,
|
||||||
|
const hkEnum<Type, hkUint8>& type, const hkEnum<Type, hkUint8>& subtype,
|
||||||
|
hkInt16 cArraySize, hkUint16 flags, hkUint16 offset,
|
||||||
|
const hkCustomAttributes* attributes)
|
||||||
|
: m_name(name), m_class(class_), m_enum(enum_), m_type(type), m_subtype(subtype),
|
||||||
|
m_cArraySize(cArraySize), m_flags(flags), m_offset(offset), m_attributes(attributes) {}
|
||||||
|
|
||||||
|
inline const char* getName() const;
|
||||||
|
|
||||||
|
inline hkClassMember::Type getType() const;
|
||||||
|
inline void setType(hkClassMember::Type type);
|
||||||
|
|
||||||
|
inline hkClassMember::Type getSubType() const;
|
||||||
|
inline void setSubType(hkClassMember::Type subtype);
|
||||||
|
|
||||||
|
hkClassMember::Type getArrayType() const;
|
||||||
|
|
||||||
|
int getSizeInBytes() const;
|
||||||
|
int getAlignment() const;
|
||||||
|
hkBool isNotOwner() const;
|
||||||
|
int getTypeName(char* buf, int bufLen) const;
|
||||||
|
int getArrayMemberSize() const;
|
||||||
|
|
||||||
|
inline hkBool hasClass() const;
|
||||||
|
const hkClass& getStructClass() const;
|
||||||
|
const hkClass* getClass() const;
|
||||||
|
inline hkBool hasEnumClass() const;
|
||||||
|
const hkClassEnum& getEnumClass() const;
|
||||||
|
|
||||||
|
int getCstyleArraySize() const;
|
||||||
|
|
||||||
|
const hkClassEnum& getEnumType() const;
|
||||||
|
int getEnumValue(const void* memberAddress) const;
|
||||||
|
void setEnumValue(void* memberAddress, int value) const;
|
||||||
|
|
||||||
|
inline int getOffset() const;
|
||||||
|
inline void setOffset(int offset);
|
||||||
|
|
||||||
|
inline const Flags& getFlags() const;
|
||||||
|
inline Flags& getFlags();
|
||||||
|
|
||||||
|
const hkVariant* getAttribute(const char* id) const;
|
||||||
|
|
||||||
|
static hkClassMember::Type getTypeOf(const char* name);
|
||||||
|
static hkClassMember::Type getSubtypeOf(const char* name);
|
||||||
|
|
||||||
|
struct TypeProperties {
|
||||||
|
HK_DECLARE_CLASS_ALLOCATOR(hkClassMember::TypeProperties)
|
||||||
|
|
||||||
|
hkEnum<hkClassMember::Type, hkUint8> m_type;
|
||||||
|
const char* m_name;
|
||||||
|
short m_size;
|
||||||
|
short m_align;
|
||||||
|
};
|
||||||
|
static const TypeProperties& getClassMemberTypeProperties(Type type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* m_name;
|
||||||
|
const hkClass* m_class;
|
||||||
|
const hkClassEnum* m_enum;
|
||||||
|
hkEnum<Type, hkUint8> m_type;
|
||||||
|
hkEnum<Type, hkUint8> m_subtype;
|
||||||
|
hkInt16 m_cArraySize;
|
||||||
|
Flags m_flags;
|
||||||
|
hkUint16 m_offset;
|
||||||
|
const hkCustomAttributes* m_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const char* hkClassMember::getName() const {
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hkClassMember::Type hkClassMember::getType() const {
|
||||||
|
return static_cast<Type>(m_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hkClassMember::setType(hkClassMember::Type type) {
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hkClassMember::Type hkClassMember::getSubType() const {
|
||||||
|
return static_cast<Type>(m_subtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hkClassMember::setSubType(hkClassMember::Type subtype) {
|
||||||
|
m_subtype = subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int hkClassMember::getOffset() const {
|
||||||
|
return m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hkClassMember::setOffset(int offset) {
|
||||||
|
m_offset = static_cast<hkUint16>(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const hkClassMember::Flags& hkClassMember::getFlags() const {
|
||||||
|
return m_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hkClassMember::Flags& hkClassMember::getFlags() {
|
||||||
|
return m_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hkBool hkClassMember::hasClass() const {
|
||||||
|
return m_class != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hkBool hkClassMember::hasEnumClass() const {
|
||||||
|
return m_enum != nullptr;
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Havok/Common/Base/hkBase.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
class hkClass;
|
||||||
|
|
||||||
|
class hkTypeInfo {
|
||||||
|
public:
|
||||||
|
HK_DECLARE_CLASS_ALLOCATOR(hkTypeInfo)
|
||||||
|
|
||||||
|
using FinishLoadedObjectFunction = void (*)(void*, int);
|
||||||
|
using CleanupLoadedObjectFunction = void (*)(void*);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
HK_ALWAYS_INLINE static hkTypeInfo make(const char* name, const char* scopedName) {
|
||||||
|
FinishLoadedObjectFunction finish = nullptr;
|
||||||
|
constexpr bool needsFinish = std::is_constructible_v<T, hkFinishLoadedObjectFlag>;
|
||||||
|
if constexpr (needsFinish)
|
||||||
|
finish = finishFunctionImpl<T>;
|
||||||
|
|
||||||
|
CleanupLoadedObjectFunction cleanup = cleanupFunctionImpl<T>;
|
||||||
|
|
||||||
|
const void* vtable = nullptr;
|
||||||
|
if constexpr (std::is_polymorphic_v<T>) {
|
||||||
|
static_assert(needsFinish, "polymorphic types must have a finish constructor");
|
||||||
|
vtable = getVtableFunctionImpl<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hkTypeInfo{name, scopedName, finish, cleanup, vtable, sizeof(T)};
|
||||||
|
}
|
||||||
|
|
||||||
|
hkTypeInfo(const char* name, const char* scopedName, FinishLoadedObjectFunction finish,
|
||||||
|
CleanupLoadedObjectFunction cleanup, const void* vtable, hk_size_t size)
|
||||||
|
: m_typeName(name), m_scopedName(scopedName), m_finishLoadedObjectFunction(finish),
|
||||||
|
m_cleanupLoadedObjectFunction(cleanup), m_vtable(vtable), m_size(size) {}
|
||||||
|
|
||||||
|
const char* getTypeName() const { return m_typeName; }
|
||||||
|
const char* getScopedName() const { return m_scopedName; }
|
||||||
|
const void* getVtable() const { return m_vtable; }
|
||||||
|
void cleanupLoadedObject(void* ptr) const;
|
||||||
|
void finishLoadedObject(void* ptr, int finishFlag) const;
|
||||||
|
void finishLoadedObjectWithoutTracker(void* ptr, int finishFlag) const;
|
||||||
|
|
||||||
|
hkBool hasFinishFunction() const { return m_finishLoadedObjectFunction != nullptr; }
|
||||||
|
hkBool hasCleanupFunction() const { return m_cleanupLoadedObjectFunction != nullptr; }
|
||||||
|
hk_size_t getSize() const { return m_size; }
|
||||||
|
hkBool isVirtual() const { return m_vtable != nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
HK_VISIBILITY_HIDDEN static void finishFunctionImpl(void* p, int finishing) {
|
||||||
|
hkFinishLoadedObjectFlag flag{finishing};
|
||||||
|
new (p) T{flag};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
HK_VISIBILITY_HIDDEN static void cleanupFunctionImpl(void* p) {
|
||||||
|
static_cast<T*>(p)->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
HK_VISIBILITY_HIDDEN static const void* getVtableFunctionImpl() {
|
||||||
|
// The following trick only works because all Havok polymorphic types are supposed
|
||||||
|
// to have hkBaseObject as the most-base class -- forcing the vtable to be at offset 0.
|
||||||
|
//
|
||||||
|
// Unfortunately we can't check if hkBaseObject is at offset 0, but let's at least
|
||||||
|
// verify that hkBaseObject is a base class of T.
|
||||||
|
static_assert(std::is_base_of_v<hkBaseObject, T>,
|
||||||
|
"polymorphic types must have hkBaseObject as a base");
|
||||||
|
|
||||||
|
union {
|
||||||
|
alignas(16) void* dummy;
|
||||||
|
std::aligned_storage_t<sizeof(T), alignof(T)> obj;
|
||||||
|
};
|
||||||
|
hkFinishLoadedObjectFlag flag;
|
||||||
|
new (static_cast<void*>(std::addressof(obj))) T{flag};
|
||||||
|
|
||||||
|
const void* vtable_ptr;
|
||||||
|
std::memcpy(&vtable_ptr, &obj, sizeof(vtable_ptr));
|
||||||
|
return vtable_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* m_typeName;
|
||||||
|
const char* m_scopedName;
|
||||||
|
FinishLoadedObjectFunction m_finishLoadedObjectFunction;
|
||||||
|
CleanupLoadedObjectFunction m_cleanupLoadedObjectFunction;
|
||||||
|
const void* m_vtable;
|
||||||
|
hk_size_t m_size;
|
||||||
|
};
|
|
@ -3,3 +3,5 @@
|
||||||
#define HK_FORCE_INLINE inline
|
#define HK_FORCE_INLINE inline
|
||||||
#define HK_ALWAYS_INLINE HK_FORCE_INLINE
|
#define HK_ALWAYS_INLINE HK_FORCE_INLINE
|
||||||
#define HK_NEVER_INLINE __attribute__((noinline))
|
#define HK_NEVER_INLINE __attribute__((noinline))
|
||||||
|
|
||||||
|
#define HK_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
using hkFloat32 = float;
|
using hkFloat32 = float;
|
||||||
using hkDouble64 = double;
|
using hkDouble64 = double;
|
||||||
using hkReal = hkFloat32;
|
using hkReal = hkFloat32;
|
||||||
|
#define HK_REAL_IS_FLOAT
|
||||||
|
|
||||||
using hkChar = char;
|
using hkChar = char;
|
||||||
using hkInt8 = std::int8_t;
|
using hkInt8 = std::int8_t;
|
||||||
|
@ -75,17 +76,17 @@ class hkBool {
|
||||||
public:
|
public:
|
||||||
HK_ALWAYS_INLINE hkBool() = default;
|
HK_ALWAYS_INLINE hkBool() = default;
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
HK_FORCE_INLINE hkBool(bool b) : m_bool(static_cast<char>(b)) {}
|
HK_FORCE_INLINE constexpr hkBool(bool b) : m_bool(static_cast<char>(b)) {}
|
||||||
|
|
||||||
HK_FORCE_INLINE explicit operator bool() const { return m_bool != 0; }
|
HK_FORCE_INLINE constexpr explicit operator bool() const { return m_bool != 0; }
|
||||||
|
|
||||||
HK_FORCE_INLINE hkBool& operator=(bool e) {
|
HK_FORCE_INLINE constexpr hkBool& operator=(bool e) {
|
||||||
m_bool = static_cast<char>(e);
|
m_bool = static_cast<char>(e);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
HK_FORCE_INLINE hkBool operator==(bool e) const { return (m_bool != 0) == e; }
|
HK_FORCE_INLINE constexpr hkBool operator==(bool e) const { return (m_bool != 0) == e; }
|
||||||
HK_FORCE_INLINE hkBool operator!=(bool e) const { return (m_bool != 0) != e; }
|
HK_FORCE_INLINE constexpr hkBool operator!=(bool e) const { return (m_bool != 0) != e; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char m_bool;
|
char m_bool;
|
||||||
|
@ -100,18 +101,19 @@ template <typename Enum, typename Storage>
|
||||||
struct hkEnum {
|
struct hkEnum {
|
||||||
HK_ALWAYS_INLINE hkEnum() {}
|
HK_ALWAYS_INLINE hkEnum() {}
|
||||||
|
|
||||||
hkEnum(Enum value) { *this = value; } // NOLINT(google-explicit-constructor)
|
constexpr hkEnum(Enum value) // NOLINT(google-explicit-constructor)
|
||||||
|
: m_storage(static_cast<Storage>(value)) {}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
operator Enum() const { return static_cast<Enum>(m_storage); }
|
constexpr operator Enum() const { return static_cast<Enum>(m_storage); }
|
||||||
|
|
||||||
hkEnum& operator=(Enum value) {
|
constexpr hkEnum& operator=(Enum value) {
|
||||||
m_storage = static_cast<Storage>(value);
|
m_storage = static_cast<Storage>(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(Enum e) const { return m_storage == static_cast<Storage>(e); }
|
constexpr bool operator==(Enum e) const { return m_storage == static_cast<Storage>(e); }
|
||||||
bool operator!=(Enum e) const { return m_storage != static_cast<Storage>(e); }
|
constexpr bool operator!=(Enum e) const { return m_storage != static_cast<Storage>(e); }
|
||||||
|
|
||||||
Storage m_storage;
|
Storage m_storage;
|
||||||
};
|
};
|
||||||
|
@ -120,29 +122,31 @@ template <typename, typename Storage>
|
||||||
class hkFlags {
|
class hkFlags {
|
||||||
public:
|
public:
|
||||||
HK_FORCE_INLINE hkFlags() {}
|
HK_FORCE_INLINE hkFlags() {}
|
||||||
HK_FORCE_INLINE explicit hkFlags(Storage s) : m_storage(s) {}
|
HK_FORCE_INLINE constexpr explicit hkFlags(Storage s) : m_storage(s) {}
|
||||||
|
|
||||||
HK_FORCE_INLINE void clear() { m_storage = 0; }
|
HK_FORCE_INLINE constexpr void clear() { m_storage = 0; }
|
||||||
HK_FORCE_INLINE void clear(Storage mask) { m_storage &= ~mask; }
|
HK_FORCE_INLINE constexpr void clear(Storage mask) { m_storage &= ~mask; }
|
||||||
HK_FORCE_INLINE void setAll(Storage s) { m_storage = s; }
|
HK_FORCE_INLINE constexpr void setAll(Storage s) { m_storage = s; }
|
||||||
|
|
||||||
HK_FORCE_INLINE void operator|=(Storage s) { m_storage |= s; }
|
HK_FORCE_INLINE constexpr void operator|=(Storage s) { m_storage |= s; }
|
||||||
HK_FORCE_INLINE void operator^=(Storage s) { m_storage ^= s; }
|
HK_FORCE_INLINE constexpr void operator^=(Storage s) { m_storage ^= s; }
|
||||||
HK_FORCE_INLINE void operator&=(Storage s) { m_storage &= s; }
|
HK_FORCE_INLINE constexpr void operator&=(Storage s) { m_storage &= s; }
|
||||||
|
|
||||||
HK_FORCE_INLINE void setWithMask(Storage s, Storage mask) {
|
HK_FORCE_INLINE constexpr void setWithMask(Storage s, Storage mask) {
|
||||||
m_storage = (m_storage & ~mask) | (s & mask);
|
m_storage = (m_storage & ~mask) | (s & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
HK_FORCE_INLINE Storage get() const { return m_storage; }
|
HK_FORCE_INLINE constexpr Storage get() const { return m_storage; }
|
||||||
HK_FORCE_INLINE bool anyIsSet(Storage mask) const { return (m_storage & mask) != 0; }
|
HK_FORCE_INLINE constexpr bool anyIsSet(Storage mask) const { return (m_storage & mask) != 0; }
|
||||||
HK_FORCE_INLINE bool noneIsSet(Storage mask) const { return (m_storage & mask) == 0; }
|
HK_FORCE_INLINE constexpr bool noneIsSet(Storage mask) const { return (m_storage & mask) == 0; }
|
||||||
HK_FORCE_INLINE bool allAreSet(Storage mask) const { return (m_storage & mask) == mask; }
|
HK_FORCE_INLINE constexpr bool allAreSet(Storage mask) const {
|
||||||
|
return (m_storage & mask) == mask;
|
||||||
|
}
|
||||||
|
|
||||||
HK_FORCE_INLINE bool operator==(const hkFlags& other) const {
|
HK_FORCE_INLINE constexpr bool operator==(const hkFlags& other) const {
|
||||||
return other.m_storage == m_storage;
|
return other.m_storage == m_storage;
|
||||||
}
|
}
|
||||||
HK_FORCE_INLINE bool operator!=(const hkFlags& other) const {
|
HK_FORCE_INLINE constexpr bool operator!=(const hkFlags& other) const {
|
||||||
return other.m_storage != m_storage;
|
return other.m_storage != m_storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,3 +191,12 @@ public:
|
||||||
HK_FORCE_INLINE hkLong hkGetByteOffset(const void* base, const void* pntr) {
|
HK_FORCE_INLINE hkLong hkGetByteOffset(const void* base, const void* pntr) {
|
||||||
return hkLong(pntr) - hkLong(base);
|
return hkLong(pntr) - hkLong(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class hkClass;
|
||||||
|
|
||||||
|
struct hkVariant {
|
||||||
|
void* m_object;
|
||||||
|
const hkClass* m_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HK_DECLARE_REFLECTION() static const hkClass& staticClass();
|
||||||
|
|
Loading…
Reference in New Issue