Skip to content

Commit

Permalink
reflector declare buch of new stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
PredatorCZ committed Dec 22, 2023
1 parent 1d1f689 commit abcdd52
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 65 deletions.
56 changes: 51 additions & 5 deletions include/spike/reflect/detail/reflector.inl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ inline std::string Reflector::GetReflectedValue(JenHash hash) const {
if (!found)
return "";

return GetReflectedValue(found->index);
return GetReflectedValue(*found);
}

inline std::string Reflector::GetReflectedValue(JenHash hash,
Expand All @@ -173,7 +173,7 @@ inline std::string Reflector::GetReflectedValue(JenHash hash,
if (!found)
return "";

return GetReflectedValue(found->index, subID);
return GetReflectedValue(*found, subID);
}

inline std::string Reflector::GetReflectedValue(JenHash hash, size_t subID,
Expand All @@ -183,7 +183,7 @@ inline std::string Reflector::GetReflectedValue(JenHash hash, size_t subID,
if (!found)
return "";

return GetReflectedValue(found->index, subID, element);
return GetReflectedValue(*found, subID, element);
}

inline ReflectedInstance Reflector::GetReflectedSubClass(JenHash hash,
Expand All @@ -193,7 +193,7 @@ inline ReflectedInstance Reflector::GetReflectedSubClass(JenHash hash,
if (!found)
return {};

return GetReflectedSubClass(found->index, subID);
return GetReflectedSubClass(*found, subID);
}

inline ReflectedInstance Reflector::GetReflectedSubClass(JenHash hash,
Expand Down Expand Up @@ -269,7 +269,7 @@ inline bool Reflector::IsArray(JenHash hash) const {
if (!found)
return false;

return IsArray(found->index);
return found->type == REFType::Array || found->type == REFType::ArrayClass;
}

inline bool Reflector::IsArray(size_t id) const {
Expand All @@ -280,3 +280,49 @@ inline bool Reflector::IsArray(size_t id) const {

return fl.type == REFType::Array || fl.type == REFType::ArrayClass;
}

inline std::string Reflector::GetReflectedValue(size_t id) const {
if (id >= GetNumReflectedValues())
return "";

auto inst = GetReflectedInstance();
const ReflType &reflValue = inst.rfStatic->types[id];
return GetReflectedValue(reflValue);
}

inline std::string Reflector::GetReflectedValue(size_t id, size_t subID) const {
if (id >= GetNumReflectedValues())
return "";

auto inst = GetReflectedInstance();
const ReflType &reflValue = inst.rfStatic->types[id];
return GetReflectedValue(reflValue, subID);
}

inline std::string Reflector::GetReflectedValue(size_t id, size_t subID,
size_t element) const {
if (id >= GetNumReflectedValues() || !IsArray(id))
return "";

auto inst = GetReflectedInstance();
const ReflType &reflValue = inst.rfStatic->types[id];
return GetReflectedValue(reflValue, subID, element);
}

inline ReflectedInstance Reflector::GetReflectedSubClass(size_t id,
size_t subID) const {
if (id >= GetNumReflectedValues())
return {};

auto inst = GetReflectedInstance();
const ReflType &reflValue = inst.rfStatic->types[id];
return GetReflectedSubClass(reflValue, subID);
}

inline ReflectedInstance Reflector::GetReflectedSubClass(ReflType type, size_t subID) {
return const_cast<const Reflector *>(this)->GetReflectedSubClass(type, subID);
}

inline ReflectedInstance Reflector::GetReflectedSubClass(size_t id, size_t subID) {
return const_cast<const Reflector *>(this)->GetReflectedSubClass(id, subID);
}
82 changes: 75 additions & 7 deletions include/spike/reflect/detail/reflector_class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ struct ReflDesc {

struct NoName {};

struct VectorMethods {
using ResizeWrap = void (*)(void *, size_t);
using AtWrap = void *(*)(void *, size_t);
ResizeWrap resize;
AtWrap at;
};

template <class C> consteval VectorMethods MakeVectorClass() {
using Vector = std::vector<C>;
VectorMethods retval{
.resize = [](void *ptr_,
size_t n) { static_cast<Vector *>(ptr_)->resize(n); },
.at = [](void *ptr_, size_t n) -> void * {
auto &ref = static_cast<Vector *>(ptr_)->at(n);
return &ref;
},
};

return retval;
}

struct MemberProxy {
const char *typeName;
const char *aliasName = nullptr;
Expand Down Expand Up @@ -72,6 +93,24 @@ struct MemberProxy {
}
};

struct ClassMethods {
using ConstructorWrap = void (*)(void *);
using DestructorWrap = void (*)(void *);

ConstructorWrap constructor = nullptr;
DestructorWrap destructor;
};

template <class C> consteval ClassMethods MakeClassMethods() {
ClassMethods retval{
.destructor = [](void *ptr_) { static_cast<C *>(ptr_)->~C(); },
};
if constexpr (std::is_default_constructible_v<C>) {
retval.constructor = [](void *ptr_) { ::new (ptr_) C(); };
}
return retval;
};

struct reflectorStatic {
using RegistryType = std::map<JenHash, const reflectorStatic *>;
const JenHash classHash;
Expand All @@ -82,11 +121,26 @@ struct reflectorStatic {
const char *const *typeAliases = nullptr;
const JenHash *typeAliasHashes = nullptr;
const ReflDesc *typeDescs;
const ClassMethods methods;
const uint32 classSize;
const JenHash baseClass;

template <class ClassType, class... C, size_t cs>
reflectorStatic(const ClassType *, const char (&className_)[cs], C... members)
template <class ClassType, class BaseType, class... C, size_t cs>
reflectorStatic(JenHash baseClassHash, const BaseType *, const ClassType *,
const char (&className_)[cs], C... members)
: classHash(JenHash(className_)), nTypes(sizeof...(C)),
className(className_) {
className(className_), methods(MakeClassMethods<ClassType>()),
classSize(sizeof(ClassType)), baseClass(baseClassHash) {

static_assert(std::is_same_v<BaseType, void> ||
std::is_base_of_v<BaseType, ClassType>,
"Provided base class is not actual base");
static_assert(!std::is_same_v<ClassType, BaseType>,
"Base class cannot be same as class");
static_assert(std::is_void_v<BaseType> ||
_getType<BaseType>::TYPE == REFType::Class,
"Base class must be class type and have ReflectorTag();");

if constexpr (sizeof...(C) > 0) {
size_t index = 0;
struct reflType2 : ReflType {
Expand Down Expand Up @@ -129,7 +183,7 @@ struct reflectorStatic {
static RegistryType PC_EXTERN &Registry();
};

static_assert(sizeof(reflectorStatic) == 56);
static_assert(sizeof(reflectorStatic) == 80);

struct ReflectedInstance {
private:
Expand Down Expand Up @@ -180,17 +234,21 @@ template <class C> class InvokeGuard;

#define BITMEMBER(member, ...) BITMEMBERNAME(member, #member, __VA_ARGS__)

#define CLASS(...) \
#define CLASS(...) BASEDCLASS(void, __VA_ARGS__)

#define BASEDCLASS(base, ...) \
template <> constexpr JenHash ClassHash<__VA_ARGS__>() { \
return #__VA_ARGS__; \
} \
template <> \
const reflectorStatic REF_EXPORT_ *GetReflectedClass<__VA_ARGS__>() { \
using class_type = __VA_ARGS__; \
static const reflectorStatic reflectedClass { \
std::add_pointer_t<class_type>{nullptr}, #__VA_ARGS__,
JenHash(#base), std::add_pointer_t<base>{nullptr}, \
std::add_pointer_t<class_type>{nullptr}, #__VA_ARGS__,

// internal, do not use
#define END_BASEDCLASS(base, ...) END_CLASS(__VA_ARGS__)
#define END_CLASS(...) \
} \
; \
Expand Down Expand Up @@ -227,7 +285,17 @@ template <class C> class InvokeGuard;
};

// Create reflection definition (use only in TU)
// what: CLASS() or ENUMERATION()
// what: CLASS(), ENUMERATION() or BASEDCLASS()
// args: MEMBER, MEMBERNAME or BITMEMBER, BITMEMBERNAME, invokes MemberProxy
// contructor
#define REFLECT(what, ...) what __VA_ARGS__ END_##what

// Create forward class reflection definition (use only in TU)
#define FWDREFLECTCLASS(...) \
template <> constexpr JenHash ClassHash<__VA_ARGS__>() { \
return #__VA_ARGS__; \
}

// Create forward enum reflection definition (use only in TU)
#define FWDREFLECTENUMERATION(...) \
template <> constexpr JenHash EnumHash<__VA_ARGS__>() { return #__VA_ARGS__; }
42 changes: 40 additions & 2 deletions include/spike/reflect/detail/reflector_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "../reflector_fwd.hpp"
#include "spike/crypto/jenkinshash.hpp"
#include "spike/util/supercore.hpp"
#include <vector>

struct ReflType;

Expand Down Expand Up @@ -82,6 +83,7 @@ struct ReflType {
};
JenHash valueNameHash;
uint16 size;
REFContainer container;

union {
uint32 raw[3]{};
Expand Down Expand Up @@ -158,7 +160,7 @@ template <typename _Ty> struct _getType : reflTypeDefault_ {
return ClassHash<_Ty>();
}
}
static constexpr uint8 SIZE = sizeof(_Ty);
static constexpr uint8 SIZE = uint8(sizeof(_Ty));
};
template <> struct _getType<bool> : reflTypeDefault_ {
static constexpr REFType TYPE = REFType::Bool;
Expand Down Expand Up @@ -193,10 +195,35 @@ template <class C, size_t _Size> struct _getType<C[_Size]> : reflTypeDefault_ {
using child_type = C;
};

template <class C> struct _getType<std::vector<C>> : _getType<C> {};

template <typename Container> struct is_container : std::false_type {};
template <typename... Ts>
struct is_container<std::vector<Ts...>> : std::true_type {};

template <class T>
using refl_is_vectormap = decltype(std::declval<T>().ReflectorMap());
template <class C>
constexpr bool refl_is_vectormap_v = es::is_detected_v<refl_is_vectormap, C>;

template <class C> consteval REFContainer REFContainerType() {
if constexpr (std::is_pointer_v<C>) {
return REFContainer::Pointer;
} else if constexpr (is_container<C>::value) {
if constexpr (std::is_same_v<C, std::vector<typename C::value_type>>) {
return refl_is_vectormap_v<typename C::value_type>
? REFContainer::ContainerVectorMap
: REFContainer::ContainerVector;
}
}

return REFContainer::None;
};

template <class type_>
ReflType BuildReflType(JenHash typeHash, uint8 index, size_t offset) {
using unref_type = std::remove_reference_t<type_>;
using type_class = _getType<unref_type>;
using type_class = _getType<std::remove_pointer_t<unref_type>>;
static_assert(type_class::TYPE != REFType::None,
"Undefined type to reflect. Did you forget void "
"ReflectorTag(); tag method for subclass member?");
Expand All @@ -208,6 +235,7 @@ ReflType BuildReflType(JenHash typeHash, uint8 index, size_t offset) {
mainType.valueNameHash = typeHash;
mainType.offset = static_cast<decltype(ReflType::offset)>(offset);
mainType.size = type_class::SIZE;
mainType.container = REFContainerType<unref_type>();

auto ParsePrimitive = [](auto &value) {
constexpr auto type = type_class::TYPE;
Expand All @@ -221,6 +249,16 @@ ReflType BuildReflType(JenHash typeHash, uint8 index, size_t offset) {
}
} else if constexpr (es::is_detected_v<refl_has_hash, type_class>) {
constexpr auto vHash = type_class::Hash();
if constexpr (type == REFType::Array || type == REFType::ArrayClass) {
if constexpr (type_class::SUBTYPE == REFType::Class) {
static_assert(vHash.raw() > 0, "Subclass for member must be "
"reflected before class that uses it");
}
} else if constexpr (type == REFType::Class) {
static_assert(
vHash.raw() > 0,
"Subclass for member must be reflected before class that uses it");
}

if constexpr (vHash.raw() > 0) {
value.asClass.typeHash = vHash.raw();
Expand Down
17 changes: 12 additions & 5 deletions include/spike/reflect/reflector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,20 @@ class Reflector {
ErrorType SetReflectedValueFloat(JenHash hashName, double value, size_t subID = 0);
ErrorType SetReflectedValueFloat(size_t id, double value, size_t subID = 0);

std::string PC_EXTERN GetReflectedValue(size_t id) const;
std::string GetReflectedValue(size_t id) const;
std::string GetReflectedValue(JenHash hashName) const;

std::string PC_EXTERN GetReflectedValue(size_t id, size_t subID) const;
std::string GetReflectedValue(size_t id, size_t subID) const;
std::string GetReflectedValue(JenHash hashName, size_t subID) const;

std::string PC_EXTERN GetReflectedValue(size_t id, size_t subID, size_t element) const;
std::string GetReflectedValue(size_t id, size_t subID, size_t element) const;
std::string GetReflectedValue(JenHash hashName, size_t subID, size_t element) const;

ReflectedInstance GetReflectedSubClass(JenHash hashName, size_t subID = 0) const;
ReflectedInstance PC_EXTERN GetReflectedSubClass(size_t id, size_t subID = 0) const;
ReflectedInstance GetReflectedSubClass(size_t id, size_t subID = 0) const;

ReflectedInstance GetReflectedSubClass(JenHash hashName, size_t subID = 0);
ReflectedInstance PC_EXTERN GetReflectedSubClass(size_t id, size_t subID = 0);
ReflectedInstance GetReflectedSubClass(size_t id, size_t subID = 0);

KVPair GetReflectedPair(size_t id, const KVPairFormat &settings = {}) const;
KVPair GetReflectedPair(JenHash hashName, const KVPairFormat &settings = {}) const;
Expand All @@ -106,6 +106,13 @@ class Reflector {
ErrorType PC_EXTERN SetReflectedValueUInt(ReflType type, uint64 value, size_t subID = 0);
ErrorType PC_EXTERN SetReflectedValueInt(ReflType type, int64 value, size_t subID = 0);
ErrorType PC_EXTERN SetReflectedValueFloat(ReflType type, double value, size_t subID = 0);

std::string PC_EXTERN GetReflectedValue(ReflType type) const;
std::string PC_EXTERN GetReflectedValue(ReflType type, size_t subID) const;
std::string PC_EXTERN GetReflectedValue(ReflType type, size_t subID, size_t element) const;

ReflectedInstance PC_EXTERN GetReflectedSubClass(ReflType type, size_t subID = 0) const;
ReflectedInstance PC_EXTERN GetReflectedSubClass(ReflType type, size_t subID = 0);
// clang-format on
private:
virtual ReflectedInstance GetReflectedInstance() const = 0;
Expand Down
7 changes: 7 additions & 0 deletions include/spike/reflect/reflector_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ enum class REFType : uint8 {
BitFieldClass,
};

enum class REFContainer : uint8 {
None,
Pointer,
ContainerVector,
ContainerVectorMap,
};

struct reflTypeDefault_ {
static constexpr JenHash Hash() { return {}; }
static constexpr JenHash SubHash() { return {}; }
Expand Down
Loading

0 comments on commit abcdd52

Please sign in to comment.