Compare commits

...

2 Commits

Author SHA1 Message Date
b4028d719f yaml bugfix 2024-11-22 22:26:06 +08:00
aab1d81925 name add 0x00 2024-11-20 21:18:48 +08:00
18 changed files with 234 additions and 34 deletions

View File

@ -1,6 +1,10 @@
metadatas:
- guid: 7dfa8412-3278-43f6-b332-ac09a132025f
- guid: 2b4239ff-796a-4b55-9d8f-272c80a16b17
name: ""
t_hash: "api::ShaderProgram\x06 mOwner!<21>/engine/assets/shader/simple.frag"
meta: ~
t_hash: api::ShaderProgram
meta:
__class__: api::ShaderProgram
__data__:
mOwner:
guid: 3585c167-9cff-4327-88db-d07601382640
includes: ~

View File

@ -1,6 +1,10 @@
metadatas:
- guid: 47c28b8c-f2aa-4357-a12d-7212de6e3a9e
- guid: 3890e4a2-7b6c-47d3-9bd2-578a50f8d684
name: ""
t_hash: "api::ShaderProgram\x06 mOwner!<21>/engine/assets/shader/simple.frag"
meta: ~
t_hash: api::ShaderProgram
meta:
__class__: api::ShaderProgram
__data__:
mOwner:
guid: 3585c167-9cff-4327-88db-d07601382640
includes: ~

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<!--
nvo- 仅数字值(即字节/字符不包括 ascii 表示)
x- 小写十六进制显示
b- bare-没有前导 0x -->
<Type Name="api::Guid">
<DisplayString>{{{Data1,nvoxb}-{Data2,nvoxb}-{Data3,nvoxb}-{Data4[0],nvoxb}{Data4[1],nvoxb}-{Data4[2],nvoxb}{Data4[3],nvoxb}{Data4[4],nvoxb}{Data4[5],nvoxb}{Data4[6],nvoxb}{Data4[7],nvoxb}}}</DisplayString>
</Type>
<Type Name="pmr::Name">
<!-- 显示 Name 的32位值 -->
<DisplayString>{g_memory_blocks[(flag3_memory29 >> 16) % 0x2000] + 2*(flag3_memory29 % 0x10000) + 2,s}</DisplayString>
</Type>
</AutoVisualizer>

View File

@ -140,6 +140,7 @@ namespace api {
return;
}
auto& res = it->second;
res.MetaDirty(true);
mDirtyBlock.push_back(&res);
}
void ResourceSystemImpl::SaveDirtyFile()

View File

@ -1,11 +1,13 @@
#include "asset/module.h"
#include "asset/resource_system.h"
#include "asset/asset_loader.h"
#include "archive/pch.h"
namespace api {
void AssetModule::OnLoad(int argc, char** argv)
{
AddSystem<ResourceSystem>();
AssetLoader::Init();
TextArchive::Register<Guid>();
}
void AssetModule::OnUnload()
{

View File

@ -1,4 +1,5 @@
#ifdef RegisterAny
RegisterAny(Name);
RegisterAny(string_view);
RegisterAny(int);
RegisterAny(unsigned int);

View File

@ -4,16 +4,16 @@ namespace gen {
template<>
inline bool YamlRead<refl::Any>(const YAML::Node& node, const refl::Any& t) {
if (!node) return false;
return api::YamlArchive::Deserialize(node, t);
return api::YamlArchive::Deserialize(node, refl::Any{ &t, refl::meta_info<refl::Any>() });
}
template<>
inline YAML::Node YamlWrite<refl::Any>(const refl::Any& t) {
return api::YamlArchive::Serialize(t);
return api::YamlArchive::Serialize(refl::Any{&t, refl::meta_info<refl::Any>()});
}
}
namespace YAML {
inline Node APILoad(std::string_view text) {
std::stringstream stream(text.data());
std::stringstream stream{ std::string(text) };
return Load(stream);
}
inline std::string_view APIDump(const Node& root) {
@ -22,8 +22,9 @@ namespace YAML {
const char* data = emitter.c_str();
size_t size = emitter.size();
// 在 FramePool 上分配内存并拷贝数据
char* buffer = static_cast<char*>(FramePool()->allocate(size, alignof(std::max_align_t)));
char* buffer = static_cast<char*>(FramePool()->allocate(size + 1, alignof(std::max_align_t)));
std::memcpy(buffer, data, size);
buffer[size] = 0x00;
// 返回指向缓冲区的 string_view
return std::string_view(buffer, size);
}

View File

@ -16,11 +16,8 @@ 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>();
else if constexpr (is_string_view_v<T> || is_string_v<T>) {
*(T*)(ptr) = node.Scalar();
}
else {
//static_assert(false, "unknown json read type");

View File

@ -19,16 +19,138 @@ namespace api {
auto uclass = meta_info<T>();
auto [bfind, it] = uclass->vtable.FindLast(VYamlSerdeRead());
if (!bfind && it) {
it = it->Insert(VYamlSerdeRead(), (void*)&gen::JsonSerde<T>::Read);
it = it->Insert(VYamlSerdeWrite(), (void*)&gen::JsonSerde<T>::Write);
it = it->Insert(VYamlSerdeRead(), (void*)&gen::YamlSerde<T>::Read);
it = it->Insert(VYamlSerdeWrite(), (void*)&gen::YamlSerde<T>::Write);
}
}
inline YAML::Node YamlArchive::Serialize(Any any)
{
if (!any) {
return YAML::Node();
}
inline bool YamlArchive::Deserialize(const YAML::Node& node, Any any)
auto it_func = any.FindVtable<YamlVTable::Write>(VYamlSerdeWrite());
if (it_func) {
return it_func(any.ptr);
}
YAML::Node result;
if (any.cls == meta_info<Any>()) {
Any obj = any.CastTo<Any>();
if (obj) {
result["__class__"] = obj.cls->name.ToStringView();
result["__data__"] = Serialize(obj);
}
return result;
}
if (any.IsContainer()) {
refl::Container docker(any);
bool isMap = any.IsMap();
auto fieldList = any.ContainerType()->GetFields(refl::FIND_ALL_MEMBER, Name(""));
for (auto obj : docker) {
if (isMap) {
Any first = obj.Member(fieldList[0]);
Any second = obj.Member(fieldList[1]);
result[Serialize(first)] = Serialize(second);
}
else {
result.push_back(Serialize(obj));
}
}
return result;
}
if (any.IsArray()) {
int n = any.ArraySize();
for (int i = 0; i < n; i++) {
result.push_back(Serialize(any.Member(i)));
}
return result;
}
if (Any p = any.Parent()) {
result["__parent__"] = Serialize(p);
}
auto fieldList = any.cls->GetFields(refl::FIND_ALL_MEMBER, Name(""));
for (auto& field : fieldList) {
YAML::Node child = Serialize(any.Member(field));
result[field.name.ToStringView()] = child;
}
return result;
}
inline bool YamlArchive::Deserialize(const YAML::Node& res, Any any)
{
if (!any) {
return false;
}
auto it_func = any.FindVtable<YamlVTable::Read>(VYamlSerdeRead());
if (it_func) {
return it_func(res, any.ptr);
}
if (any.cls == meta_info<Any>() && res) {
auto __class = res["__class__"];
if (!__class) {
return false;
}
auto name = __class.Scalar();
auto cls = refl::find_info(name);
if (cls) {
Any obj = cls->New(FramePool());
*any.CastTo<Any*>() = obj;
return Deserialize(res["__data__"], obj);
}
*any.CastTo<Any*>() = {};
return false;
}
if (any.IsContainer()) {
refl::Container docker(any);
docker.construct();
Any any = docker.malloc(FramePool());
bool isMap = res.IsMap() && any.IsMap();
Any first, second;
if (isMap) {
auto fieldList = any.ContainerType()->GetFields(refl::FIND_ALL_MEMBER, Name(""));
first = any.Member(fieldList[0]);
second = any.Member(fieldList[1]);
}
for (auto it : res) {
if (isMap) {
Deserialize(it.first, first);
Deserialize(it.second, second);
}
else {
Deserialize(it, any);
}
docker.insert(any);
any.Destruct();
}
return true;
}
if (res.IsSequence() && any.IsArray()) {
for (std::size_t i = 0; i < res.size(); i++) {
Deserialize(res[i], any.Member(i));
}
return true;
}
if (res.IsMap() && any.IsObject()) {
auto fieldList = any.cls->GetFields(refl::FIND_ALL_MEMBER, Name(""));
auto rt = res.begin();
int diff = res.size() - fieldList.size();
if (diff > 1 || (diff == 1 && !any.HasParent())) {
return false;
}
if (diff == 1) {
Deserialize(rt++->second, any.Parent());
}
auto ft = fieldList.begin();
for (; ft != fieldList.end() && rt != res.end(); ++ft, ++rt) {
if (ft->name != Name(rt->first.Scalar())) {
return false;
}
Deserialize(rt->second, any.Member(*ft));
}
return true;
}
if (res.IsScalar() && any.IsObject()) {
const std::string& str = res.Scalar();
return any.Construct(Any{ str });
}
return false;
}
}

View File

@ -27,7 +27,7 @@ namespace api {
void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx)
{
if (!shader) {
shader = ResourceSystem::Ptr()->LoadEmplaceResource<Shader>();
shader = ResourceSystem::Ptr()->LoadEmplaceResource<Shader>(Guid("3585c167-9cff-4327-88db-d07601382640"));
shader->Name("api::PosVertex");
shader->ubName("api::ubSimple");
auto vert = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.vert");

View File

@ -68,6 +68,11 @@ namespace pmr {
void SetStringEntryHeader(StringEntryHeader _stringEntryHeader) {
stringEntryHeader = _stringEntryHeader;
}
void SetStringData(const char* str, uint16_t size) {
memcpy(data, str, size);
data[size] = 0x00;
}
uint16_t GetSize()const { return stringEntryHeader.GetSize(); }
const char* GetData() const { return data; };
};
struct HashInfo {
@ -151,6 +156,7 @@ namespace pmr {
static constexpr uint32_t ALIGN_BYTES = 2u;
static constexpr uint32_t MAX_MEMORY_BLOCK_SIZE = (1u << 16u) * 2u;
private:
std::array<SlotPool, MAX_SLOT_POOL_ARRAY_SIZE> slotPoolArray;
uint16_t currentMemoryBlockIndex;
uint16_t currentMemoryBlockAlignedCursor;
char* memoryBlockArray[MAX_MEMORY_BLOCK_ARRAY_SIZE];
@ -162,9 +168,8 @@ namespace pmr {
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")
inline static char** g_memory_blocks = nullptr;
UNIQUER_INLINE_STATIC(StringEntryMemoryManager, stringEntryMemoryManager, "pmr::name::stringEntryMemoryManager")
uint32_t flag3_memory29;
public:
Name()noexcept : flag3_memory29(0) {};
@ -196,14 +201,14 @@ namespace pmr {
{
if (!flag3_memory29)return "";
const StringEntry* stringEntry = UNIQUER_VAL(stringEntryMemoryManager).GetStringEntry(StringEntryHandle(flag3_memory29));
return std::string_view(stringEntry->GetData(), stringEntry->GetStringEntryHeader().GetSize());
return std::string_view(stringEntry->GetData(), stringEntry->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());
return std::string(stringEntry->GetData(), stringEntry->GetSize());
}
};
}

View File

@ -64,7 +64,7 @@ namespace pmr {
const Name::Slot& oldSlot = oldSlotArray[slotIndex];
StringEntry* stringEntry = stringEntryMemoryManager.GetStringEntry(oldSlotArray[slotIndex].GetStringEntryHandle());
const HashInfo hashInfo(std::string_view(stringEntry->GetData(), stringEntry->GetStringEntryHeader().GetSize()));
const HashInfo hashInfo(std::string_view(stringEntry->GetData(), stringEntry->GetSize()));
Name::Slot& slot = FindUnusedSlot(hashInfo);
@ -75,7 +75,6 @@ namespace pmr {
}
inline Name::StringEntryMemoryManager::StringEntryMemoryManager()
{
auto& slotPoolArray = UNIQUER_VAL(slotPoolArray);
for (auto& slotPool : slotPoolArray)
{
slotPool.size = 0;
@ -83,6 +82,7 @@ namespace pmr {
slotPool.slotArray = (Slot*)(xmalloc(SlotPool::SLOT_POOL_INITIALIZE_SIZE * sizeof(Slot)));
std::memset(slotPool.slotArray, 0, SlotPool::SLOT_POOL_INITIALIZE_SIZE);
}
g_memory_blocks = memoryBlockArray;
currentMemoryBlockIndex = 0;
currentMemoryBlockAlignedCursor = 0;
memoryBlockArray[0] = (char*)(xmalloc(MAX_MEMORY_BLOCK_SIZE));
@ -94,7 +94,7 @@ namespace pmr {
}
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 size = meta_align_size(sizeof(StringEntryHeader) + stringEntryHeader.GetSize() + 1, ALIGN_BYTES);
const uint32_t alignedSize = size >> 1;
StringEntryHandle stringEntryHandle{};
@ -112,8 +112,7 @@ namespace pmr {
StringEntry* stringEntry = GetStringEntry(stringEntryHandle);
stringEntry->SetStringEntryHeader(stringEntryHeader);
memcpy(const_cast<char*>(stringEntry->GetData()), data, stringEntryHeader.GetSize());
stringEntry->SetStringData(data, stringEntryHeader.GetSize());
return stringEntryHandle;
}
inline void Name::StringEntryMemoryManager::CreateNewMemoryBlock()
@ -132,7 +131,8 @@ namespace pmr {
return 0u;
}
HashInfo hashInfo(view);
auto& slotPool = UNIQUER_VAL(slotPoolArray)[0];
auto& stringEntryMemoryManager = UNIQUER_VAL(stringEntryMemoryManager);
auto& slotPool = stringEntryMemoryManager.slotPoolArray[hashInfo.GetSlotPoolIndex()];
uint32_t slotValue = 0u;
{
std::unique_lock<std::mutex> lock(slotPool.mutex);
@ -141,7 +141,7 @@ namespace pmr {
if (!slot.IsUsed())
{
slotPool.size++;
StringEntryHandle stringEntryHandle = UNIQUER_VAL(stringEntryMemoryManager).AllocateStringEntry(hashInfo.GetStringEntryHeader(), hashInfo.GetData());
StringEntryHandle stringEntryHandle = stringEntryMemoryManager.AllocateStringEntry(hashInfo.GetStringEntryHeader(), hashInfo.GetData());
slot.Load(hashInfo.GetSlotHashProbe<IS_USED_MASK>(), stringEntryHandle);
}
slotValue = slot.GetSlotValue();

View File

@ -41,16 +41,25 @@ namespace refl {
template<typename T>
T FindVtable(Name name)const;
bool Construct(span<Any> ArgsList) const;
void Destruct()const;
Any New(pmr::memory_resource* pool)const;
Any Member(const FieldPtr& field)const;
Any Member(int i)const;
Any Parent()const;
bool HasParent()const;
bool IsArray()const;
bool IsObject()const;
bool IsContainer()const;
bool IsSequence()const;
bool IsMap()const;
const UClass* ContainerType()const;
int ArraySize()const;
void CopyTo(void* ptr)const;
void MoveTo(void* ptr)const {
CopyTo(ptr);
Destruct();
}
};
}

View File

@ -2,6 +2,10 @@
#include "uclass.h"
#include "convert.h"
namespace refl{
inline bool Any::HasParent() const
{
return cls->flag & CLASS_PARENT_FLAG;
}
inline bool Any::IsArray() const
{
return cls->flag & CLASS_ARRAY_FLAG;
@ -22,6 +26,29 @@ namespace refl{
{
return cls->flag & CLASS_MAP_FLAG;
}
inline const UClass* Any::ContainerType() const
{
if (IsContainer()) {
return cls->parent;
}
return nullptr;
}
inline int Any::ArraySize() const
{
if (cls->flag & CLASS_ARRAY_FLAG) {
return cls->size / cls->parent->size;
}
return 0;
}
inline void Any::CopyTo(void* ptr) const
{
Any to{ ptr, cls };
auto fieldList = cls->GetFields(refl::FIND_ALL_MEMBER, Name(""));
for (auto field : fieldList) {
Any obj = to.Member(field);
Convert::Construct(obj, Member(field));
}
}
inline bool Any::Check(const UClass* parent)const
{
if (cls == parent) {
@ -36,6 +63,10 @@ namespace refl{
{
return cls->Construct((void*)ptr, ArgsList);
}
inline void Any::Destruct() const
{
cls->Destruct((void*)ptr);
}
inline Any Any::New(pmr::memory_resource* pool) const
{
void* data = pool->allocate(cls->size);

View File

@ -12,6 +12,11 @@ namespace refl {
operator Any()const{
return Any{ ptr, cls };
}
Any malloc(pmr::memory_resource* alloc)const {
void* it = alloc->allocate(cls->parent->size);
cls->Construct(it);
return Any{ it, cls };
}
span<const FieldPtr> GetFields() {
return cls->parent->GetFields(EFieldFind::FIND_ALL_MEMBER, Name(""));
}

View File

@ -26,6 +26,9 @@ namespace vkn {
auto shader_stage = GlslToSpirv::GetShaderStage(shader_kind);
auto program = m ? ResourceSystem::Ptr()->LoadEmplaceResource<vkShaderProgram>(m->guid, shader_stage)
: ResourceSystem::Ptr()->LoadEmplaceResource<vkShaderProgram>(shader_stage);
if (m && m->meta) {
m->meta.MoveTo(program.Ptr());
}
FileHandle handle(path);
if (!handle.Open(FILE_OP::READ, mFileFlag & FileFlag::File_Binary)) {
return program;

View File

@ -7,6 +7,7 @@ target("editor")
add_files("src/editor/*.cpp")
target("engine")
add_defines("ENGINE_ROOT="..os.curdir():gsub("\\", "\\\\"),{public = false})
add_headerfiles("include/*.natvis")
add_includedirs("include", {public = true})
set_kind("shared")
set_group("Engine")

View File

@ -3,6 +3,6 @@ rule("engine.plugin")
on_config(function (target)
import("make_plugin")
local file = target:extraconf("rules", "engine.plugin", "file")
make_plugin(target, file or "module.h")
--make_plugin(target, file or "module.h")
end)