name 字符串优化
This commit is contained in:
parent
a6458a82c0
commit
f51befaff0
@ -1,4 +1,6 @@
|
||||
{
|
||||
"metadatas": [],
|
||||
"includes": []
|
||||
}
|
||||
metadatas:
|
||||
- guid: 7dfa8412-3278-43f6-b332-ac09a132025f
|
||||
name: ""
|
||||
t_hash: "api::ShaderProgram\x06 mOwner!<21>/engine/assets/shader/simple.frag"
|
||||
meta: ~
|
||||
includes: ~
|
||||
@ -0,0 +1,6 @@
|
||||
metadatas:
|
||||
- guid: 47c28b8c-f2aa-4357-a12d-7212de6e3a9e
|
||||
name: ""
|
||||
t_hash: "api::ShaderProgram\x06 mOwner!<21>/engine/assets/shader/simple.frag"
|
||||
meta: ~
|
||||
includes: ~
|
||||
@ -24,7 +24,7 @@ namespace api {
|
||||
for (auto& elem : bundle.GetAll())
|
||||
std::visit([&](auto& handle) {
|
||||
using T = std::decay_t<decltype(*handle)>;
|
||||
SerializedMeta meta{ handle.guid, handle->Name(), meta_name<T>().view() };
|
||||
SerializedMeta meta{ handle.guid, handle->Name(), meta_name<T>() };
|
||||
if constexpr (is_meta_v<T>) {
|
||||
meta.meta = handle->Meta();
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ namespace api
|
||||
template<typename T>
|
||||
const SerializedMeta* FetchMeta() const;
|
||||
template<typename T>
|
||||
const SerializedMeta* FetchMeta(string_view asset_name) const;
|
||||
const SerializedMeta* FetchMeta(Name asset_name) const;
|
||||
void Add(const SerializedMeta& meta) {
|
||||
metadatas.push_back(meta);
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ namespace api
|
||||
template<typename T>
|
||||
inline const SerializedMeta* MetaBundle::FetchMeta() const
|
||||
{
|
||||
string_view name = meta_name<typename T::BaseResource>().view();
|
||||
Name name = meta_name<typename T::BaseResource>();
|
||||
for (auto& elem : metadatas)
|
||||
{
|
||||
if (elem.t_hash == name)
|
||||
@ -13,9 +13,9 @@ namespace api
|
||||
return nullptr;
|
||||
}
|
||||
template<typename T>
|
||||
inline const SerializedMeta* MetaBundle::FetchMeta(string_view asset_name) const
|
||||
inline const SerializedMeta* MetaBundle::FetchMeta(Name asset_name) const
|
||||
{
|
||||
string_view name = meta_name<typename T::BaseResource>().view();
|
||||
Name name = meta_name<typename T::BaseResource>();
|
||||
for (auto& elem : metadatas)
|
||||
{
|
||||
if (elem.t_hash == name && asset_name == elem.name)
|
||||
|
||||
@ -45,19 +45,20 @@ namespace api {
|
||||
{
|
||||
DestroyGraph();
|
||||
}
|
||||
void ModuleManagerImpl::CreateModule(Name name, bool shared)
|
||||
void ModuleManagerImpl::CreateModule(Name name, bool is_shared)
|
||||
{
|
||||
bool hotfix = true;
|
||||
IModule* module = shared ?
|
||||
IModule* module = is_shared ?
|
||||
spawnDynamicModule(name, hotfix) :
|
||||
spawnStaticModule(name);
|
||||
if (!module) { return; }
|
||||
mModuleBlocks[name] = ModuleBlock{false, false};
|
||||
ModuleBlock& block = mModuleBlocks[name];
|
||||
auto& moduleInfo = module->mInfo;
|
||||
Name shared("shared");
|
||||
for (auto& dep : moduleInfo.dependencies) {
|
||||
if(auto it = mModuleBlocks.find(dep.name); it == mModuleBlocks.end())
|
||||
CreateModule(dep.name, dep.kind == pmr::FName("shared"));
|
||||
CreateModule(dep.name, dep.kind == shared);
|
||||
}
|
||||
module->OnLoad(mInfo.argc, mInfo.argv);
|
||||
block.isLoad = true;
|
||||
|
||||
@ -19,7 +19,7 @@ namespace gen {
|
||||
else if constexpr (std::is_floating_point_v<T>) {
|
||||
*(T*)(ptr) = (T)yyjson_get_real(val);
|
||||
}
|
||||
else if constexpr (is_string_v<T>) {
|
||||
else if constexpr (is_string_view_v<T> || is_string_v<T>) {
|
||||
*(T*)(ptr) = yyjson_get_str(val);
|
||||
}
|
||||
else {
|
||||
@ -40,14 +40,12 @@ namespace gen {
|
||||
else if constexpr (std::is_floating_point_v<T>) {
|
||||
return yyjson_mut_real(doc, *(T*)(ptr));
|
||||
}
|
||||
else if constexpr (is_string_view_v<T>) {
|
||||
return yyjson_mut_str(doc, std::string_view(*(T*)ptr).data());
|
||||
}
|
||||
else if constexpr (is_string_v<T>) {
|
||||
if constexpr (requires(T * t) { t->data(); }) {
|
||||
return yyjson_mut_str(doc, ((T*)ptr)->data());
|
||||
}
|
||||
else {
|
||||
return yyjson_mut_str(doc, std::string(*(T*)ptr).data());
|
||||
}
|
||||
}
|
||||
else {
|
||||
//static_assert(false, "unknown json write type");
|
||||
}
|
||||
|
||||
@ -33,11 +33,11 @@ namespace api {
|
||||
#include "../register.inl"
|
||||
#undef RegisterAny
|
||||
}
|
||||
inline consteval size_t VJsonSerdeRead() {
|
||||
return string_hash("JsonSerdeRead");
|
||||
inline Name VJsonSerdeRead() {
|
||||
return Name("JsonSerdeRead");
|
||||
}
|
||||
inline consteval size_t VJsonSerdeWrite() {
|
||||
return string_hash("JsonSerdeWrite");
|
||||
inline Name VJsonSerdeWrite() {
|
||||
return Name("JsonSerdeWrite");
|
||||
}
|
||||
template<typename T>
|
||||
inline void JsonArchive::Register()
|
||||
|
||||
@ -6,14 +6,20 @@ namespace gen {
|
||||
struct Meta {};
|
||||
template<typename T>
|
||||
concept is_string_v = requires(T t) {
|
||||
{ static_cast<std::string>(t) } -> std::convertible_to<std::string>;
|
||||
{ static_cast<std::string>(t) } -> std::same_as<std::string>;
|
||||
};
|
||||
template<typename T>
|
||||
concept is_serde_v = std::is_same_v<T, bool> || std::is_integral_v<T> || std::is_floating_point_v<T> || is_string_v<T> || std::is_enum_v<T>;
|
||||
concept is_string_view_v = requires(T t) {
|
||||
{ static_cast<std::string_view>(t) } -> std::same_as<std::string_view>;
|
||||
};
|
||||
template<typename T>
|
||||
concept is_serde_v = std::is_same_v<T, bool> || std::is_integral_v<T> || std::is_floating_point_v<T> || is_string_v<T> || std::is_enum_v<T>
|
||||
|| is_string_view_v<T>;
|
||||
}
|
||||
namespace api {
|
||||
using meta::result;
|
||||
using std::string_view;
|
||||
using pmr::Name;
|
||||
enum class SerializeError : char
|
||||
{
|
||||
SERDE_EMPTY,
|
||||
|
||||
@ -16,6 +16,9 @@ namespace gen {
|
||||
else if constexpr (std::is_enum_v<T>) {
|
||||
*(T*)(ptr) = (T)node.as<uint32_t>();
|
||||
}
|
||||
else if constexpr (is_string_view_v<T>) {
|
||||
*(T*)(ptr) = node.as<std::string_view>();
|
||||
}
|
||||
else if constexpr (is_string_v<T>) {
|
||||
*(T*)(ptr) = node.as<std::string>();
|
||||
}
|
||||
@ -31,14 +34,12 @@ namespace gen {
|
||||
else if constexpr (std::is_enum_v<T>) {
|
||||
return YAML::Node{ *(uint32_t*)(T*)ptr };
|
||||
}
|
||||
else if constexpr (is_string_view_v<T>) {
|
||||
return YAML::Node{ std::string_view(*(T*)ptr).data() };
|
||||
}
|
||||
else if constexpr (is_string_v<T>) {
|
||||
if constexpr (requires(T * t) { t->data(); }) {
|
||||
return YAML::Node{ ((T*)ptr)->data()};
|
||||
}
|
||||
else {
|
||||
return YAML::Node{ std::string(*(T*)ptr).data() };
|
||||
}
|
||||
}
|
||||
else {
|
||||
//static_assert(false, "unknown json write type");
|
||||
}
|
||||
|
||||
@ -7,11 +7,11 @@ namespace api {
|
||||
#include "../register.inl"
|
||||
#undef RegisterAny
|
||||
}
|
||||
inline consteval size_t VYamlSerdeRead() {
|
||||
return string_hash("YamlSerdeRead");
|
||||
inline Name VYamlSerdeRead() {
|
||||
return Name("YamlSerdeRead");
|
||||
}
|
||||
inline consteval size_t VYamlSerdeWrite() {
|
||||
return string_hash("YamlSerdeWrite");
|
||||
inline Name VYamlSerdeWrite() {
|
||||
return Name("YamlSerdeWrite");
|
||||
}
|
||||
template<typename T>
|
||||
inline void YamlArchive::Register()
|
||||
|
||||
@ -27,8 +27,8 @@ namespace api {
|
||||
void Execute(FRenderView& view);
|
||||
void Clear();
|
||||
TextureDesc Resource(Name name) {
|
||||
constexpr size_t surface = string_hash("surface");
|
||||
if (name.Hash() == surface) {
|
||||
static Name surface("surface");
|
||||
if (name == surface) {
|
||||
return mSurface;
|
||||
}
|
||||
auto it = mResourceTable.find(name);
|
||||
|
||||
@ -29,15 +29,15 @@ namespace api
|
||||
}
|
||||
shaderc_shader_kind GlslToSpirv::GetShaderKind(Name name)
|
||||
{
|
||||
switch (name.Hash())
|
||||
{
|
||||
case string_hash(".vert"): return shaderc_shader_kind::shaderc_vertex_shader;
|
||||
case string_hash(".geom"): return shaderc_shader_kind::shaderc_geometry_shader;
|
||||
case string_hash(".tese"): return shaderc_shader_kind::shaderc_tess_evaluation_shader;
|
||||
case string_hash(".tesc"): return shaderc_shader_kind::shaderc_tess_control_shader;
|
||||
case string_hash(".frag"): return shaderc_shader_kind::shaderc_fragment_shader;
|
||||
default: return shaderc_shader_kind::shaderc_miss_shader;
|
||||
static Name vert(".vert");
|
||||
static Name frag(".frag");
|
||||
if (name == vert) {
|
||||
return shaderc_shader_kind::shaderc_vertex_shader;
|
||||
}
|
||||
if(name == frag) {
|
||||
return shaderc_shader_kind::shaderc_fragment_shader;
|
||||
}
|
||||
throw std::runtime_error("unsupport type");
|
||||
}
|
||||
ShaderStage GlslToSpirv::GetShaderStage(shaderc_shader_kind kind)
|
||||
{
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
#include <vector>
|
||||
#include <memory_resource>
|
||||
namespace pmr {
|
||||
using std::pmr::unsynchronized_pool_resource;
|
||||
using std::pmr::memory_resource;
|
||||
using std::pmr::vector;
|
||||
class ZLIB_API FrameAllocator : public memory_resource {
|
||||
|
||||
@ -1,81 +1,217 @@
|
||||
#pragma once
|
||||
#include <mutex>
|
||||
#include <array>
|
||||
#include "singleton.h"
|
||||
#include "frame_allocator.h"
|
||||
#include <unordered_map>
|
||||
namespace pmr
|
||||
{
|
||||
template<typename T1, typename T2, typename Hasher = std::hash<T1>>
|
||||
using table = std::pmr::unordered_map<T1, T2, Hasher>;
|
||||
using std::pmr::string;
|
||||
static consteval inline size_t InvalidValue() noexcept { return static_cast<size_t>(-1); }
|
||||
struct Name {
|
||||
private:
|
||||
size_t hash;
|
||||
#ifdef API_DEBUG
|
||||
std::string_view value;
|
||||
#endif // API_DEBUG
|
||||
public:
|
||||
Name():hash(InvalidValue()) {};
|
||||
template<size_t N>
|
||||
Name(const char(&str)[N]) noexcept;
|
||||
Name(const char* str)noexcept;
|
||||
Name(const std::string& str)noexcept;
|
||||
Name(const string& str)noexcept;
|
||||
Name(std::string_view str)noexcept;
|
||||
auto operator<=>(const Name& other) const noexcept { return hash <=> other.hash; };
|
||||
const char* data()const { return ToStringView().data(); }
|
||||
constexpr size_t Hash() const noexcept { return hash; }
|
||||
std::string ToString() const;
|
||||
const std::string_view ToStringView() const;
|
||||
operator size_t()const {return hash;}
|
||||
operator std::string() const { return ToString(); }
|
||||
};
|
||||
class CName {
|
||||
private:
|
||||
size_t hash;
|
||||
std::string_view value;
|
||||
public:
|
||||
constexpr CName() noexcept : hash{ InvalidValue() } {}
|
||||
constexpr CName(string str) noexcept : hash{ string_hash(str) }, value(str) {}
|
||||
constexpr CName(std::string_view str) noexcept : hash{ string_hash(str) } ,value(str) {}
|
||||
template<size_t N>
|
||||
constexpr CName(const char(&str)[N]) noexcept : hash{ string_hash(str) }, value(str) {}
|
||||
const char* data()const { return Value().data(); }
|
||||
constexpr size_t Hash() const noexcept { return hash; }
|
||||
constexpr std::string_view Value() const noexcept { return value; }
|
||||
constexpr bool Valid() const noexcept { return hash != InvalidValue(); }
|
||||
operator Name() {return Name(value);}
|
||||
explicit constexpr operator bool() const noexcept { return Valid(); }
|
||||
|
||||
constexpr auto operator<=>(const CName& rhs) const noexcept { return hash <=> rhs.hash; };
|
||||
bool operator==(const CName& other) const { return hash == other.hash; }
|
||||
std::string ToString() const { return std::string(value); };
|
||||
operator std::string() const { return ToString(); }
|
||||
};
|
||||
inline bool operator==(const CName& cname, const Name& name) {
|
||||
return cname.Hash() == name.Hash();
|
||||
}
|
||||
namespace pmr {
|
||||
template <class T>
|
||||
constexpr inline void hash_combine(size_t& seed, const T& v) noexcept
|
||||
{
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
consteval static CName FName(std::string_view view) { return CName{ view }; };
|
||||
template<typename T1, typename T2, typename Hasher = std::hash<T1>>
|
||||
using table = std::pmr::unordered_map<T1, T2, Hasher>;
|
||||
using std::pmr::string;
|
||||
class Name {
|
||||
static constexpr uint32_t IS_USED_MASK = 1u << 29u;
|
||||
static constexpr uint32_t STRING_ENTRY_HANDLE_BITS = 29u;
|
||||
static constexpr uint32_t STRING_ENTRY_HANDLE_MASK = (1u << 29u) - 1u;
|
||||
static constexpr uint32_t MAX_STRING_SIZE = 1023u;
|
||||
static constexpr uint32_t MAX_SLOT_POOL_ARRAY_SIZE = 256u;
|
||||
static constexpr uint32_t MAX_MEMORY_BLOCK_ARRAY_SIZE = 8192u;
|
||||
struct StringEntryHandle
|
||||
{
|
||||
static constexpr uint16_t MEMORY_BLOCK_INDEX_MASK = (1u << 13u) - 1u;
|
||||
private:
|
||||
uint16_t empty3_memoryBlockIndex13;
|
||||
uint16_t memoryBlockAlignedOffset16;
|
||||
public:
|
||||
StringEntryHandle()
|
||||
: empty3_memoryBlockIndex13(0u), memoryBlockAlignedOffset16(0u){}
|
||||
StringEntryHandle(uint32_t stringEntryHandleValue)
|
||||
: StringEntryHandle(static_cast<uint16_t>(stringEntryHandleValue >> 16)& MEMORY_BLOCK_INDEX_MASK, static_cast<uint16_t>(stringEntryHandleValue)) {}
|
||||
StringEntryHandle(uint16_t memoryBlockIndex, uint16_t memoryBlockAlignedOffset)
|
||||
: empty3_memoryBlockIndex13(memoryBlockIndex), memoryBlockAlignedOffset16(memoryBlockAlignedOffset) {}
|
||||
uint16_t GetMemoryBlockIndex() const {
|
||||
return empty3_memoryBlockIndex13;
|
||||
}
|
||||
uint16_t GetMemoryBlockAlignedOffset() const {
|
||||
return memoryBlockAlignedOffset16;
|
||||
}
|
||||
uint32_t GetStringEntryHandleValue() const {
|
||||
return static_cast<uint32_t>(empty3_memoryBlockIndex13) << 16 | memoryBlockAlignedOffset16;
|
||||
}
|
||||
};
|
||||
struct StringEntryHeader
|
||||
{
|
||||
static constexpr uint16_t SIZE_MASK = (1u << 10u) - 1u;
|
||||
static constexpr uint16_t STRING_HASH_PROBE_MASK = ((1u << 6u) - 1u) << 10u;
|
||||
private:
|
||||
uint16_t stringHashProbe6_size10;
|
||||
public:
|
||||
void Init(const uint8_t stringHashProbe, const uint16_t size) {
|
||||
stringHashProbe6_size10 = (STRING_HASH_PROBE_MASK & (static_cast<uint16_t>(stringHashProbe) << 10u)) | (SIZE_MASK & size);
|
||||
}
|
||||
uint16_t GetSize() const { return SIZE_MASK & stringHashProbe6_size10; }
|
||||
operator uint16_t() { return stringHashProbe6_size10; }
|
||||
};
|
||||
struct StringEntry
|
||||
{
|
||||
private:
|
||||
StringEntryHeader stringEntryHeader;
|
||||
char data[MAX_STRING_SIZE];
|
||||
public:
|
||||
StringEntryHeader GetStringEntryHeader() const {
|
||||
return stringEntryHeader;
|
||||
}
|
||||
void SetStringEntryHeader(StringEntryHeader _stringEntryHeader) {
|
||||
stringEntryHeader = _stringEntryHeader;
|
||||
}
|
||||
const char* GetData() const { return data; };
|
||||
};
|
||||
struct HashInfo {
|
||||
static constexpr uint32_t SLOT_POOL_INDEX_MASK = (1u << 8u) - 1u;
|
||||
static constexpr uint32_t SLOT_HASH_PROBE_MASK = ((1u << 3u) - 1) << 13u;
|
||||
static constexpr uint32_t STRING_HASH_PROBE_MASK = (1u << 6u) - 1;
|
||||
const char* data;
|
||||
StringEntryHeader stringEntryHeader;
|
||||
uint16_t slotProbe3_empty21_slotPool8;
|
||||
uint32_t slotIndex32;
|
||||
HashInfo(std::string_view view) {
|
||||
uint64_t hash = string_hash(view);
|
||||
uint32_t Hi = static_cast<uint32_t>(hash >> 32);
|
||||
uint32_t Lo = static_cast<uint32_t>(hash);
|
||||
|
||||
slotIndex32 = Lo;
|
||||
slotProbe3_empty21_slotPool8 = (SLOT_HASH_PROBE_MASK & (Hi >> 16)) | (SLOT_POOL_INDEX_MASK & Hi);
|
||||
stringEntryHeader.Init((Hi >> 8u) & STRING_HASH_PROBE_MASK, view.size());
|
||||
data = view.data();
|
||||
}
|
||||
const char* GetData() {
|
||||
return data;
|
||||
}
|
||||
uint32_t GetSlotIndex() const{
|
||||
return slotIndex32;
|
||||
}
|
||||
StringEntryHeader GetStringEntryHeader() const {
|
||||
return stringEntryHeader;
|
||||
}
|
||||
uint32_t GetSlotPoolIndex() const {
|
||||
return SLOT_POOL_INDEX_MASK & slotProbe3_empty21_slotPool8;
|
||||
}
|
||||
template<uint32_t mask>
|
||||
uint32_t GetSlotHashProbe() const
|
||||
{
|
||||
return mask | (SLOT_HASH_PROBE_MASK & slotProbe3_empty21_slotPool8) << 16;
|
||||
}
|
||||
};
|
||||
|
||||
struct Slot
|
||||
{
|
||||
static constexpr uint32_t SLOT_HASH_PROBE_MASK = ((1u << 3u) - 1) << 29u;
|
||||
static constexpr uint32_t STRING_ENTRY_HANDLE_MASK = (1u << 29u) - 1u;
|
||||
static constexpr uint32_t MEMORY_BLOCK_ALIGNED_OFFSET_MASK = (1u << 16u) - 1u;
|
||||
static constexpr uint32_t MEMORY_BLOCK_INDEX_MASK = ((1u << 13u) - 1u);
|
||||
private:
|
||||
uint32_t slotHashProbe3_stringEntryHandle29;
|
||||
public:
|
||||
bool IsTargetSlot(HashInfo hashInfo) const;
|
||||
bool IsUsed() const{ return (slotHashProbe3_stringEntryHandle29 & IS_USED_MASK) == IS_USED_MASK; }
|
||||
uint32_t GetSlotHashProbe() const { return SLOT_HASH_PROBE_MASK & slotHashProbe3_stringEntryHandle29; };
|
||||
StringEntryHandle GetStringEntryHandle() const {
|
||||
return StringEntryHandle((slotHashProbe3_stringEntryHandle29 >> 16) & MEMORY_BLOCK_INDEX_MASK, slotHashProbe3_stringEntryHandle29 & MEMORY_BLOCK_ALIGNED_OFFSET_MASK);
|
||||
}
|
||||
uint32_t GetStringEntryHandleValue() const { return slotHashProbe3_stringEntryHandle29 & STRING_ENTRY_HANDLE_BITS; };
|
||||
uint32_t GetSlotValue() const { return slotHashProbe3_stringEntryHandle29; };
|
||||
void Load(uint32_t slotHashProbeValue,StringEntryHandle stringEntryHandle) {
|
||||
slotHashProbe3_stringEntryHandle29 = slotHashProbeValue | stringEntryHandle.GetStringEntryHandleValue();
|
||||
}
|
||||
void Load(Slot srcSlot) {slotHashProbe3_stringEntryHandle29 = srcSlot.slotHashProbe3_stringEntryHandle29;}
|
||||
};
|
||||
struct SlotPool
|
||||
{
|
||||
friend class Name;
|
||||
static constexpr double SLOT_POOL_RESIZE_USAGE_RATE = 0.9;
|
||||
static constexpr uint32_t SLOT_POOL_INITIALIZE_SIZE = 256u;
|
||||
private:
|
||||
uint32_t capcity;
|
||||
uint32_t size;
|
||||
Slot* slotArray;
|
||||
std::mutex mutex;
|
||||
public:
|
||||
Slot& FindUnusedOrTargetSlot(HashInfo hashInfo);
|
||||
Slot& FindUnusedSlot(HashInfo hashInfo);
|
||||
void AutoResize();
|
||||
void Resize();
|
||||
};
|
||||
struct StringEntryMemoryManager
|
||||
{
|
||||
friend class Name;
|
||||
static constexpr uint32_t ALIGN_BYTES = 2u;
|
||||
static constexpr uint32_t MAX_MEMORY_BLOCK_SIZE = (1u << 16u) * 2u;
|
||||
private:
|
||||
uint16_t currentMemoryBlockIndex;
|
||||
uint16_t currentMemoryBlockAlignedCursor;
|
||||
char* memoryBlockArray[MAX_MEMORY_BLOCK_ARRAY_SIZE];
|
||||
std::mutex mutex;
|
||||
public:
|
||||
StringEntryMemoryManager();
|
||||
StringEntry* GetStringEntry(StringEntryHandle stringEntryHandle) const;
|
||||
StringEntryHandle AllocateStringEntry(StringEntryHeader stringEntryHeader, const char* data);
|
||||
private:
|
||||
void CreateNewMemoryBlock();
|
||||
};
|
||||
using tSlotPoolArray = std::array<SlotPool, MAX_SLOT_POOL_ARRAY_SIZE>;
|
||||
inline UNIQUER_STATIC(tSlotPoolArray, slotPoolArray, "pmr::name::slotPoolArray")
|
||||
inline UNIQUER_STATIC(StringEntryMemoryManager, stringEntryMemoryManager, "pmr::name::stringEntryMemoryManager")
|
||||
uint32_t flag3_memory29;
|
||||
public:
|
||||
Name()noexcept : flag3_memory29(0) {};
|
||||
Name(std::string view) noexcept : flag3_memory29(MakeInterned(view)) {};
|
||||
Name(std::string_view view) noexcept : flag3_memory29(MakeInterned(view)) {};
|
||||
template<size_t N>
|
||||
Name(const char(&str)[N]) noexcept : Name(std::string_view(str)) {}
|
||||
Name(const char* str)noexcept : Name(std::string_view(str)){};
|
||||
auto operator<=>(const Name& other) const noexcept { return flag3_memory29 <=> other.flag3_memory29; };
|
||||
uint32_t MakeInterned(std::string_view view);
|
||||
uint32_t Hash() const{
|
||||
return flag3_memory29;
|
||||
}
|
||||
operator uint32_t() const {
|
||||
return flag3_memory29;
|
||||
}
|
||||
operator std::string_view()const {
|
||||
return ToStringView();
|
||||
}
|
||||
operator std::string()const {
|
||||
return ToString();
|
||||
}
|
||||
const char* data()const {
|
||||
if (!flag3_memory29)return nullptr;
|
||||
const StringEntry* stringEntry = UNIQUER_VAL(stringEntryMemoryManager).GetStringEntry(StringEntryHandle(flag3_memory29));
|
||||
return stringEntry->GetData();
|
||||
}
|
||||
std::string_view ToStringView() const
|
||||
{
|
||||
if (!flag3_memory29)return "";
|
||||
const StringEntry* stringEntry = UNIQUER_VAL(stringEntryMemoryManager).GetStringEntry(StringEntryHandle(flag3_memory29));
|
||||
return std::string_view(stringEntry->GetData(), stringEntry->GetStringEntryHeader().GetSize());
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
if (!flag3_memory29)return "";
|
||||
const StringEntry* stringEntry = UNIQUER_VAL(stringEntryMemoryManager).GetStringEntry(StringEntryHandle(flag3_memory29));
|
||||
return std::string(stringEntry->GetData(), stringEntry->GetStringEntryHeader().GetSize());
|
||||
}
|
||||
};
|
||||
}
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<::pmr::CName>
|
||||
{
|
||||
size_t operator()(const ::pmr::CName& name) const noexcept
|
||||
{
|
||||
return name.Hash();
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct hash<::pmr::Name>
|
||||
{
|
||||
size_t operator()(const ::pmr::Name& name) const noexcept
|
||||
uint32_t operator()(const ::pmr::Name& name) const noexcept
|
||||
{
|
||||
return name.Hash();
|
||||
}
|
||||
|
||||
@ -1,74 +1,151 @@
|
||||
namespace pmr {
|
||||
using NameTable_t = table<size_t,const string>;
|
||||
inline NameTable_t& TableRef() {
|
||||
UNIQUER_STATIC(NameTable_t, Table, "pmr::nametable")
|
||||
return UNIQUER_VAL(Table);
|
||||
}
|
||||
struct NameTable {
|
||||
static const string& Find(size_t id);
|
||||
template<typename T>
|
||||
static std::string_view MakePair(size_t id, T&& str);
|
||||
};
|
||||
template<typename T>
|
||||
inline std::string_view NameTable::MakePair(size_t id, T&& str)
|
||||
{
|
||||
auto& Table = TableRef();
|
||||
auto it = Table.find(id);
|
||||
if (it == Table.end()) {
|
||||
auto it2 = Table.emplace(std::make_pair(id, string(str, Table.get_allocator())));
|
||||
if (it2.second) {
|
||||
return it2.first->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
inline const string& NameTable::Find(size_t id)
|
||||
{
|
||||
auto& Table = TableRef();
|
||||
auto it = Table.find(id);
|
||||
if (it == Table.end()) {
|
||||
static string empty("", Table.get_allocator());
|
||||
return empty;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
#ifdef API_DEBUG
|
||||
#define MAKE_NAME_PAIR(hash, str) value = NameTable::MakePair(hash, str)
|
||||
#define NAME_TO_STRING value
|
||||
#else
|
||||
#define MAKE_NAME_PAIR(hash, str) NameTable::MakePair(hash, str)
|
||||
#define NAME_TO_STRING NameTable::Find(hash)
|
||||
#endif
|
||||
inline std::string Name::ToString() const
|
||||
{
|
||||
return std::string(NAME_TO_STRING);
|
||||
}
|
||||
inline const std::string_view Name::ToStringView() const
|
||||
{
|
||||
return std::string_view(NAME_TO_STRING);
|
||||
}
|
||||
inline Name::Name(const char* str) noexcept: hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
template<std::size_t N>
|
||||
inline Name::Name(const char(&str)[N]) noexcept : hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
inline Name::Name(const std::string& str) noexcept : hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
inline Name::Name(std::string_view str) noexcept : hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
inline Name::Name(const string& str)noexcept : hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
#undef MAKE_NAME_PAIR
|
||||
#undef NAME_TO_STRING
|
||||
#include "name.h"
|
||||
constexpr inline size_t meta_align_size(size_t size, size_t alignment = 8) {
|
||||
return (size + alignment - 1) / alignment * alignment;
|
||||
}
|
||||
XMALLOC_API void* xmalloc(size_t size);
|
||||
namespace pmr {
|
||||
inline bool Name::Slot::IsTargetSlot(HashInfo hashInfo) const
|
||||
{
|
||||
if (GetSlotHashProbe() == hashInfo.GetSlotHashProbe<IS_USED_MASK>())
|
||||
{
|
||||
const StringEntry* stringEntry = UNIQUER_VAL(stringEntryMemoryManager).GetStringEntry(GetStringEntryHandle());
|
||||
auto entryHeader = stringEntry->GetStringEntryHeader();
|
||||
if (entryHeader == hashInfo.GetStringEntryHeader() && 0 == strncmp(stringEntry->GetData(), hashInfo.GetData(), entryHeader.GetSize()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline Name::Slot& Name::SlotPool::FindUnusedOrTargetSlot(HashInfo hashInfo)
|
||||
{
|
||||
const uint32_t SLOT_POOL_CAPCITY_MASK = capcity - 1;
|
||||
for (uint32_t slotIndex = hashInfo.GetSlotIndex() & SLOT_POOL_CAPCITY_MASK; true; slotIndex = (slotIndex + 1) & SLOT_POOL_CAPCITY_MASK)
|
||||
{
|
||||
Slot& slot = slotArray[slotIndex];
|
||||
|
||||
if (!slot.IsUsed() || slot.IsTargetSlot(hashInfo))
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline Name::Slot& Name::SlotPool::FindUnusedSlot(HashInfo hashInfo)
|
||||
{
|
||||
const uint32_t SLOT_POOL_CAPCITY_MASK = capcity - 1;
|
||||
for (uint32_t slotIndex = hashInfo.GetSlotIndex() & SLOT_POOL_CAPCITY_MASK; true; slotIndex = (slotIndex + 1) & SLOT_POOL_CAPCITY_MASK)
|
||||
{
|
||||
Slot& slot = slotArray[slotIndex];
|
||||
|
||||
if (!slot.IsUsed())
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void Name::SlotPool::AutoResize()
|
||||
{
|
||||
if (size > SLOT_POOL_RESIZE_USAGE_RATE * capcity)
|
||||
{
|
||||
Resize();
|
||||
}
|
||||
}
|
||||
inline void Name::SlotPool::Resize()
|
||||
{
|
||||
uint32_t oldCapcity = capcity;
|
||||
Slot* oldSlotArray = slotArray;
|
||||
|
||||
capcity = oldCapcity * 2;
|
||||
slotArray = reinterpret_cast<Slot*>(xmalloc(capcity * sizeof(Slot)));
|
||||
//std::memset(slotArray, 0, capcity * sizeof(Slot));
|
||||
auto& stringEntryMemoryManager = UNIQUER_VAL(stringEntryMemoryManager);
|
||||
for (uint32_t slotIndex = 0; slotIndex < size; slotIndex++)
|
||||
{
|
||||
const Name::Slot& oldSlot = oldSlotArray[slotIndex];
|
||||
|
||||
StringEntry* stringEntry = stringEntryMemoryManager.GetStringEntry(oldSlotArray[slotIndex].GetStringEntryHandle());
|
||||
const HashInfo hashInfo(std::string_view(stringEntry->GetData(), stringEntry->GetStringEntryHeader().GetSize()));
|
||||
|
||||
Name::Slot& slot = FindUnusedSlot(hashInfo);
|
||||
|
||||
slot.Load(oldSlot);
|
||||
}
|
||||
|
||||
std::free(oldSlotArray);
|
||||
}
|
||||
inline Name::StringEntryMemoryManager::StringEntryMemoryManager()
|
||||
{
|
||||
auto& slotPoolArray = UNIQUER_VAL(slotPoolArray);
|
||||
for (auto& slotPool : slotPoolArray)
|
||||
{
|
||||
slotPool.size = 0;
|
||||
slotPool.capcity = SlotPool::SLOT_POOL_INITIALIZE_SIZE;
|
||||
slotPool.slotArray = (Slot*)(xmalloc(SlotPool::SLOT_POOL_INITIALIZE_SIZE * sizeof(Slot)));
|
||||
std::memset(slotPool.slotArray, 0, SlotPool::SLOT_POOL_INITIALIZE_SIZE);
|
||||
}
|
||||
currentMemoryBlockIndex = 0;
|
||||
currentMemoryBlockAlignedCursor = 0;
|
||||
memoryBlockArray[0] = (char*)(xmalloc(MAX_MEMORY_BLOCK_SIZE));
|
||||
std::memset(memoryBlockArray[0], 0, MAX_MEMORY_BLOCK_SIZE);
|
||||
}
|
||||
inline Name::StringEntry* Name::StringEntryMemoryManager::GetStringEntry(StringEntryHandle stringEntryHandle) const
|
||||
{
|
||||
return reinterpret_cast<Name::StringEntry*>(memoryBlockArray[stringEntryHandle.GetMemoryBlockIndex()] + stringEntryHandle.GetMemoryBlockAlignedOffset() * ALIGN_BYTES);
|
||||
}
|
||||
inline Name::StringEntryHandle Name::StringEntryMemoryManager::AllocateStringEntry(StringEntryHeader stringEntryHeader, const char* data)
|
||||
{
|
||||
const uint32_t size = meta_align_size(sizeof(StringEntryHeader) + stringEntryHeader.GetSize(), ALIGN_BYTES);
|
||||
const uint32_t alignedSize = size >> 1;
|
||||
|
||||
StringEntryHandle stringEntryHandle{};
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
|
||||
if (((static_cast<uint32_t>(currentMemoryBlockAlignedCursor) + alignedSize) << 1) >= MAX_MEMORY_BLOCK_SIZE)
|
||||
{
|
||||
CreateNewMemoryBlock();
|
||||
}
|
||||
|
||||
stringEntryHandle = StringEntryHandle(currentMemoryBlockIndex, currentMemoryBlockAlignedCursor);
|
||||
currentMemoryBlockAlignedCursor += alignedSize;
|
||||
}
|
||||
|
||||
StringEntry* stringEntry = GetStringEntry(stringEntryHandle);
|
||||
stringEntry->SetStringEntryHeader(stringEntryHeader);
|
||||
memcpy(const_cast<char*>(stringEntry->GetData()), data, stringEntryHeader.GetSize());
|
||||
|
||||
return stringEntryHandle;
|
||||
}
|
||||
inline void Name::StringEntryMemoryManager::CreateNewMemoryBlock()
|
||||
{
|
||||
if (currentMemoryBlockIndex >= (MAX_MEMORY_BLOCK_ARRAY_SIZE - 1))
|
||||
throw std::runtime_error("Interned string only supports a maximum of 1GB memory.");
|
||||
|
||||
currentMemoryBlockIndex += 1;
|
||||
currentMemoryBlockAlignedCursor = 0;
|
||||
memoryBlockArray[currentMemoryBlockIndex] = (char*)(xmalloc(MAX_MEMORY_BLOCK_SIZE));
|
||||
std::memset(memoryBlockArray[currentMemoryBlockIndex], 0, MAX_MEMORY_BLOCK_SIZE);
|
||||
}
|
||||
inline uint32_t Name::MakeInterned(std::string_view view)
|
||||
{
|
||||
if (view.empty()) {
|
||||
return 0u;
|
||||
}
|
||||
HashInfo hashInfo(view);
|
||||
auto& slotPool = UNIQUER_VAL(slotPoolArray)[0];
|
||||
uint32_t slotValue = 0u;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(slotPool.mutex);
|
||||
slotPool.AutoResize();
|
||||
Name::Slot& slot = slotPool.FindUnusedOrTargetSlot(hashInfo);
|
||||
if (!slot.IsUsed())
|
||||
{
|
||||
slotPool.size++;
|
||||
StringEntryHandle stringEntryHandle = UNIQUER_VAL(stringEntryMemoryManager).AllocateStringEntry(hashInfo.GetStringEntryHeader(), hashInfo.GetData());
|
||||
slot.Load(hashInfo.GetSlotHashProbe<IS_USED_MASK>(), stringEntryHandle);
|
||||
}
|
||||
slotValue = slot.GetSlotValue();
|
||||
}
|
||||
return slotValue;
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,7 @@ namespace refl {
|
||||
operator bool()const { return cls && ptr; }
|
||||
bool Check(const UClass* parent) const;
|
||||
template<typename T>
|
||||
T FindVtable(size_t name)const;
|
||||
T FindVtable(Name name)const;
|
||||
bool Construct(span<Any> ArgsList) const;
|
||||
Any New(pmr::memory_resource* pool)const;
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ namespace refl{
|
||||
return any;
|
||||
}
|
||||
template<typename T>
|
||||
inline T Any::FindVtable(size_t name) const
|
||||
inline T Any::FindVtable(Name name) const
|
||||
{
|
||||
return (T)cls->vtable.Find(name);
|
||||
}
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
#pragma once
|
||||
#include "field.h"
|
||||
constexpr inline size_t meta_align_size(size_t size, size_t alignment = 8) {
|
||||
return (size + alignment - 1) / alignment * alignment;
|
||||
}
|
||||
namespace gen {
|
||||
using refl::real_type_t;
|
||||
using pmr::CName;
|
||||
using pmr::FName;
|
||||
template<typename T, size_t hash>
|
||||
struct MetaImpl {};
|
||||
template<typename T>
|
||||
@ -38,16 +33,16 @@ namespace refl {
|
||||
static FieldPtr CtorField(T(*ptr)(Args...), const MethodData& data = {});
|
||||
|
||||
template<typename T, typename Obj>
|
||||
static FieldPtr MemberField(T Obj::* ptr, CName name, const MemberData& data = {});
|
||||
static FieldPtr MemberField(T Obj::* ptr, std::string_view name, const MemberData& data = {});
|
||||
|
||||
template<typename R, typename ...Args>
|
||||
static FieldPtr MethodField(R(*ptr)(Args...), CName name, const MethodData& data = {});
|
||||
static FieldPtr MethodField(R(*ptr)(Args...), std::string_view name, const MethodData& data = {});
|
||||
|
||||
template<typename T, typename R, typename ...Args>
|
||||
static FieldPtr MethodField(R(T::* ptr)(Args...), CName name, const MethodData& data = {});
|
||||
static FieldPtr MethodField(R(T::* ptr)(Args...), std::string_view name, const MethodData& data = {});
|
||||
|
||||
template<typename T, typename R, typename ...Args>
|
||||
static FieldPtr MethodField(R(T::* ptr)(Args...)const, CName name, const MethodData& data = {}) {
|
||||
static FieldPtr MethodField(R(T::* ptr)(Args...)const, std::string_view name, const MethodData& data = {}) {
|
||||
return MethodField(remove_const(ptr), name, data);
|
||||
}
|
||||
};
|
||||
|
||||
@ -43,7 +43,7 @@ namespace refl {
|
||||
return FieldPtr{Name("Ctor"), cls, method, flag};
|
||||
}
|
||||
template<typename T, typename Obj>
|
||||
inline FieldPtr MetaHelp::MemberField(T Obj::* ptr, CName name, const MemberData& data)
|
||||
inline FieldPtr MetaHelp::MemberField(T Obj::* ptr, std::string_view name, const MemberData& data)
|
||||
{
|
||||
const UClass* cls = meta_info<T>();
|
||||
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG;
|
||||
@ -58,7 +58,7 @@ namespace refl {
|
||||
return FieldPtr{ name, cls, member, flag };
|
||||
}
|
||||
template<typename R, typename ...Args>
|
||||
inline FieldPtr MetaHelp::MethodField(R(*ptr)(Args...), CName name, const MethodData& data)
|
||||
inline FieldPtr MetaHelp::MethodField(R(*ptr)(Args...), std::string_view name, const MethodData& data)
|
||||
{
|
||||
MethodData method;
|
||||
uint32_t flag = FIELD_METHOD_FLAG;
|
||||
@ -74,7 +74,7 @@ namespace refl {
|
||||
return { name, cls, method,flag };
|
||||
}
|
||||
template<typename T, typename R, typename ...Args>
|
||||
inline FieldPtr MetaHelp::MethodField(R(T::* ptr)(Args...), CName name, const MethodData& data) {
|
||||
inline FieldPtr MetaHelp::MethodField(R(T::* ptr)(Args...), std::string_view name, const MethodData& data) {
|
||||
MethodData method;
|
||||
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
|
||||
const UClass* cls = meta_info<real_type_t<R>(*)(const void*, real_type_t<Args>...)>();
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
#include "pmr/name.h"
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
namespace refl {
|
||||
using pmr::Name;
|
||||
template <size_t N>
|
||||
struct TStr {
|
||||
std::array<char, N> value{}; // 确切长度的字符数组,不依赖 '\0'
|
||||
@ -23,8 +25,6 @@ namespace refl {
|
||||
template <size_t N>
|
||||
TStr(const char(&)[N]) -> TStr<N - 1>;
|
||||
|
||||
template<auto v>
|
||||
constexpr auto value_name() noexcept;
|
||||
template<typename T>
|
||||
constexpr auto meta_name() noexcept;
|
||||
Name meta_name()noexcept;
|
||||
}
|
||||
@ -15,7 +15,7 @@ namespace refl {
|
||||
# endif
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto raw_meta_name() noexcept {
|
||||
constexpr auto raw_meta_tstr() noexcept {
|
||||
constexpr std::string_view sign = func_signature<T>();
|
||||
constexpr size_t size = sign.size();
|
||||
return TStr<size>{ sign };
|
||||
@ -32,7 +32,7 @@ namespace refl {
|
||||
return num < 10 ? 1 : 1 + _num_digits(num / 10);
|
||||
}
|
||||
template <int N, int Digits = _num_digits(N)>
|
||||
constexpr auto num_name() {
|
||||
constexpr auto num_tstr() {
|
||||
char data[Digits + 1];
|
||||
int n = N;
|
||||
for (int i = Digits - 1; i >= 0; --i) {
|
||||
@ -42,7 +42,7 @@ namespace refl {
|
||||
return TStr{ data };
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto num_prefix_name() {
|
||||
constexpr auto num_prefix_tstr() {
|
||||
if constexpr (std::is_integral_v<T>) {
|
||||
if constexpr (std::is_signed_v<T>) {
|
||||
return TStr{ "S" };
|
||||
@ -60,7 +60,7 @@ namespace refl {
|
||||
}
|
||||
}
|
||||
template<auto v>
|
||||
constexpr auto value_name()noexcept {
|
||||
constexpr auto value_tstr()noexcept {
|
||||
using T = decltype(v);
|
||||
if constexpr (std::is_null_pointer_v<T>)
|
||||
return TStr{ "nullptr" };
|
||||
@ -95,13 +95,13 @@ namespace refl {
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto meta_name() noexcept {
|
||||
constexpr auto meta_tstr() noexcept {
|
||||
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)>();
|
||||
constexpr auto prefix = detail::num_prefix_tstr<T>();
|
||||
constexpr auto bit = detail::num_tstr<8 * sizeof(T)>();
|
||||
return concat_seq(prefix, bit);
|
||||
}
|
||||
else if constexpr (std::is_array_v<T>) {
|
||||
@ -109,20 +109,26 @@ namespace refl {
|
||||
constexpr auto ex = std::extent_v<T, 0>;
|
||||
if constexpr (r == 1) {
|
||||
if constexpr (ex == 0)
|
||||
return concat_seq(TStr{"[]{"}, meta_name<std::remove_extent_t<T>>(), TStr{"}"});
|
||||
return concat_seq(TStr{"[]{"}, meta_tstr<std::remove_extent_t<T>>(), TStr{"}"});
|
||||
else
|
||||
return concat_seq(TStr{"["}, detail::num_name<ex>(), TStr{"]{"}, meta_name<std::remove_extent_t<T>>(), TStr{"}"});
|
||||
return concat_seq(TStr{"["}, detail::num_tstr<ex>(), TStr{"]{"}, meta_tstr<std::remove_extent_t<T>>(), TStr{"}"});
|
||||
}
|
||||
else { // r > 1
|
||||
static_assert(r > 1);
|
||||
if constexpr (ex == 0)
|
||||
return concat_seq(TStr{"[]"}, type_name<std::remove_extent_t<T>>());
|
||||
else
|
||||
return concat_seq(TStr{"["}, detail::num_name<ex>(), TStr{"]"}, meta_name<std::remove_extent_t<T>>());
|
||||
return concat_seq(TStr{"["}, detail::num_tstr<ex>(), TStr{"]"}, meta_tstr<std::remove_extent_t<T>>());
|
||||
}
|
||||
}
|
||||
else {
|
||||
return detail::raw_meta_name<T>();
|
||||
return detail::raw_meta_tstr<T>();
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
Name meta_name() noexcept
|
||||
{
|
||||
auto view = meta_tstr<T>().view();
|
||||
return Name(view);
|
||||
}
|
||||
}
|
||||
@ -7,8 +7,6 @@
|
||||
namespace refl {
|
||||
using std::span;
|
||||
using pmr::Name;
|
||||
using pmr::CName;
|
||||
using pmr::FName;
|
||||
using pmr::table;
|
||||
namespace detail {
|
||||
// 定义一个模板结构体用于检测是否为 数组
|
||||
|
||||
@ -26,11 +26,11 @@ namespace refl {
|
||||
struct vtable_uclass
|
||||
{
|
||||
struct Node {
|
||||
size_t name;
|
||||
Name name;
|
||||
void* method;
|
||||
Node* next;
|
||||
Node(size_t name, void* ptr) :name(name), method(ptr), next(nullptr) {}
|
||||
Node* Insert(size_t name, void* ptr) {
|
||||
Node(Name name, void* ptr) :name(name), method(ptr), next(nullptr) {}
|
||||
Node* Insert(Name name, void* ptr) {
|
||||
Node* it = new Node(name, ptr);
|
||||
next = it;
|
||||
return it;
|
||||
@ -39,9 +39,6 @@ namespace refl {
|
||||
Node* header{nullptr};
|
||||
operator bool() { return header; }
|
||||
void Add(Name name, void* ptr) {
|
||||
Add(name.Hash(), ptr);
|
||||
}
|
||||
void Add(size_t name, void* ptr) {
|
||||
auto [bfind, it] = FindLast(name);
|
||||
if (bfind) {
|
||||
return;
|
||||
@ -50,7 +47,7 @@ namespace refl {
|
||||
Node** prev= it ? &(it->next) : &header;
|
||||
*prev = next;
|
||||
}
|
||||
std::pair<bool,Node*> FindLast(size_t name) const{
|
||||
std::pair<bool,Node*> FindLast(Name name) const{
|
||||
Node *prev = nullptr, *it = header;
|
||||
while (it) {
|
||||
if (it->name == name) {
|
||||
@ -61,7 +58,7 @@ namespace refl {
|
||||
}
|
||||
return std::make_pair(false, prev);
|
||||
}
|
||||
void* Find(size_t name) const {
|
||||
void* Find(Name name) const {
|
||||
Node* it = header;
|
||||
while (it) {
|
||||
if (it->name == name) {
|
||||
@ -81,25 +78,25 @@ namespace refl {
|
||||
using Construct_t = bool (*)(void* ptr, const UClass* cls,span<Any> ArgsList);
|
||||
using Destruct_t = void (*)(void*);
|
||||
void AddGetFields(GetFields_t func) {
|
||||
Add(string_hash("GetFields"), (void*)func);
|
||||
Add(Name("GetFields"), (void*)func);
|
||||
}
|
||||
void AddGetParams(GetParams_t func) {
|
||||
Add(string_hash("GetParams"), (void*)func);
|
||||
Add(Name("GetParams"), (void*)func);
|
||||
}
|
||||
void AddCall(Call_t func) {
|
||||
Add(string_hash("Call"), (void*)func);
|
||||
Add(Name("Call"), (void*)func);
|
||||
}
|
||||
void AddConstruct(Construct_t func) {
|
||||
Add(string_hash("Construct"), (void*)func);
|
||||
Add(Name("Construct"), (void*)func);
|
||||
}
|
||||
void AddDestruct(Destruct_t func) {
|
||||
Add(string_hash("Destruct"), (void*)func);
|
||||
Add(Name("Destruct"), (void*)func);
|
||||
}
|
||||
GetFields_t GetFields() const { return (GetFields_t) Find(string_hash("GetFields")); }
|
||||
GetParams_t GetParams() const { return (GetParams_t) Find(string_hash("GetParams")); }
|
||||
Call_t Call() const { return (Call_t) Find(string_hash("Call")); }
|
||||
Construct_t Construct() const { return (Construct_t) Find(string_hash("Construct")); }
|
||||
Destruct_t Destruct() const { return (Destruct_t) Find(string_hash("Destruct")); }
|
||||
GetFields_t GetFields() const { return (GetFields_t) Find(Name("GetFields")); }
|
||||
GetParams_t GetParams() const { return (GetParams_t) Find(Name("GetParams")); }
|
||||
Call_t Call() const { return (Call_t) Find(Name("Call")); }
|
||||
Construct_t Construct() const { return (Construct_t) Find(Name("Construct")); }
|
||||
Destruct_t Destruct() const { return (Destruct_t) Find(Name("Destruct")); }
|
||||
};
|
||||
class UClass {
|
||||
public:
|
||||
@ -111,7 +108,7 @@ namespace refl {
|
||||
UClass(const UClass*) = delete;
|
||||
UClass& operator=(const UClass*) = delete;
|
||||
public:
|
||||
UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
|
||||
UClass(Name name, uint32_t size, const UClass* parent = nullptr)
|
||||
:name(name), size(size), parent(parent) {}
|
||||
Any New(pmr::memory_resource* pool, span<Any> ArgsList = {}) const {
|
||||
void* ptr = pool->allocate(size);
|
||||
|
||||
@ -5,7 +5,7 @@ namespace refl {
|
||||
template<typename T>
|
||||
class UClass_Auto : public UClass {
|
||||
public:
|
||||
UClass_Auto() : UClass(meta_name<T>().view(), sizeof(T)) {
|
||||
UClass_Auto() : UClass(meta_name<T>(), sizeof(T)) {
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
using RT = std::remove_pointer_t<T>;
|
||||
flag |= CLASS_POINTER_FLAG;
|
||||
@ -38,7 +38,7 @@ namespace refl {
|
||||
using MethodType = R(*)(Args...);
|
||||
public:
|
||||
std::array<const UClass*, sizeof...(Args) + 1> UList{};
|
||||
UMethod_Auto() : UClass(meta_name<MethodType>().view(), sizeof(MethodType)) {
|
||||
UMethod_Auto() : UClass(meta_name<MethodType>(), sizeof(MethodType)) {
|
||||
flag = CLASS_TRIVIAL_FLAG;
|
||||
vtable.AddGetParams(&UMethod_Auto::GetParams);
|
||||
vtable.AddCall(&UMethod_Auto::Call);
|
||||
@ -137,7 +137,7 @@ namespace refl {
|
||||
memcpy(pit, &it, sizeof(it));
|
||||
pit->val = &*it;
|
||||
}
|
||||
UClass_Container() : UClass_Container_Impl(meta_name<T>().view(), sizeof(T)) {
|
||||
UClass_Container() : UClass_Container_Impl(meta_name<T>(), sizeof(T)) {
|
||||
parent = meta_info<value_type>();
|
||||
flag = CLASS_CONTAINER_FLAG;
|
||||
vtable.AddConstruct(&UClass_Container::construct);
|
||||
@ -164,7 +164,7 @@ namespace refl {
|
||||
using FieldsType = decltype(MetaImpl::MakeFields());
|
||||
public:
|
||||
FieldsType Fields{ MetaImpl::MakeFields() };
|
||||
UClass_Meta() : UClass(meta_name<T>().view(), sizeof(T)) {
|
||||
UClass_Meta() : UClass(meta_name<T>(), sizeof(T)) {
|
||||
if constexpr (has_parent_v<T>) {
|
||||
parent = meta_info<parent_t<T>>();
|
||||
}
|
||||
@ -281,8 +281,8 @@ namespace refl {
|
||||
inline const UClass* meta_info()
|
||||
{
|
||||
using T = real_type_t<Type>;
|
||||
constexpr auto name = meta_name<T>();
|
||||
if (auto cls = find_info(name.view())) {
|
||||
auto name = meta_name<T>();
|
||||
if (auto cls = find_info(name)) {
|
||||
return cls;
|
||||
}
|
||||
UClass* cls;
|
||||
@ -290,27 +290,27 @@ namespace refl {
|
||||
cls = new(MetaGlobalPool()) UClass_Meta<T, meta_t<T>>{};
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, void>) {
|
||||
cls = new(MetaGlobalPool()) UClass{ name.view(), 0 };
|
||||
cls = new(MetaGlobalPool()) UClass{ name, 0 };
|
||||
}
|
||||
else {
|
||||
cls = meta_info_impl<T>::create();
|
||||
}
|
||||
auto& ClassTable = UNIQUER_VAL(ClassTable);
|
||||
ClassTable[name.view()] = cls;
|
||||
ClassTable[name] = cls;
|
||||
return cls;
|
||||
}
|
||||
template<typename T, size_t hash>
|
||||
inline const UClass* meta_info()
|
||||
{
|
||||
if constexpr (have_meta_impl_v<T, hash>) {
|
||||
constexpr auto name = meta_name<T>();
|
||||
const UClass* cls = find_info(name.view(), hash);
|
||||
auto name = meta_name<T>();
|
||||
const UClass* cls = find_info(name, hash);
|
||||
if (cls) {
|
||||
return cls;
|
||||
}
|
||||
cls = new(MetaGlobalPool()) UClass_Meta<T, gen::MetaImpl<T, hash>>{};
|
||||
auto& MetaClassTable = UNIQUER_VAL(MetaClassTable);
|
||||
if (auto it = MetaClassTable.find(name.view()); it != MetaClassTable.end()) {
|
||||
if (auto it = MetaClassTable.find(name); it != MetaClassTable.end()) {
|
||||
auto meta = &it->second;
|
||||
while (meta) {
|
||||
if (!meta->next) {
|
||||
@ -321,7 +321,7 @@ namespace refl {
|
||||
}
|
||||
}
|
||||
else {
|
||||
MetaClassTable.emplace(name.view(), MetaClasses{hash, cls});
|
||||
MetaClassTable.emplace(name, MetaClasses{hash, cls});
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
|
||||
@ -6,3 +6,4 @@ header_component("zlib","engine")
|
||||
end
|
||||
add_syslinks("kernel32")
|
||||
set_pcheader("include/refl/pch.h")
|
||||
add_deps("xmalloc", {public = true})
|
||||
@ -29,7 +29,7 @@ function shared_module(name, owner, opt)
|
||||
set_group("Engine/"..owner.."__dyn")
|
||||
add_rules("engine.api")
|
||||
add_includedirs("include", {public = true})
|
||||
--add_rules("engine.plugin", {file = opt and opt.file or "include/" .. name .. "/module.h"})
|
||||
add_rules("engine.plugin", {file = opt and opt.file or "include/" .. name .. "/module.h"})
|
||||
end
|
||||
function add_dependency(...)
|
||||
add_deps(...)
|
||||
|
||||
@ -12,7 +12,6 @@ target("engine")
|
||||
set_group("Engine")
|
||||
add_rules("engine.api")
|
||||
add_files("src/engine/*.cpp")
|
||||
add_deps("xmalloc", {public = true})
|
||||
includes("xmake/xmake.lua")
|
||||
includes("3rdparty/xmake.lua")
|
||||
includes("tools/xmake.lua")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user