support yyjson
This commit is contained in:
parent
51f009c05e
commit
0a5cb27b27
53
engine/modules/engine/core/include/archive/json.h
Normal file
53
engine/modules/engine/core/include/archive/json.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include "meta/result.h"
|
||||
#include "json/serialize.inl"
|
||||
#include "json/serde.inl"
|
||||
namespace api {
|
||||
using meta::result;
|
||||
enum class SerializeError : char
|
||||
{
|
||||
EMPTY,
|
||||
ERROR,
|
||||
};
|
||||
template<typename T>
|
||||
inline bool JsonDeserialize(string_view text, T* obj) {
|
||||
yyjson_alc alc = JsonAllocatorAdapter();
|
||||
yyjson_doc* doc = yyjson_read_opts((char*)text.data(), text.size(), YYJSON_READ_INSITU, &alc, nullptr);
|
||||
yyjson_val* root = yyjson_doc_get_root(doc);
|
||||
if constexpr (has_json_specialization_v<T>) {
|
||||
return JsonSerde<T>::Read(root, obj);
|
||||
}
|
||||
else {
|
||||
return JsonArchive::Deserialize(root, obj);
|
||||
}
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
inline result<T, SerializeError> JsonDeserialize(string_view text, Args&& ...args) {
|
||||
if (text.empty()) {
|
||||
return SerializeError::EMPTY;
|
||||
}
|
||||
T* obj = new(FramePool)T(std::forward<Args>(args)...);
|
||||
bool bsuccess = JsonDeserialize<T>(text, obj);
|
||||
using ResultType = result<T, SerializeError>;
|
||||
return bsuccess ? ResultType{ *obj } : ResultType{ SerializeError::ERROR };
|
||||
}
|
||||
template<has_json_specialization_v T>
|
||||
inline string_view JsonSerialize(const T& t) {
|
||||
yyjson_alc alc = JsonAllocatorAdapter();
|
||||
yyjson_mut_doc* doc = yyjson_mut_doc_new(&alc);
|
||||
yyjson_mut_val* root = JsonSerde<T>::Write(doc, Any{t});
|
||||
yyjson_mut_doc_set_root(doc, root);
|
||||
size_t len;
|
||||
const char* json_str = yyjson_mut_write_opts(doc, 0, &alc, &len, NULL);
|
||||
return json_str ? string_view(json_str, len) : string_view("");
|
||||
}
|
||||
inline string_view JsonSerialize(Any any) {
|
||||
yyjson_alc alc = JsonAllocatorAdapter();
|
||||
yyjson_mut_doc* doc = yyjson_mut_doc_new(&alc);
|
||||
yyjson_mut_val* root = JsonArchive::Serialize(doc, any);
|
||||
yyjson_mut_doc_set_root(doc, root);
|
||||
size_t len;
|
||||
const char* json_str = yyjson_mut_write_opts(doc, 0, &alc, &len, NULL);
|
||||
return json_str ? string_view(json_str, len) : string_view("");
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,58 @@
|
||||
#pragma once
|
||||
#include "serialize.h"
|
||||
#include "refl/pch.h"
|
||||
#include <format>
|
||||
#include <string_view>
|
||||
namespace api {
|
||||
struct JsonSerialize {
|
||||
|
||||
namespace archive {
|
||||
template<typename T>
|
||||
concept is_string_v = requires(T t) {
|
||||
{ static_cast<std::string>(t) } -> std::convertible_to<std::string>;
|
||||
};
|
||||
}
|
||||
using std::string_view;
|
||||
using refl::Any;
|
||||
using refl::UClass;
|
||||
using refl::type_name;
|
||||
using refl::TypeInfo;
|
||||
template<typename T>
|
||||
struct JsonSerde {
|
||||
inline static bool read(yyjson_val* val, T& v)
|
||||
{
|
||||
return r.read(v);
|
||||
inline static bool Read(yyjson_val* val, Any any) {
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
*any.CastTo<T*>() = (T)yyjson_get_bool(val);
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T>) {
|
||||
*any.CastTo<T*>() = (T)yyjson_get_uint(val);
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<T>) {
|
||||
*any.CastTo<T*>() = (T)yyjson_get_real(val);
|
||||
}
|
||||
else if constexpr (archive::is_string_v<T>) {
|
||||
*any.CastTo<T*>() = yyjson_get_str(val);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error(std::format("unknown json read type {}", type_name<T>().View()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
inline static yyjson_mut_val* Write(yyjson_mut_doc* doc, Any any) {
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
return yyjson_mut_bool(doc, *any.CastTo<T*>());
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T>) {
|
||||
return yyjson_mut_uint(doc, *any.CastTo<T*>());
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<T>) {
|
||||
return yyjson_mut_real(doc, *any.CastTo<T*>());
|
||||
}
|
||||
else if constexpr (archive::is_string_v<T>) {
|
||||
auto c = (any.CastTo<T*>())->data();
|
||||
return yyjson_mut_str(doc, "");
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error(std::format("unknown json write type {}", type_name<T>().View()));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
26
engine/modules/engine/core/include/archive/json/serde.inl
Normal file
26
engine/modules/engine/core/include/archive/json/serde.inl
Normal file
@ -0,0 +1,26 @@
|
||||
#include "serde.h"
|
||||
namespace api {
|
||||
namespace detail {
|
||||
// 辅助结构体,用于检查特化版本
|
||||
template<typename T, typename = void>
|
||||
struct has_json_specialization : std::false_type {};
|
||||
// 特化辅助结构体,匹配特化版本
|
||||
template <typename T>
|
||||
struct has_json_specialization<T, std::void_t<decltype(&JsonSerde<T>::Read) >> : std::true_type {};
|
||||
}
|
||||
template<typename T>
|
||||
concept has_json_specialization_v = detail::has_json_specialization<T>::value;
|
||||
|
||||
#ifdef API_DEBUG
|
||||
template<typename T>
|
||||
inline bool JsonRead(yyjson_val* node, const T& t) {
|
||||
return JsonSerde<T>::Read(node, t);
|
||||
}
|
||||
template<typename T>
|
||||
inline yyjson_mut_val* JsonWrite(yyjson_mut_doc* doc, const T& t) {
|
||||
return JsonSerde<T>::Write(doc, t);
|
||||
}
|
||||
#else
|
||||
#define JsonRead(node, t) JsonSerde<decltype(t)>::Read(node, t)
|
||||
#endif
|
||||
}
|
||||
@ -1,85 +1,24 @@
|
||||
#pragma once
|
||||
#include "zlog.h"
|
||||
#include "yyjson.h"
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include "serde.h"
|
||||
namespace api {
|
||||
using std::string_view;
|
||||
struct JsonReader {
|
||||
struct Level {
|
||||
enum EType : uint32_t {
|
||||
EObjectIndex = -1,
|
||||
EArrayIndex = 0,
|
||||
};
|
||||
yyjson_val* val = nullptr;
|
||||
uint32_t index = EObjectIndex;
|
||||
constexpr Level(yyjson_val* val, EType type = EObjectIndex) noexcept
|
||||
: val(val),index(type){}
|
||||
constexpr bool is_object()const {
|
||||
return index == EObjectIndex;
|
||||
}
|
||||
constexpr bool is_array()const {
|
||||
return index != EObjectIndex;
|
||||
}
|
||||
};
|
||||
yyjson_doc* doc;
|
||||
std::vector<Level> stack;
|
||||
~JsonReader() {
|
||||
if (doc) {
|
||||
yyjson_doc_free(doc);
|
||||
}
|
||||
}
|
||||
JsonReader(string_view json) {
|
||||
yyjson_read_err err = {};
|
||||
doc = yyjson_read_opts((char*)json.data(), json.size(), 0, nullptr, &err);
|
||||
if (doc == nullptr) {
|
||||
zlog::error("Failed to parse JSON: {}, error: {}", json.data(), err.msg);
|
||||
}
|
||||
}
|
||||
yyjson_val* find(string_view name) {
|
||||
auto back = stack.back();
|
||||
if (back.is_object()) {
|
||||
return yyjson_obj_get(back.val, name.data());
|
||||
}
|
||||
return yyjson_arr_get(back.val, back.index++);
|
||||
}
|
||||
bool start_object(string_view name = "") {
|
||||
yyjson_val* root = stack.empty() ? yyjson_doc_get_root(doc) : find(name);
|
||||
stack.emplace_back(root, Level::EObjectIndex);
|
||||
}
|
||||
void end_object() {
|
||||
stack.pop_back();
|
||||
}
|
||||
bool start_array(string_view name = "") {
|
||||
yyjson_val* root = stack.empty() ? yyjson_doc_get_root(doc) : find(name);
|
||||
stack.emplace_back(root, Level::EArrayIndex);
|
||||
}
|
||||
void end_array() {
|
||||
stack.pop_back();
|
||||
}
|
||||
struct JsonVTable {
|
||||
bool(*Read)(yyjson_val*, Any) = nullptr;
|
||||
yyjson_mut_val*(*Write)(yyjson_mut_doc*, Any) = nullptr;
|
||||
template<typename T>
|
||||
bool read(T& v, const string_view& name = "") {
|
||||
template<typename T>
|
||||
concept is_string_v = requires(T t) {
|
||||
{ static_cast<std::string>(t) } -> std::convertible_to<std::string>;
|
||||
static JsonVTable Make() {
|
||||
return { &JsonSerde<T>::Read, &JsonSerde<T>::Write };
|
||||
}
|
||||
};
|
||||
yyjson_val* parent = find(name);
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
v = (T)yyjson_get_bool(parent);
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T>) {
|
||||
v = (T)yyjson_get_uint(parent);
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<T>) {
|
||||
v = (T)yyjson_get_real(parent);
|
||||
}
|
||||
else if constexpr (is_string_v<T>){
|
||||
v = yyjson_get_str(parent);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
using JsonFuncTable = std::pmr::unordered_map<const UClass*, JsonVTable>;
|
||||
struct JsonArchive {
|
||||
private:
|
||||
static JsonFuncTable BuildFuncTable();
|
||||
inline static JsonFuncTable FuncTable = BuildFuncTable();
|
||||
public:
|
||||
template<typename T>
|
||||
static void Register();
|
||||
static yyjson_mut_val* Serialize(yyjson_mut_doc* doc, Any any);
|
||||
static bool Deserialize(yyjson_val* res, Any any);
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
#include "serialize.h"
|
||||
#include "serde.h"
|
||||
namespace api {
|
||||
// 定义 yyjson_alc 适配器类
|
||||
yyjson_alc JsonAllocatorAdapter(std::pmr::memory_resource* mr = &FramePool) {
|
||||
// 初始化 yyjson_alc 结构体
|
||||
yyjson_alc alc;
|
||||
alc.malloc = [](void* ctx, size_t size) -> void* {
|
||||
auto* adapter = static_cast<std::pmr::memory_resource*>(ctx);
|
||||
return adapter->allocate(size);
|
||||
};
|
||||
alc.realloc = [](void* ctx, void* ptr, size_t old_size, size_t size) -> void* {
|
||||
auto* adapter = static_cast<std::pmr::memory_resource*>(ctx);
|
||||
// std::pmr::memory_resource 不支持直接重新分配
|
||||
// 因此,先分配新的内存,再拷贝数据
|
||||
void* new_ptr = adapter->allocate(size);
|
||||
if (ptr) {
|
||||
std::memcpy(new_ptr, ptr, std::min(old_size, size));
|
||||
adapter->deallocate(ptr, old_size);
|
||||
}
|
||||
return new_ptr;
|
||||
};
|
||||
alc.free = [](void* ctx, void* ptr) {
|
||||
auto* adapter = static_cast<std::pmr::memory_resource*>(ctx);
|
||||
adapter->deallocate(ptr, 0);
|
||||
};
|
||||
alc.ctx = mr;
|
||||
return alc;
|
||||
}
|
||||
inline JsonFuncTable JsonArchive::BuildFuncTable()
|
||||
{
|
||||
JsonFuncTable funcTable{ &MemPool };
|
||||
#define RegisterAny(T) funcTable.emplace(&TypeInfo<T>::StaticClass,JsonVTable::Make<T>())
|
||||
#include "../register.inl"
|
||||
#undef RegisterAny
|
||||
return funcTable;
|
||||
}
|
||||
template<typename T>
|
||||
inline void JsonArchive::Register()
|
||||
{
|
||||
FuncTable.emplace(&TypeInfo<T>::StaticClass, JsonVTable::Make<T>());
|
||||
}
|
||||
inline yyjson_mut_val* JsonArchive::Serialize(yyjson_mut_doc* doc, Any any)
|
||||
{
|
||||
if (!any) {
|
||||
return {};
|
||||
}
|
||||
auto it = FuncTable.find(any.cls);
|
||||
if (it != FuncTable.end()) {
|
||||
return it->second.Write(doc, any);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
inline bool JsonArchive::Deserialize(yyjson_val* res, Any any)
|
||||
{
|
||||
if (!any) {
|
||||
return false;
|
||||
}
|
||||
auto it = FuncTable.find(any.cls);
|
||||
if (it != FuncTable.end()) {
|
||||
return it->second.Read(res, any);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
11
engine/modules/engine/core/include/archive/register.inl
Normal file
11
engine/modules/engine/core/include/archive/register.inl
Normal file
@ -0,0 +1,11 @@
|
||||
#ifdef RegisterAny
|
||||
RegisterAny(string_view);
|
||||
RegisterAny(int);
|
||||
RegisterAny(unsigned int);
|
||||
RegisterAny(short);
|
||||
RegisterAny(unsigned short);
|
||||
RegisterAny(char);
|
||||
RegisterAny(unsigned char);
|
||||
RegisterAny(float);
|
||||
RegisterAny(double);
|
||||
#endif // RegisterAny
|
||||
46
engine/modules/engine/zlib/include/meta/result.h
Normal file
46
engine/modules/engine/zlib/include/meta/result.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
namespace meta
|
||||
{
|
||||
// a struct stolen from rust
|
||||
// lets us define a result, or return an error otherwise
|
||||
template<typename Result, typename Error>
|
||||
class result
|
||||
: protected std::variant<Result, Error>
|
||||
{
|
||||
protected:
|
||||
using Base = std::variant<Result, Error>;
|
||||
private:
|
||||
static constexpr auto Success = 0;
|
||||
static constexpr auto Failure = 1;
|
||||
static_assert(std::is_default_constructible_v<Error>, "Error must be default constructible");
|
||||
public:
|
||||
using value_type = Result;
|
||||
using Base::Base;
|
||||
using Base::operator=;
|
||||
|
||||
// accessors
|
||||
Result& value();
|
||||
template<typename U, typename = std::enable_if_t<std::is_constructible_v<Result, U>>>
|
||||
Result value_or(U&& result) const;
|
||||
Error& error();
|
||||
const Result& value() const;
|
||||
const Error& error() const;
|
||||
|
||||
// monadic operators
|
||||
template<class Fn> auto map(Fn&& visitor) const;
|
||||
template<class Fn> auto and_then(Fn&& visitor) const;
|
||||
template<class Fn, class ErrFn> auto and_then(Fn&& visitor, ErrFn&& err_visitor) const;
|
||||
template<class ErrFunc> auto or_else(ErrFunc&& err_visitor) const;
|
||||
|
||||
// operator overloads
|
||||
explicit operator bool() const;
|
||||
Result& operator*();
|
||||
Result* operator->();
|
||||
const Result& operator*() const;
|
||||
const Result* operator->() const;
|
||||
};
|
||||
}
|
||||
#include "result.inl"
|
||||
54
engine/modules/engine/zlib/include/meta/result.inl
Normal file
54
engine/modules/engine/zlib/include/meta/result.inl
Normal file
@ -0,0 +1,54 @@
|
||||
namespace meta
|
||||
{
|
||||
template<typename Result, typename Error>
|
||||
inline Result& result<Result, Error>::value()
|
||||
{
|
||||
return std::get<Success>(*this);
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
template<typename U, typename>
|
||||
Result result<Result, Error>::value_or(U&& result) const
|
||||
{
|
||||
return bool(*this) ? **this : static_cast<Result>(std::forward<U>(result));
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
inline Error& result<Result, Error>::error()
|
||||
{
|
||||
return std::get<Failure>(*this);
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
inline const Result& result<Result, Error>::value() const
|
||||
{
|
||||
return std::get<Success>(*this);
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
inline const Error& result<Result, Error>::error() const
|
||||
{
|
||||
return std::get<Failure>(*this);
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
inline result<Result, Error>::operator bool() const
|
||||
{
|
||||
return Base::index() == Success;
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
inline Result& result<Result, Error>::operator*()
|
||||
{
|
||||
return value();
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
inline Result* result<Result, Error>::operator->()
|
||||
{
|
||||
return &operator*();
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
const Result& result<Result, Error>::operator*() const
|
||||
{
|
||||
return value();
|
||||
}
|
||||
template<typename Result, typename Error>
|
||||
const Result* result<Result, Error>::operator->() const
|
||||
{
|
||||
return &operator*();
|
||||
}
|
||||
}
|
||||
@ -45,3 +45,5 @@ inline void* operator new(size_t size, pmr::FrameAllocatorPool& pool, size_t ali
|
||||
return pool.allocate(size, alignment);
|
||||
}
|
||||
#include "frame_allocator.inl"
|
||||
inline static pmr::FrameAllocatorPool MemPool{};
|
||||
inline static pmr::FrameAllocatorPool FramePool{};
|
||||
@ -31,9 +31,9 @@ namespace pmr
|
||||
};
|
||||
struct Name {
|
||||
size_t hash;
|
||||
#ifdef Z_DEBUG
|
||||
#ifdef API_DEBUG
|
||||
std::string_view value;
|
||||
#endif // Z_DEBUG
|
||||
#endif // API_DEBUG
|
||||
public:
|
||||
Name():hash(NameID::InvalidValue()) {};
|
||||
Name(const char* str)noexcept;
|
||||
|
||||
@ -40,7 +40,7 @@ namespace pmr {
|
||||
{
|
||||
return NameTable::Find(hash);
|
||||
}
|
||||
#ifdef Z_DEBUG
|
||||
#ifdef API_DEBUG
|
||||
#define MAKE_NAME_PAIR(hash, str) value = NameTable::MakePair(hash, str)
|
||||
#define NAME_TO_STRING value
|
||||
#else
|
||||
|
||||
@ -2,27 +2,20 @@
|
||||
#include "type.h"
|
||||
namespace refl {
|
||||
class UClass;
|
||||
struct Any;
|
||||
template<typename T>
|
||||
concept is_not_any_v = !std::is_same_v<args_type_t<T>, Any>;
|
||||
struct Any {
|
||||
public:
|
||||
const void* ptr;
|
||||
const UClass* cls;
|
||||
public:
|
||||
constexpr Any() : ptr(nullptr), cls(nullptr) {}
|
||||
constexpr Any(const void* ptr, const UClass* cls) : ptr(ptr), cls(cls) {}
|
||||
template<typename T>
|
||||
constexpr Any(T&& v) : ptr(&v), cls(TypeInfo<args_type_t<T>>::StaticClass) {
|
||||
if constexpr (std::is_same_v<args_type_t<T>, Any>) {
|
||||
ptr = v.ptr;
|
||||
cls = v.cls;
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
constexpr Any(T* v) : ptr(v), cls(&TypeInfo<args_type_t<T>>::StaticClass) {
|
||||
if constexpr (std::is_same_v<args_type_t<T>, Any>) {
|
||||
ptr = v->ptr;
|
||||
cls = v->cls;
|
||||
}
|
||||
}
|
||||
constexpr Any() noexcept: ptr(nullptr), cls(nullptr) {}
|
||||
constexpr Any(const void* ptr, const UClass* cls) noexcept : ptr(ptr), cls(cls) {}
|
||||
template<is_not_any_v T>
|
||||
constexpr Any(T&& v) noexcept : ptr(&v), cls(&TypeInfo<args_type_t<T>>::StaticClass) {}
|
||||
template<is_not_any_v T>
|
||||
constexpr Any(T* v) noexcept : ptr(v), cls(&TypeInfo<args_type_t<T>>::StaticClass) {}
|
||||
template<typename T>//参数 T* => T*
|
||||
constexpr inline T CastTo() const {
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
@ -37,6 +30,7 @@ namespace refl {
|
||||
}
|
||||
}
|
||||
public:
|
||||
operator bool()const { return cls && ptr; }
|
||||
bool Check(const UClass* parent) const;
|
||||
};
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
namespace refl {
|
||||
template<size_t N>
|
||||
struct TStr {
|
||||
|
||||
@ -79,13 +79,17 @@ namespace refl {
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto type_name() noexcept {
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
if constexpr (std::is_same_v<T, void>) {
|
||||
return TStr{ "void" };
|
||||
}
|
||||
else if constexpr (std::is_arithmetic_v<T>) {
|
||||
constexpr auto prefix = detail::num_prefix_name<T>();
|
||||
constexpr auto bit = detail::num_name<8 * sizeof(T)>();
|
||||
return detail::concat(prefix, bit);
|
||||
}
|
||||
else {
|
||||
static_assert("not support");
|
||||
//static_assert("not support");
|
||||
return TStr{ "unknown" };
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,6 +44,8 @@ namespace refl {
|
||||
uint32_t flag{0};
|
||||
const UClass* parent;
|
||||
vtable_uclass* vtable{nullptr};
|
||||
UClass(const UClass*) = delete;
|
||||
UClass& operator=(const UClass*) = delete;
|
||||
public:
|
||||
UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
|
||||
:name(name), size(size), parent(parent) {}
|
||||
@ -59,7 +61,7 @@ namespace refl {
|
||||
}
|
||||
template<typename T>
|
||||
bool IsChildOf(bool bthis = false) const {
|
||||
return IsChildOf(TypeInfo<T>::StaticClass, bthis);
|
||||
return IsChildOf(&TypeInfo<T>::StaticClass, bthis);
|
||||
}
|
||||
public:
|
||||
template<typename T>
|
||||
|
||||
@ -1,44 +1,41 @@
|
||||
#include "uclass.h"
|
||||
#include "name.h"
|
||||
namespace refl{
|
||||
namespace detail {
|
||||
inline static pmr::FrameAllocatorPool MemPool{};
|
||||
}
|
||||
template <class T>
|
||||
concept is_metas_v = false;//requires(const Name & name) { MetaImpl<T>::MyMetas::GetMeta(name); };
|
||||
template<typename T>
|
||||
class UClass_Auto : public UClass {
|
||||
using UClass::UClass;
|
||||
using MyUClass = UClass_Auto<T>;
|
||||
public:
|
||||
static MyUClass* BuildClass() {
|
||||
MyUClass* cls = new(detail::MemPool)MyUClass(type_name<T>().View(), sizeof(T));
|
||||
UClass_Auto() : UClass(type_name<T>().View(), sizeof(T)) {
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
using RT = std::remove_pointer_t<T>;
|
||||
cls->flag |= CLASS_POINTER_FLAG;
|
||||
flag |= CLASS_POINTER_FLAG;
|
||||
if constexpr (!std::is_same_v<RT, void>) {
|
||||
cls->parent = TypeInfo<RT>::StaticClass;
|
||||
parent = &TypeInfo<RT>::StaticClass;
|
||||
}
|
||||
}
|
||||
else if constexpr (is_array_v<T>) {
|
||||
using RT = is_array_t<T>;
|
||||
cls->flag = CLASS_ARRAY_FLAG;
|
||||
flag = CLASS_ARRAY_FLAG;
|
||||
if constexpr (std::is_pointer_v<RT>) {
|
||||
cls->flag |= CLASS_POINTER_FLAG;
|
||||
flag |= CLASS_POINTER_FLAG;
|
||||
}
|
||||
cls->parent = TypeInfo<RT>::StaticClass;
|
||||
parent = &TypeInfo<RT>::StaticClass;
|
||||
}
|
||||
else {
|
||||
cls->vtable = new(detail::MemPool)vtable_uclass();
|
||||
cls->vtable->Construct = &UClass::Construct<T>;
|
||||
cls->vtable->Destruct = &UClass::Destruct<T>;
|
||||
vtable = new(MemPool)vtable_uclass();
|
||||
vtable->Construct = &UClass::Construct<T>;
|
||||
vtable->Destruct = &UClass::Destruct<T>;
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct TypeInfoImpl<void> {
|
||||
inline static UClass StaticClass{ type_name<void>().View(), 0 };
|
||||
};
|
||||
template<typename T>
|
||||
struct TypeInfoImpl {
|
||||
using MyUClass = UClass_Auto<T>;
|
||||
inline static MyUClass* StaticClass = MyUClass::BuildClass();
|
||||
inline static MyUClass StaticClass{};
|
||||
};
|
||||
}
|
||||
@ -2,6 +2,6 @@ header_component("zlib","engine")
|
||||
set_basename("myzlib")
|
||||
add_headerfiles("include/**.h", "include/**.inl")
|
||||
if is_mode("debug") then
|
||||
add_defines("Z_DEBUG", {public = true})
|
||||
add_defines("API_DEBUG", {public = true})
|
||||
end
|
||||
set_pcheader("include/refl/pch.h")
|
||||
@ -6,7 +6,7 @@
|
||||
#include <stack>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include "yyjson.h"
|
||||
#include "archive/json.h"
|
||||
namespace pmr {
|
||||
using std::pmr::monotonic_buffer_resource;
|
||||
using std::pmr::vector;
|
||||
@ -134,13 +134,38 @@ void genLua(const char* file_path, const pmr::vector<MacroData>& mdList) {
|
||||
oss << '}';
|
||||
writeFile(file_path, oss.str());
|
||||
}
|
||||
namespace api {
|
||||
struct Guid {
|
||||
int a;
|
||||
float b;
|
||||
};
|
||||
template<>
|
||||
struct JsonSerde<Guid> {
|
||||
inline static bool Read(yyjson_val* node, Any any) {
|
||||
Guid& v = *any.CastTo<Guid*>();
|
||||
JsonRead(yyjson_obj_get(node, "a"), v.a);
|
||||
JsonRead(yyjson_obj_get(node, "b"), v.b);
|
||||
return true;
|
||||
}
|
||||
inline static yyjson_mut_val* Write(yyjson_mut_doc* doc, Any any) {
|
||||
Guid& v = *any.CastTo<Guid*>();
|
||||
auto obj = yyjson_mut_obj(doc);
|
||||
yyjson_mut_obj_add_val(doc, obj, "a", JsonWrite(doc, v.a));
|
||||
yyjson_mut_obj_add_val(doc, obj, "b", JsonWrite(doc, v.b));
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
}
|
||||
void genPlugin(const char* file_path, const pmr::vector<MacroData>& mdList) {
|
||||
yyjson_read_err err = {};
|
||||
std::pmr::string json{"{a=1}"};
|
||||
yyjson_doc* _document = yyjson_read_opts(
|
||||
(char*)json.data(), json.size(),
|
||||
0, nullptr, &err);
|
||||
auto obj = yyjson_doc_get_root((yyjson_doc*)_document);
|
||||
api::Guid guid;
|
||||
guid.a = 1243;
|
||||
std::string_view data = api::JsonSerialize(guid);
|
||||
auto res = api::JsonDeserialize<api::Guid>(data);
|
||||
if (res) {
|
||||
api::Guid g2 = res.value();
|
||||
int a = g2.a;
|
||||
int b = g2.b;
|
||||
}
|
||||
}
|
||||
int main() {
|
||||
const char* file_path = R"(F:\engine\zengine\engine\modules\render\vulkan\include\vulkan\module.h)";
|
||||
|
||||
@ -17,7 +17,7 @@ int main() {
|
||||
constexpr TStr str3 = detail::concat(str1, str2);
|
||||
constexpr auto r1 = value_name<8 * sizeof(int)>();
|
||||
constexpr int v = 12;
|
||||
auto cls = refl::TypeInfo<int>::StaticClass;
|
||||
auto cls = &refl::TypeInfo<int>::StaticClass;
|
||||
//auto str4 = concat(r1, str2);
|
||||
auto t1 = refl::type_name<int>();
|
||||
auto v1 = refl::type_name<int>().View();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user