diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-20 21:08:19 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-20 21:08:19 -0400 |
| commit | 40d69e7e40a18865a31af2f55efcde369d36dbbb (patch) | |
| tree | 95a2cbbe40192183d13f846f3444b32d7e12b0e8 /src | |
| parent | ead9e484db969a880470d625b1884aced296e722 (diff) | |
pke: serialization overhaul + embedded assets
Diffstat (limited to 'src')
| -rw-r--r-- | src/asset-manager.cpp | 38 | ||||
| -rw-r--r-- | src/asset-manager.hpp | 8 | ||||
| -rw-r--r-- | src/ecs.cpp | 10 | ||||
| -rw-r--r-- | src/ecs.hpp | 1 | ||||
| -rw-r--r-- | src/entities.cpp | 14 | ||||
| -rw-r--r-- | src/font.cpp | 530 | ||||
| -rw-r--r-- | src/font.hpp | 4 | ||||
| -rw-r--r-- | src/game.cpp | 20 | ||||
| -rw-r--r-- | src/serialization-component.cpp | 2 | ||||
| -rw-r--r-- | src/serialization-font.cpp | 140 | ||||
| -rw-r--r-- | src/serialization-font.hpp | 2 | ||||
| -rw-r--r-- | src/serialization-static-ui.cpp | 294 | ||||
| -rw-r--r-- | src/serialization.cpp | 66 | ||||
| -rw-r--r-- | src/serialization.hpp | 16 | ||||
| -rw-r--r-- | src/static-ui.cpp | 66 | ||||
| -rw-r--r-- | src/static-ui.hpp | 19 | ||||
| -rw-r--r-- | src/vendor-pkh-include.cpp | 2 |
17 files changed, 684 insertions, 548 deletions
diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp index 2976643..b7a82fd 100644 --- a/src/asset-manager.cpp +++ b/src/asset-manager.cpp @@ -46,10 +46,11 @@ void AM_Load_Task(Asset &asset) { return; } asset.size = std::filesystem::file_size(asset.basePath); - asset.ptr = pk_new_base(asset.size, alignof(max_align_t)); + void *ptr = pk_new_base(asset.size, alignof(max_align_t)); file.seekg(0, std::ios::beg); - file.read(static_cast<char *>(asset.ptr), asset.size); + file.read(static_cast<char *>(ptr), asset.size); file.close(); + asset.ptr = ptr; asset.state = PKE_ASSET_LOADING_STATE_LOADED; } @@ -85,8 +86,9 @@ AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t strncpy(asset.key, key, AssetKeyLength); asset.basePath = nullptr; asset.size = size; - asset.ptr = pk_new_base(size, alignment); - memcpy(asset.ptr, data, size); + void *ptr = pk_new_base(size, alignment); + memcpy(ptr, data, size); + asset.ptr = ptr; asset.state = PKE_ASSET_LOADING_STATE_LOADED; asset.type = type; return assetHandle; @@ -149,6 +151,28 @@ AssetHandle AM_Register(const char *path, AssetType type) { return assetHandle; } +AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, int64_t size) { + assert(data != nullptr && "Attempt to register invalid asset data"); + assert(data != CAFE_BABE(void) && "Attempt to register invalid asset data"); + assert(size != 0 && "Attempt to register asset data of size 0"); + Asset *searchedAsset = AM_Get_Inner(key); + if (searchedAsset != nullptr) { + return searchedAsset->handle; + } + AssetHandle assetHandle{Buckets_NewHandle(Asset_BucketContainer)}; + Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; + new (&asset) Asset{}; + asset.handle = assetHandle; + strncpy(asset.key, key, AssetKeyLength); + asset.basePath = nullptr; + asset.size = size; + asset.ptr = data; + asset.state = PKE_ASSET_LOADING_STATE_LOADED; + asset.type = type; + asset.flags = PKE_ASSET_FLAGS_MEM_STATIC; + return assetHandle; +} + void AM_Release(AssetHandle assetHandle) { assert(assetHandle != AssetHandle_MAX); Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; @@ -243,9 +267,11 @@ void AM_GC() { for (long b = 0; b <= Asset_BucketContainer.pkeHandle.bucketIndex; ++b) { for (long i = 0; i < Asset_BucketContainer.pkeHandle.itemIndex; ++i) { Asset &asset = Asset_BucketContainer.buckets[b][i]; - if (asset.referenceCount > 0) + if (asset.referenceCount > 0) { + fprintf(stderr, "[AM_GC] Asset '%.16s' still in use, count: %i", asset.key, asset.referenceCount); continue; - if (asset.ptr != nullptr && asset.ptr != CAFE_BABE(void)) { + } + if (asset.ptr != nullptr && asset.ptr != CAFE_BABE(void) && !PK_HAS_FLAG(asset.flags, PKE_ASSET_FLAGS_MEM_STATIC)) { pk_delete_base(asset.ptr, asset.size); } asset.size = 0; diff --git a/src/asset-manager.hpp b/src/asset-manager.hpp index ec98d08..5106375 100644 --- a/src/asset-manager.hpp +++ b/src/asset-manager.hpp @@ -12,6 +12,7 @@ constexpr AssetHandle AssetHandle_MAX = AssetHandle{ pk_handle_MAX_constexpr }; TypeSafeInt_constexpr(AssetLoadingState, uint8_t, 0xFF); TypeSafeInt_constexpr(AssetType, uint8_t, 0xFF); +TypeSafeInt_constexpr(AssetFlags, uint8_t, 0xFF); const int64_t AssetKeyLength = 16; using AssetKey = char[AssetKeyLength]; @@ -29,6 +30,9 @@ const AssetType PKE_ASSET_TYPE_AUDIO = AssetType {0x08}; const AssetType PKE_ASSET_TYPE_FONT = AssetType {0x10}; const AssetType PKE_ASSET_TYPE_ALL = AssetType {0xFF}; +const AssetFlags PKE_ASSET_FLAGS_NONE = AssetFlags {0x00}; +const AssetFlags PKE_ASSET_FLAGS_MEM_STATIC = AssetFlags {0x01}; + constexpr int64_t EngineDefinedAssetCount = 8; extern AssetKey EngineDefinedAssets[EngineDefinedAssetCount]; @@ -37,17 +41,19 @@ struct Asset { AssetKey key = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'}; const char *basePath = nullptr; int64_t size = 0; - void *ptr = nullptr; + const void *ptr = nullptr; std::future<void> future; int8_t referenceCount = 0; AssetLoadingState state = PKE_ASSET_LOADING_STATE_UNLOADED; AssetType type = PKE_ASSET_TYPE_UNSET; + AssetFlags flags = PKE_ASSET_FLAGS_NONE; }; void AM_Init(); AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t size, std::size_t alignment); AssetHandle AM_Register(const char *path, AssetType type); AssetHandle AM_Register(AssetKey key, AssetType type, const char *path); +AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, int64_t size); void AM_Release(AssetHandle assetHandle); const Asset *AM_Get(AssetHandle assetHandle); const AssetHandle AM_GetHandle(AssetKey key); diff --git a/src/ecs.cpp b/src/ecs.cpp index d029b18..9d0245e 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -105,6 +105,16 @@ Entity_Base *ECS_GetEntity(EntityHandle handle) { return ecs.bc.entityPtrs[handle]; } +Entity_Base *ECS_GetEntityByUUID(pk_uuid uuid) { + for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.entityPtrs.pkeHandle.bucketIndex; ++b) { + for (pk_handle_item_index_T i = 0; i < ecs.bc.entityPtrs.pkeHandle.itemIndex; ++i) { + Entity_Base *bs = ecs.bc.entityPtrs.buckets[b][i]; + if (bs->uuid == uuid) return bs; + } + } + return nullptr; +} + void ECS_MarkForRemoval(Entity_Base *entity) { assert(entity->handle != EntityHandle_MAX && "Attempting to remove invalid entity"); assert(entity->isMarkedForRemoval == false && "Entity already marked for removal"); diff --git a/src/ecs.hpp b/src/ecs.hpp index b25fdb7..a934fa2 100644 --- a/src/ecs.hpp +++ b/src/ecs.hpp @@ -17,6 +17,7 @@ void ECS_Tick_Late(double delta); Entity_Base *ECS_CreateGenericEntity(); EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEnt = nullptr); Entity_Base *ECS_GetEntity(EntityHandle handle); +Entity_Base *ECS_GetEntityByUUID(pk_uuid uuid); void ECS_MarkForRemoval(Entity_Base *entity); void ECS_HandleCollision(CompInstance *lhs, CompInstance *rhs); diff --git a/src/entities.cpp b/src/entities.cpp index 860907c..1ffecb3 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -343,7 +343,7 @@ void EntityType_PreLoad(EntityType_LoadHelperStruct &helper) { btConvexHullShape *shape; { shape = pk_new<btConvexHullShape>(MemBkt_Bullet); - btScalar *vertDataPointer = reinterpret_cast<btScalar *>(helper.modelBinAsset->ptr); + btScalar *vertDataPointer = reinterpret_cast<btScalar *>(const_cast<void *>(helper.modelBinAsset->ptr)); /* TODO JCB - 2024-01-02 * we shouldn't assume that the first index is the vertexes */ @@ -438,7 +438,7 @@ void EntityType_PreLoad(EntityType_LoadHelperStruct &helper) { etdHelper.textureAssetHandle = AssetHandle{AM_GetHandle(etd.textureAssetKey)}; if (etdHelper.textureAssetHandle != AssetHandle_MAX) { etdHelper.textureAsset = AM_Get(etdHelper.textureAssetHandle); - stbi_uc *pixels = stbi_load_from_memory(static_cast<stbi_uc *>(etdHelper.textureAsset->ptr), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); + stbi_uc *pixels = stbi_load_from_memory(static_cast<stbi_uc *>(const_cast<void *>(etdHelper.textureAsset->ptr)), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); assert(pixels != nullptr && "sbti_load failed to load image."); stbi_image_free(pixels); } else { @@ -515,7 +515,7 @@ void EntityType_LoadTexture(EntityType_LoadHelperStruct &helper, const int64_t i int32_t pixelWidth, pixelHeight, pixelChannels; stbi_uc *pixels = nullptr; if (etdHelper.textureAssetHandle != AssetHandle_MAX) { - pixels = stbi_load_from_memory(static_cast<stbi_uc *>(etdHelper.textureAsset->ptr), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); + pixels = stbi_load_from_memory(static_cast<stbi_uc *>(const_cast<void *>(etdHelper.textureAsset->ptr)), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha); assert(pixels != nullptr && "sbti_load failed to load image."); } else { pixelWidth = 2; @@ -827,19 +827,19 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh char *srcPtr = nullptr; dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetVert; - srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accVert.buffer_view->offset; + srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accVert.buffer_view->offset; memcpy(dstPtr, srcPtr, accVert.buffer_view->size); dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetNorm; - srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accNorm.buffer_view->offset; + srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accNorm.buffer_view->offset; memcpy(dstPtr, srcPtr, accNorm.buffer_view->size); dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetUV; - srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accUV.buffer_view->offset; + srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accUV.buffer_view->offset; memcpy(dstPtr, srcPtr, accUV.buffer_view->size); dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetIndex; - srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accIndex.buffer_view->offset; + srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accIndex.buffer_view->offset; memcpy(dstPtr, srcPtr, accIndex.buffer_view->size); VkCommandBufferBeginInfo vkCommandBufferBeginInfo; diff --git a/src/font.cpp b/src/font.cpp index c94890b..380827b 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -8,6 +8,7 @@ #include "vendor-stb-image-include.h" #include "game-settings.hpp" #include "ecs.hpp" +#include "../embed/embedded-fonts.h" #include <vulkan/vulkan_core.h> @@ -253,6 +254,21 @@ void FontType_Init() { ft->glyphs = nullptr; ft->renders = nullptr; } + AssetKey ak_img = "fnt_mquin_img\0\0"; + AssetKey ak_glyphs = "fnt_mquin_gly\0\0"; + AssetHandle ah_img = AM_Register_Static(ak_img, PKE_ASSET_TYPE_TEXTURE, embedded_fonts[0].data, embedded_fonts[0].size); + AssetHandle ah_glyphs = AM_Register_Static(ak_glyphs, PKE_ASSET_TYPE_UNSET, embedded_fonts[1].data, embedded_fonts[1].size); + FontTypeMSDFSettings msdf_s; + msdf_s.minimum_scale = 144; + msdf_s.px_range = 4; + FontTypeSpacing spacing; + spacing.geometry_scale = 0.0625; + spacing.em_size = 1; + spacing.ascender_y = 0.875; + spacing.descender_y = -0.125; + spacing.line_height = 1.125; + spacing.underline_y = 0.0625; + FontType_RegisterFont(cstring_to_pk_cstr("fnt_mquin_7y"), ah_img, ah_glyphs, &msdf_s, &spacing); } void FontType_Teardown() { @@ -471,6 +487,11 @@ void FontType_Deserialize(std::istream &stream) { } } +FontType* FontType_Get(FontTypeIndex idx) { + assert(idx < ftd.h_ft); + return &ftd.arr_ft[static_cast<FontTypeIndex_T>(idx)]; +} + FontType* FontType_GetFonts(FontTypeIndex &count) { count = ftd.h_ft; return ftd.arr_ft; @@ -524,116 +545,124 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle ft->atlas_size.x = (float)txtr_x; ft->atlas_size.y = (float)txtr_y; - // buffers + ECS_CreateEntity(ft); - glm::vec2 atlas_size_buffer[4]; - for (int i = 0; i < 4; ++i) { - atlas_size_buffer[i] = ft->atlas_size; - } + if (window != NULL) { - pkvk_buffer_create_data create_data{}; - create_data.buffer_byte_length[0] = sizeof(pkeIntrinsicsPlane.vert[0]) * 4; - create_data.buffer_byte_length[1] = sizeof(pkeIntrinsicsPlane.uv[0]) * 4; - create_data.buffer_byte_length[2] = sizeof(atlas_size_buffer[0]) * 4; - create_data.buffer_byte_length[3] = sizeof(pkeIntrinsicsPlane.index[0]) * 6; - create_data.buffer_byte_length[4] = sizeof(FontInstanceBufferItem); - create_data.src_data[0] = &pkeIntrinsicsPlane.vert; - create_data.src_data[1] = &pkeIntrinsicsPlane.uv; - create_data.src_data[2] = &atlas_size_buffer; - create_data.src_data[3] = &pkeIntrinsicsPlane.index; - create_data.src_data[4] = nullptr; - create_data.n_buffers = 5; - create_data.index_index = 3; - create_data.index_instance = 4; - - pkvk_buffer_create_data_out out{}; - pkvk_buffer_create(&create_data, &out); - - ft->bindings.bd_vertex.buffer = out.buffers[0]; - ft->bindings.bd_vertex.firstBinding = 0; - ft->bindings.bd_vertex.bindingCount = 1; - ft->bindings.bd_uv.buffer = out.buffers[1]; - ft->bindings.bd_uv.firstBinding = 1; - ft->bindings.bd_uv.bindingCount = 1; - ft->bindings.bd_atlas_size.buffer = out.buffers[2]; - ft->bindings.bd_atlas_size.firstBinding = 2; - ft->bindings.bd_atlas_size.bindingCount = 1; - ft->bindings.bd_index.buffer = out.buffers[3]; - ft->bindings.bd_index.firstBinding = 0; - ft->bindings.bd_index.bindingCount = 1; - ft->bindings.index_count = 6; - ft->bindings.bd_instance.buffer = out.buffers[4]; - ft->bindings.bd_instance.firstBinding = 3; - ft->bindings.bd_instance.bindingCount = 1; - ft->gr.deviceMemoryVert = out.device_memory_vertex; - ft->gr.deviceMemoryInst = out.device_memory_instance; - - ft->bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(FontInstanceBufferItem); - - // texture - - pkvk_texture_upload_data txtr_data{}; - txtr_data.bytes = txtr_bytes; - txtr_data.n_bytes = imageSizeBytes; - txtr_data.width = (uint32_t)txtr_x; - txtr_data.height = (uint32_t)txtr_y; - - pkvk_texture_upload_data_out txtr_out{}; - pkvk_texture_upload(&txtr_data, &txtr_out); - - ft->gr.textureImage = txtr_out.image; - ft->gr.textureImageView = txtr_out.image_view; - ft->gr.deviceMemoryTexture = txtr_out.device_memory; - - free(txtr_bytes); - - /* - * Vulkan descriptor sets - */ - VkDescriptorPoolSize descriptorPoolSizes[1]; - descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptorPoolSizes[0].descriptorCount = (uint32_t)1; - - VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo; - vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - vkDescriptorPoolCreateInfo.pNext = nullptr; - vkDescriptorPoolCreateInfo.flags = 0; - vkDescriptorPoolCreateInfo.maxSets = (uint32_t)1; - vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)1; - vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes; - - // consider making me a global pool - vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &ft->gr.vkDescriptorPool); - assert(vkResult == VK_SUCCESS); - - VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo; - vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - vkDescriptorSetAllocateInfo.pNext = nullptr; - vkDescriptorSetAllocateInfo.descriptorPool = ft->gr.vkDescriptorPool; - vkDescriptorSetAllocateInfo.descriptorSetCount = (uint32_t)1; - vkDescriptorSetAllocateInfo.pSetLayouts = &pkePipelines.descr_layouts.named.txtr; - - vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, &ft->gr.vkDescriptorSet); - assert(vkResult == VK_SUCCESS); - - VkDescriptorImageInfo textureDescriptorInfo; - textureDescriptorInfo.sampler = global_sampler; - textureDescriptorInfo.imageView = ft->gr.textureImageView; - textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkWriteDescriptorSet writeDescriptorSet; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.pNext = nullptr; - writeDescriptorSet.dstSet = ft->gr.vkDescriptorSet; - writeDescriptorSet.dstBinding = (uint32_t)0; - writeDescriptorSet.dstArrayElement = (uint32_t)0; - writeDescriptorSet.descriptorCount = (uint32_t)1; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writeDescriptorSet.pImageInfo = &textureDescriptorInfo; - writeDescriptorSet.pBufferInfo = nullptr; - writeDescriptorSet.pTexelBufferView = nullptr; - - vkUpdateDescriptorSets(vkDevice, (uint32_t)1, &writeDescriptorSet, 0, nullptr); + // buffers + + glm::vec2 atlas_size_buffer[4]; + for (int i = 0; i < 4; ++i) { + atlas_size_buffer[i] = ft->atlas_size; + } + + pkvk_buffer_create_data create_data{}; + create_data.buffer_byte_length[0] = sizeof(pkeIntrinsicsPlane.vert[0]) * 4; + create_data.buffer_byte_length[1] = sizeof(pkeIntrinsicsPlane.uv[0]) * 4; + create_data.buffer_byte_length[2] = sizeof(atlas_size_buffer[0]) * 4; + create_data.buffer_byte_length[3] = sizeof(pkeIntrinsicsPlane.index[0]) * 6; + create_data.buffer_byte_length[4] = sizeof(FontInstanceBufferItem); + create_data.src_data[0] = &pkeIntrinsicsPlane.vert; + create_data.src_data[1] = &pkeIntrinsicsPlane.uv; + create_data.src_data[2] = &atlas_size_buffer; + create_data.src_data[3] = &pkeIntrinsicsPlane.index; + create_data.src_data[4] = nullptr; + create_data.n_buffers = 5; + create_data.index_index = 3; + create_data.index_instance = 4; + + pkvk_buffer_create_data_out out{}; + pkvk_buffer_create(&create_data, &out); + + ft->bindings.bd_vertex.buffer = out.buffers[0]; + ft->bindings.bd_vertex.firstBinding = 0; + ft->bindings.bd_vertex.bindingCount = 1; + ft->bindings.bd_uv.buffer = out.buffers[1]; + ft->bindings.bd_uv.firstBinding = 1; + ft->bindings.bd_uv.bindingCount = 1; + ft->bindings.bd_atlas_size.buffer = out.buffers[2]; + ft->bindings.bd_atlas_size.firstBinding = 2; + ft->bindings.bd_atlas_size.bindingCount = 1; + ft->bindings.bd_index.buffer = out.buffers[3]; + ft->bindings.bd_index.firstBinding = 0; + ft->bindings.bd_index.bindingCount = 1; + ft->bindings.index_count = 6; + ft->bindings.bd_instance.buffer = out.buffers[4]; + ft->bindings.bd_instance.firstBinding = 3; + ft->bindings.bd_instance.bindingCount = 1; + ft->gr.deviceMemoryVert = out.device_memory_vertex; + ft->gr.deviceMemoryInst = out.device_memory_instance; + + ft->bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(FontInstanceBufferItem); + + // texture + + pkvk_texture_upload_data txtr_data{}; + txtr_data.bytes = txtr_bytes; + txtr_data.n_bytes = imageSizeBytes; + txtr_data.width = (uint32_t)txtr_x; + txtr_data.height = (uint32_t)txtr_y; + + pkvk_texture_upload_data_out txtr_out{}; + pkvk_texture_upload(&txtr_data, &txtr_out); + + ft->gr.textureImage = txtr_out.image; + ft->gr.textureImageView = txtr_out.image_view; + ft->gr.deviceMemoryTexture = txtr_out.device_memory; + + free(txtr_bytes); + + /* + * Vulkan descriptor sets + */ + VkDescriptorPoolSize descriptorPoolSizes[1]; + descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorPoolSizes[0].descriptorCount = (uint32_t)1; + + VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo; + vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + vkDescriptorPoolCreateInfo.pNext = nullptr; + vkDescriptorPoolCreateInfo.flags = 0; + vkDescriptorPoolCreateInfo.maxSets = (uint32_t)1; + vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)1; + vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes; + + // consider making me a global pool + vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &ft->gr.vkDescriptorPool); + assert(vkResult == VK_SUCCESS); + + VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo; + vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + vkDescriptorSetAllocateInfo.pNext = nullptr; + vkDescriptorSetAllocateInfo.descriptorPool = ft->gr.vkDescriptorPool; + vkDescriptorSetAllocateInfo.descriptorSetCount = (uint32_t)1; + vkDescriptorSetAllocateInfo.pSetLayouts = &pkePipelines.descr_layouts.named.txtr; + + vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, &ft->gr.vkDescriptorSet); + assert(vkResult == VK_SUCCESS); + + VkDescriptorImageInfo textureDescriptorInfo; + textureDescriptorInfo.sampler = global_sampler; + textureDescriptorInfo.imageView = ft->gr.textureImageView; + textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkWriteDescriptorSet writeDescriptorSet; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.pNext = nullptr; + writeDescriptorSet.dstSet = ft->gr.vkDescriptorSet; + writeDescriptorSet.dstBinding = (uint32_t)0; + writeDescriptorSet.dstArrayElement = (uint32_t)0; + writeDescriptorSet.descriptorCount = (uint32_t)1; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSet.pImageInfo = &textureDescriptorInfo; + writeDescriptorSet.pBufferInfo = nullptr; + writeDescriptorSet.pTexelBufferView = nullptr; + + vkUpdateDescriptorSets(vkDevice, (uint32_t)1, &writeDescriptorSet, 0, nullptr); + + } else { + free(txtr_bytes); + } AM_Release(fontTextureHandle); AM_Release(glyphsHandle); @@ -727,6 +756,7 @@ void FontType_Unload(FontTypeIndex idx) { ft->title.val = nullptr; ft->title.length = 0; } + ECS_MarkForRemoval(ft); } // TODO perf? @@ -735,7 +765,7 @@ void FontType_Unload(FontTypeIndex idx) { // However, the new buffer is exactly the length it needs to be and no greater. // Consider using a heuristic to allocate a buffer larger than needed. // At the time of writing, the only way to do this is to un-register text. -FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent) { +FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent, pk_uuid uuid) { assert(settings != nullptr); PKVK_TmpBufferDetails tmpBufferDetails{}; VkDeviceSize byteCount; @@ -757,103 +787,157 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && } fr = &ft->renders[(FontRenderIndex_T)idx_fr]; *fr = {}; + fr->uuid = uuid; ECS_CreateEntity(fr, parent); fr->fr_handle.index_ft = idx_ft; fr->fr_handle.index_fr = idx_fr; fr->settings = *settings; fr->text = str; - // insert new characters into tmp buffer - { - DynArray<uint32_t> glyph_indices; - glyph_indices.Reserve(str.length); - count = 0; - for (i = 0; i < str.length;) { - fgc = nullptr; - u = 0; - // determine unicode char - ii = utf8_to_unicode(&str.val[i], u); - if (ii == 0) { - fprintf(stderr, "failed to determine unicode for character: at byte index: '%i'\n", i); - i += 1; - continue; + if (window != NULL) { + // insert new characters into tmp buffer + { + DynArray<uint32_t> glyph_indices; + glyph_indices.Reserve(str.length); + count = 0; + for (i = 0; i < str.length;) { + fgc = nullptr; + u = 0; + // determine unicode char + ii = utf8_to_unicode(&str.val[i], u); + if (ii == 0) { + fprintf(stderr, "failed to determine unicode for character: at byte index: '%i'\n", i); + i += 1; + continue; + } + i += ii; + + // binary search for glyph details + l = 0; + r = ft->n_glyphs - 1; + do { + m = l + (r-l)/2; + fgc = &ft->glyphs[m]; + if (fgc->unicode < u) + l = m + 1; + else + r = m - 1; + } while (fgc->unicode != u && l <= r); + + if (fgc->unicode != u) { + fprintf(stderr, "font: '%s' does not contain unicode character '%u'\n", ft->title.val, u); + continue; + } + count += 1; + glyph_indices.Push(m); } - i += ii; - - // binary search for glyph details - l = 0; - r = ft->n_glyphs - 1; - do { - m = l + (r-l)/2; - fgc = &ft->glyphs[m]; - if (fgc->unicode < u) - l = m + 1; - else - r = m - 1; - } while (fgc->unicode != u && l <= r); - - if (fgc->unicode != u) { - fprintf(stderr, "font: '%s' does not contain unicode character '%u'\n", ft->title.val, u); - continue; + + // TODO specific bucket + fr->n_glyphs = count; + fr->glyph_indices = pk_new<uint32_t>(count); + for (i = 0; i < count; ++i) { + fr->glyph_indices[i] = glyph_indices[i]; } - count += 1; - glyph_indices.Push(m); } - // TODO specific bucket - fr->n_glyphs = count; - fr->glyph_indices = pk_new<uint32_t>(count); - for (i = 0; i < count; ++i) { - fr->glyph_indices[i] = glyph_indices[i]; - } - } + VkDeviceSize item_count_orig = ft->bindings.instance_counter; + VkDeviceSize item_length_new = PK_MAX(ft->bindings.instance_buffer_max_count, ft->bindings.instance_counter + count); + + // copy existing buffer to new buffer + // create new buffer + if (ft->bindings.instance_buffer_max_count < item_length_new) { + byteCount = sizeof(FontInstanceBufferItem) * item_length_new; + VkBuffer newBuffer; + VkBufferCreateInfo bufferCI; + bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferCI.pNext = nullptr; + bufferCI.flags = {}; + bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + bufferCI.queueFamilyIndexCount = 1; + bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + bufferCI.size = byteCount; + vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); + assert(vkResult == VK_SUCCESS); - VkDeviceSize item_count_orig = ft->bindings.instance_counter; - VkDeviceSize item_length_new = PK_MAX(ft->bindings.instance_buffer_max_count, ft->bindings.instance_counter + count); - - // copy existing buffer to new buffer - // create new buffer - if (ft->bindings.instance_buffer_max_count < item_length_new) { - byteCount = sizeof(FontInstanceBufferItem) * item_length_new; - VkBuffer newBuffer; - VkBufferCreateInfo bufferCI; - bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCI.pNext = nullptr; - bufferCI.flags = {}; - bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - bufferCI.queueFamilyIndexCount = 1; - bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex; - bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - bufferCI.size = byteCount; - vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); - assert(vkResult == VK_SUCCESS); + VkMemoryRequirements vkMemReqs; + vkGetBufferMemoryRequirements(vkDevice, newBuffer, &vkMemReqs); + assert(sizeof(FontInstanceBufferItem) % vkMemReqs.alignment == 0); - VkMemoryRequirements vkMemReqs; - vkGetBufferMemoryRequirements(vkDevice, newBuffer, &vkMemReqs); - assert(sizeof(FontInstanceBufferItem) % vkMemReqs.alignment == 0); + vkDestroyBuffer(vkDevice, newBuffer, vkAllocator); + newBuffer = VK_NULL_HANDLE; - vkDestroyBuffer(vkDevice, newBuffer, vkAllocator); - newBuffer = VK_NULL_HANDLE; + bufferCI.size = vkMemReqs.size + (vkMemReqs.alignment - (vkMemReqs.size & vkMemReqs.alignment)); + vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); + assert(vkResult == VK_SUCCESS); - bufferCI.size = vkMemReqs.size + (vkMemReqs.alignment - (vkMemReqs.size & vkMemReqs.alignment)); - vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer); - assert(vkResult == VK_SUCCESS); + VkDeviceMemory new_memory; + VkMemoryAllocateInfo vkMemoryAllocateInfo; + vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + vkMemoryAllocateInfo.pNext = nullptr; + vkMemoryAllocateInfo.allocationSize = bufferCI.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VkDeviceMemory new_memory; - VkMemoryAllocateInfo vkMemoryAllocateInfo; - vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - vkMemoryAllocateInfo.pNext = nullptr; - vkMemoryAllocateInfo.allocationSize = bufferCI.size; - vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkResult = vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &new_memory); + assert(vkResult == VK_SUCCESS); - vkResult = vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &new_memory); - assert(vkResult == VK_SUCCESS); + vkResult = vkBindBufferMemory(vkDevice, newBuffer, new_memory, 0); + assert(vkResult == VK_SUCCESS); - vkResult = vkBindBufferMemory(vkDevice, newBuffer, new_memory, 0); - assert(vkResult == VK_SUCCESS); + if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE && ft->bindings.instance_counter > 0) { + PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails, PKVK_TmpBufferFlags_NONE); + + VkCommandBufferBeginInfo vkCommandBufferBeginInfo; + vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + vkCommandBufferBeginInfo.pNext = nullptr; + // TODO consider single-use? + vkCommandBufferBeginInfo.flags = 0; + vkCommandBufferBeginInfo.pInheritanceInfo = nullptr; + vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo); + assert(vkResult == VK_SUCCESS); + + VkBufferCopy vk_buffer_copy{}; + vk_buffer_copy.srcOffset = 0; + vk_buffer_copy.dstOffset = 0; + vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter; + assert(vk_buffer_copy.size != 0); + vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, ft->bindings.bd_instance.buffer, newBuffer, 1, &vk_buffer_copy); + + vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer); + assert(vkResult == VK_SUCCESS); + + VkSubmitInfo submitInfo; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pNext = nullptr; + submitInfo.waitSemaphoreCount = 0; + submitInfo.pWaitSemaphores = nullptr; + submitInfo.pWaitDstStageMask = nullptr; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &tmpBufferDetails.cmdBuffer; + submitInfo.signalSemaphoreCount = 0; + submitInfo.pSignalSemaphores = nullptr; + vkResult = vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr); + assert(vkResult == VK_SUCCESS); + vkResult = vkQueueWaitIdle(tmpBufferDetails.queue); + assert(vkResult == VK_SUCCESS); + + PKVK_EndBuffer(tmpBufferDetails, PKVK_TmpBufferFlags_NONE); + } + if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, ft->bindings.bd_instance.buffer, vkAllocator); + if (ft->gr.deviceMemoryInst != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, ft->gr.deviceMemoryInst, vkAllocator); - if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE && ft->bindings.instance_counter > 0) { - PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails, PKVK_TmpBufferFlags_NONE); + ft->gr.deviceMemoryInst = new_memory; + ft->bindings.bd_instance.buffer = newBuffer; + } + ft->bindings.instance_buffer_max_count = item_length_new; + ft->bindings.instance_counter += count; + + // create tmp local buffer & copy data to graphics card + byteCount = sizeof(FontInstanceBufferItem) * count; + PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails); + { VkCommandBufferBeginInfo vkCommandBufferBeginInfo; vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -864,12 +948,13 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo); assert(vkResult == VK_SUCCESS); + FontType_Inner_CalcTransforms(ft, fr, (FontInstanceBufferItem*)tmpBufferDetails.deviceData); + VkBufferCopy vk_buffer_copy{}; vk_buffer_copy.srcOffset = 0; - vk_buffer_copy.dstOffset = 0; - vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter; - assert(vk_buffer_copy.size != 0); - vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, ft->bindings.bd_instance.buffer, newBuffer, 1, &vk_buffer_copy); + vk_buffer_copy.dstOffset = sizeof(FontInstanceBufferItem) * item_count_orig; + vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * count; + vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->bindings.bd_instance.buffer, 1, &vk_buffer_copy); vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer); assert(vkResult == VK_SUCCESS); @@ -888,65 +973,20 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr && assert(vkResult == VK_SUCCESS); vkResult = vkQueueWaitIdle(tmpBufferDetails.queue); assert(vkResult == VK_SUCCESS); - - PKVK_EndBuffer(tmpBufferDetails, PKVK_TmpBufferFlags_NONE); } - if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE) - vkDestroyBuffer(vkDevice, ft->bindings.bd_instance.buffer, vkAllocator); - if (ft->gr.deviceMemoryInst != VK_NULL_HANDLE) - vkFreeMemory(vkDevice, ft->gr.deviceMemoryInst, vkAllocator); - - ft->gr.deviceMemoryInst = new_memory; - ft->bindings.bd_instance.buffer = newBuffer; - } - ft->bindings.instance_buffer_max_count = item_length_new; - ft->bindings.instance_counter += count; - - // create tmp local buffer & copy data to graphics card - byteCount = sizeof(FontInstanceBufferItem) * count; - PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails); - { - - VkCommandBufferBeginInfo vkCommandBufferBeginInfo; - vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - vkCommandBufferBeginInfo.pNext = nullptr; - // TODO consider single-use? - vkCommandBufferBeginInfo.flags = 0; - vkCommandBufferBeginInfo.pInheritanceInfo = nullptr; - vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo); - assert(vkResult == VK_SUCCESS); - - FontType_Inner_CalcTransforms(ft, fr, (FontInstanceBufferItem*)tmpBufferDetails.deviceData); - - VkBufferCopy vk_buffer_copy{}; - vk_buffer_copy.srcOffset = 0; - vk_buffer_copy.dstOffset = sizeof(FontInstanceBufferItem) * item_count_orig; - vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * count; - vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->bindings.bd_instance.buffer, 1, &vk_buffer_copy); - - vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer); - assert(vkResult == VK_SUCCESS); - - VkSubmitInfo submitInfo; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pNext = nullptr; - submitInfo.waitSemaphoreCount = 0; - submitInfo.pWaitSemaphores = nullptr; - submitInfo.pWaitDstStageMask = nullptr; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &tmpBufferDetails.cmdBuffer; - submitInfo.signalSemaphoreCount = 0; - submitInfo.pSignalSemaphores = nullptr; - vkResult = vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr); - assert(vkResult == VK_SUCCESS); - vkResult = vkQueueWaitIdle(tmpBufferDetails.queue); - assert(vkResult == VK_SUCCESS); + PKVK_EndBuffer(tmpBufferDetails); } - PKVK_EndBuffer(tmpBufferDetails); return fr->fr_handle; } +FontRender *FontType_GetFontRender(FontRenderHandle frh) { + assert(frh.index_ft < ftd.h_ft); + FontType *ft = &ftd.arr_ft[static_cast<FontTypeIndex_T>(frh.index_ft)]; + assert(frh.index_fr < ft->h_render); + return &ft->renders[static_cast<FontRenderIndex_T>(frh.index_fr)]; +} + void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings) { assert(settings != nullptr); assert((FontTypeIndex_T)ftd.h_ft > (FontTypeIndex_T)frh.index_ft); diff --git a/src/font.hpp b/src/font.hpp index d31209c..a8b1ecf 100644 --- a/src/font.hpp +++ b/src/font.hpp @@ -118,10 +118,12 @@ void FontType_Teardown(); void FontType_Tick(double delta); void FontType_Serialize(std::ostream &stream, FontType *ft); void FontType_Deserialize(std::istream &stream); +FontType* FontType_Get(FontTypeIndex idx); FontType* FontType_GetFonts(FontTypeIndex &count); FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing); void FontType_Unload(FontTypeIndex idx); -FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent = nullptr); +FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent = nullptr, pk_uuid uuid = pk_uuid_zed); +FontRender *FontType_GetFontRender(FontRenderHandle frh); void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings); void FontType_RemoveStringRender(FontRenderHandle frh); diff --git a/src/game.cpp b/src/game.cpp index 5013c49..4ca5161 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -186,21 +186,19 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) { // TODO remove me: temp stuff for testing pke_ui_box *ui_box = pke_ui_box_new_root(); ui_box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC; - ui_box->pos_top_left_x = 0.1; - ui_box->pos_top_left_y = 0.1; - ui_box->max_width = 0.8; - ui_box->max_height = 0.8; + ui_box->pos_top_left.x = 0.1; + ui_box->pos_top_left.y = 0.1; + ui_box->max_size.x = 0.8; + ui_box->max_size.y = 0.8; // TODO remove me: temp stuff for testing pke_ui_box *c_ui_box = pke_ui_box_new_child(ui_box, PKE_UI_BOX_TYPE_TEXT); c_ui_box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC; - c_ui_box->pos_top_left_x = 20; - c_ui_box->pos_top_left_y = 20; - c_ui_box->max_width = 3000; - c_ui_box->max_height = 3000; - pke_ui_box_type_data_text *box_text = reinterpret_cast<pke_ui_box_type_data_text*>(c_ui_box->type_data); - box_text->font_render_handle = fr_1; - box_text->font_render_settings = fr_set; + c_ui_box->pos_top_left.x = 20; + c_ui_box->pos_top_left.y = 20; + c_ui_box->max_size.x = 3000; + c_ui_box->max_size.y = 3000; + c_ui_box->type_data->text.font_render_handle = fr_1; GameTimePoint lastTimePoint = pkeSettings.steadyClock.now(); double deltaTillNextRender = pkeSettings.deltaPerFrame; diff --git a/src/serialization-component.cpp b/src/serialization-component.cpp index 3ff4d5d..4f65a5a 100644 --- a/src/serialization-component.cpp +++ b/src/serialization-component.cpp @@ -276,7 +276,7 @@ void pke_deserialize_instance(srlztn_deserialize_helper *h, pke_kve_container *k inst_pos.posRot.setOrigin(bt_pos); inst_pos.posRot.setRotation(bt_quat); pk_arr_t<CompInstance *> instances; - srlztn_instance_mapping map{}; + srlztn_ecs_mapping map{}; map.serialized_uuid = comp.uuid; if (et_ptr != nullptr) { if (et_ptr->createInstanceCallback.func != nullptr) { diff --git a/src/serialization-font.cpp b/src/serialization-font.cpp index 761643c..b57e6e7 100644 --- a/src/serialization-font.cpp +++ b/src/serialization-font.cpp @@ -1,13 +1,16 @@ #include "serialization-font.hpp" +#include "ecs.hpp" +#include "font.hpp" #include "pk.h" +#include "serialization.hpp" pk_handle pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr) { assert(h != nullptr); assert(fr != nullptr); char *s; - pk_handle inst_pos_handle; + pk_handle font_render_settings_handle; pke_kve kve{}; pke_kve_container kvec{}; @@ -15,55 +18,88 @@ pk_handle pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr) return PK_HANDLE_MAX; } + font_render_settings_handle = pke_serialize_font_render_settings(h, &fr->settings); + kvec.srlztn_handle = h->handle_head; - kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_CAMERA); + kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_FONT_RENDER); kvec.bkt = h->bkt; kvec.arr.bkt = h->bkt; kvec.children.bkt = h->bkt; kvec.child_handles.bkt = h->bkt; h->handle_head.itemIndex++; - pk_arr_append_t(&kvec.child_handles, inst_pos_handle); + pk_arr_append_t(&kvec.child_handles, font_render_settings_handle); - if (fr->uuid != pk_uuid_zed && fr->uuid != pk_uuid_max) { - kve.key = SRLZTN_UI_BOX_UUID; + { + kve.key = SRLZTN_UI_FONT_RENDER_UUID; s = pk_new<char>(37, h->bkt); sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(fr->uuid)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } + { + kve.key = SRLZTN_UI_FONT_RENDER_FONT_TYPE_UUID; + s = pk_new<char>(37, h->bkt); + FontType *ft = FontType_Get(fr->fr_handle.index_ft); + sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(ft->uuid)); + kve.val = s; + kve.end = SRLZTN_KVE_END; + pk_arr_append_t(&kvec.arr, kve); + } if (fr->text.val != nullptr) { kve.key = SRLZTN_UI_FONT_RENDER_TEXT_BEGIN; - s = pk_new<char>(fr->text.reserved, h->bkt); - sprintf(s, "%s", fr->text.val); + s = pk_new<char>(strlen(fr->text.val) + 3, h->bkt); + sprintf(s, "\n%s\n", fr->text.val); kve.val = s; kve.end = SRLZTN_MULTILINE_END; pk_arr_append_t(&kvec.arr, kve); } pk_arr_append_t(&h->kvp_containers, kvec); - return pke_serialize_font_render_settings(h, &fr->settings); + kvec.arr.data = nullptr; + kvec.children.data = nullptr; + kvec.child_handles.data = nullptr; + return kvec.srlztn_handle; } -void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRender *fr) { +void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec) { assert(h != nullptr); - assert(fr != nullptr); + assert(kvec != nullptr); + assert(kvec->children.next == 1); + + pke_kve *kve = nullptr; + pk_uuid uuid; + pk_uuid font_type_uuid; + pk_cstr str; + FontRenderSettings frs{}; + pke_deserialize_font_render_settings(h, kvec->children[0], &frs); + uint32_t i; char *s; for (i = 0; i < kvec->arr.next; ++i) { - if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_UUID, strlen(SRLZTN_UI_FONT_RENDER_UUID)) == 0) { - kvec->arr[i].val >> fr->uuid; + kve = &kvec->arr[i]; + if (strcmp(kve->key, SRLZTN_UI_FONT_RENDER_UUID) == 0) { + kve->val >> uuid; + continue; + } + if (strcmp(kve->key, SRLZTN_UI_FONT_RENDER_FONT_TYPE_UUID) == 0) { + kve->val >> font_type_uuid; continue; } - if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_TEXT_BEGIN, strlen(SRLZTN_UI_FONT_RENDER_TEXT_BEGIN)) == 0) { - fr->text.length = strlen(kvec->arr[i].val) + 1; - fr->text.reserved = fr->text.reserved + 1; - // TODO specific bkt - s = pk_new<char>(fr->text.reserved, NULL); - fr->text.val = s; + if (strcmp(kve->key, SRLZTN_UI_FONT_RENDER_TEXT_BEGIN) == 0) { + str.length = strlen(kve->val) + 1; + str.reserved = str.length + 1; + // TODO specific bkt? + s = pk_new<char>(str.reserved, NULL); + sprintf(s, "%s", kve->val); + str.val = s; continue; } } + + FontType *font_type_ent = static_cast<FontType *>(ECS_GetEntityByUUID(font_type_uuid)); + // parent is set later - up to the parent to take ownership + FontType_AddStringRender(font_type_ent->index_ft, std::move(str), &frs, nullptr, uuid); } pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRenderSettings *frs) { @@ -80,7 +116,7 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen kvec.child_handles.bkt = h->bkt; h->handle_head.itemIndex++; - if (frs->char_scale != 0.0) { + { kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE; len = snprintf(NULL, 0, "%f", frs->char_scale); s = pk_new<char>(len+1, h->bkt); @@ -89,7 +125,7 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (frs->line_height_scale != 0.0) { + { kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE; len = snprintf(NULL, 0, "%f", frs->line_height_scale); s = pk_new<char>(len+1, h->bkt); @@ -98,7 +134,7 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (frs->char_spacing_scale != 0.0) { + { kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE; len = snprintf(NULL, 0, "%f", frs->char_spacing_scale); s = pk_new<char>(len+1, h->bkt); @@ -107,25 +143,25 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (frs->surface_area_size != glm::ivec2(0)) { + { kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE; - len = snprintf(NULL, 0, "%d, %d", frs->surface_area_size.x, frs->surface_area_size.y); + len = snprintf(NULL, 0, "%d%s%d", frs->surface_area_size.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_size.y); s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%d, %d", frs->surface_area_size.x, frs->surface_area_size.y); + sprintf(s, "%d%s%d", frs->surface_area_size.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_size.y); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (frs->surface_area_pos != glm::ivec2(0)) { + { kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS; - len = snprintf(NULL, 0, "%d, %d", frs->surface_area_pos.x, frs->surface_area_pos.y); + len = snprintf(NULL, 0, "%d%s%d", frs->surface_area_pos.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_pos.y); s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%d, %d", frs->surface_area_pos.x, frs->surface_area_pos.y); + sprintf(s, "%d%s%d", frs->surface_area_pos.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_pos.y); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (frs->surface_area_type_flags != FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_NONE) { + { kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS; s = pk_new<char>(5, h->bkt); sprintf(s, "0x%.2X", FONT_RENDER_SURFACE_AREA_TYPE_FLAG_T(frs->surface_area_type_flags)); @@ -135,12 +171,16 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen } pk_arr_append_t(&h->kvp_containers, kvec); + kvec.arr.data = nullptr; + kvec.children.data = nullptr; + kvec.child_handles.data = nullptr; return kvec.srlztn_handle; } void pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRenderSettings *frs) { (void)h; - uint32_t i; + uint32_t i, index; + const char *starting_char; PK_STN_RES stn_res; char *str_end; for (i = 0; i < kvec->arr.next; ++i) { @@ -166,29 +206,31 @@ void pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, pke_kve_ continue; } if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE)) == 0) { - stn_res = pk_stn(&frs->surface_area_size.x, kvec->arr[i].val, &str_end); - if (stn_res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[%s] Err '%u' parsing '%s' (x) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, kvec->arr[i].val); - continue; - } - size_t prefix_len = strchr(kvec->arr[i].val, ',') - (kvec->arr[i].val); - stn_res = pk_stn(&frs->surface_area_size.y, kvec->arr[i].val + prefix_len, &str_end); - if (stn_res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[%s] Err '%u' parsing '%s' (y) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, kvec->arr[i].val); - } + starting_char = kvec->arr[i].val; + index = 0; + do { + assert(index < 2); + stn_res = pk_stn(&frs->surface_area_size[index], starting_char, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s'[%i] from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, index, kvec->arr[i].val); + } + starting_char = str_end + 1; + ++index; + } while (*str_end != '\0'); continue; } if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS)) == 0) { - stn_res = pk_stn(&frs->surface_area_pos.x, kvec->arr[i].val, &str_end); - if (stn_res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[%s] Err '%u' parsing '%s' (x) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, kvec->arr[i].val); - continue; - } - size_t prefix_len = strchr(kvec->arr[i].val, ',') - (kvec->arr[i].val); - stn_res = pk_stn(&frs->surface_area_pos.y, kvec->arr[i].val + prefix_len, &str_end); - if (stn_res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[%s] Err '%u' parsing '%s' (y) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, kvec->arr[i].val); - } + starting_char = kvec->arr[i].val; + index = 0; + do { + assert(index < 2); + stn_res = pk_stn(&frs->surface_area_pos[index], starting_char, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s'[%i] from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, index, kvec->arr[i].val); + } + starting_char = str_end + 1; + ++index; + } while (*str_end != '\0'); continue; } if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS)) == 0) { diff --git a/src/serialization-font.hpp b/src/serialization-font.hpp index e41f974..c12dc13 100644 --- a/src/serialization-font.hpp +++ b/src/serialization-font.hpp @@ -5,7 +5,7 @@ #include "font.hpp" pk_handle pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr); -void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRender *fr); +void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec); pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRenderSettings *frs); void pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRenderSettings *frs); diff --git a/src/serialization-static-ui.cpp b/src/serialization-static-ui.cpp index 447e7d0..4c45cc1 100644 --- a/src/serialization-static-ui.cpp +++ b/src/serialization-static-ui.cpp @@ -1,50 +1,56 @@ #include "serialization-static-ui.hpp" #include "ecs.hpp" +#include "font.hpp" #include "pk.h" -#include "serialization-font.hpp" #include "static-ui.hpp" -pk_handle pke_serialize_ui_box_internal(srlztn_serialize_helper *h, pke_ui_box_type_data_text *data) { +pk_handle pke_serialize_ui_box_internal(srlztn_serialize_helper *h, pke_ui_box_type_data::pke_ui_box_type_data_text *data) { char *s; - pk_handle font_render_handle; pke_kve kve{}; pke_kve_container kvec{}; - font_render_handle = pke_serialize_font_render_settings(h, &data->font_render_settings); - kvec.srlztn_handle = h->handle_head; - kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_UI_BOX); + kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_UI_BOX_TYPE_DATA); kvec.bkt = h->bkt; kvec.arr.bkt = h->bkt; kvec.children.bkt = h->bkt; kvec.child_handles.bkt = h->bkt; h->handle_head.itemIndex++; - if (font_render_handle != PK_HANDLE_MAX) { - pk_arr_append_t(&kvec.child_handles, font_render_handle); - } - if (data->font_render_uuid != pk_uuid_zed) { + { kve.key = SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID; s = pk_new<char>(37, h->bkt); - sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(data->font_render_uuid)); + FontRender *fr = FontType_GetFontRender(data->font_render_handle); + sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(fr->uuid)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } pk_arr_append_t(&h->kvp_containers, kvec); + kvec.arr.data = nullptr; + kvec.children.data = nullptr; + kvec.child_handles.data = nullptr; return kvec.srlztn_handle; } -void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_container *kvec, pke_ui_box_type_data_text *data) { - assert(kvec->children.next == 1); - - pke_deserialize_font_render_settings(h, kvec, &data->font_render_settings); +void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_container *kvec, pke_ui_box_type_data::pke_ui_box_type_data_text *data) { + (void)h; + assert(kvec != nullptr); + assert(data != nullptr); + assert(kvec->arr.next == 1); + pk_uuid font_render_uuid = pk_uuid_zed; if (strstr(SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID, kvec->arr[0].key)) { - kvec->arr[0].val >> data->font_render_uuid; + kvec->arr[0].val >> font_render_uuid; } + + assert(font_render_uuid != pk_uuid_zed); + + FontRender *fr = static_cast<FontRender *>(ECS_GetEntityByUUID(font_render_uuid)); + + data->font_render_handle = fr->fr_handle; } pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) { @@ -55,8 +61,7 @@ pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) { pke_kve_container kvec{}; if (box->type == PKE_UI_BOX_TYPE_TEXT) { - pke_ui_box_type_data_text *d = reinterpret_cast<pke_ui_box_type_data_text *>(box->type_data); - internal_type_handle = pke_serialize_ui_box_internal(h, d); + internal_type_handle = pke_serialize_ui_box_internal(h, &box->type_data->text); } kvec.srlztn_handle = h->handle_head; @@ -95,61 +100,34 @@ pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) { kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (box->pos_top_left_x != 0.0) { - kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT_X; - len = snprintf(NULL, 0, "%f", box->pos_top_left_x); - s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%f", box->pos_top_left_x); - kve.val = s; - kve.end = SRLZTN_KVE_END; - pk_arr_append_t(&kvec.arr, kve); - } - if (box->pos_top_left_y != 0.0) { - kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT_Y; - len = snprintf(NULL, 0, "%f", box->pos_top_left_y); + { + kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT; + len = snprintf(NULL, 0, "%f;%f", box->pos_top_left.x, box->pos_top_left.y); s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%f", box->pos_top_left_y); + sprintf(s, "%f;%f", box->pos_top_left.x, box->pos_top_left.y); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (box->min_width != 0.0) { - kve.key = SRLZTN_UI_BOX_MIN_WIDTH; - len = snprintf(NULL, 0, "%f", box->min_width); + if (box->min_size != glm::vec2(0,0)) { + kve.key = SRLZTN_UI_BOX_MIN_SIZE; + len = snprintf(NULL, 0, "%f;%f", box->min_size.x, box->min_size.y); s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%f", box->min_width); + sprintf(s, "%f%f", box->min_size.x, box->min_size.y); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (box->min_height != 0.0) { - kve.key = SRLZTN_UI_BOX_MIN_HEIGHT; - len = snprintf(NULL, 0, "%f", box->min_height); + if (box->max_size != glm::vec2(0,0)) { + kve.key = SRLZTN_UI_BOX_MAX_SIZE; + len = snprintf(NULL, 0, "%f;%f", box->max_size[0], box->max_size[1]); s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%f", box->min_height); + sprintf(s, "%f;%f", box->max_size[0], box->max_size[1]); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (box->max_width != 0.0) { - kve.key = SRLZTN_UI_BOX_MAX_WIDTH; - len = snprintf(NULL, 0, "%f", box->max_width); - s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%f", box->max_width); - kve.val = s; - kve.end = SRLZTN_KVE_END; - pk_arr_append_t(&kvec.arr, kve); - } - if (box->max_height != 0.0) { - kve.key = SRLZTN_UI_BOX_MAX_HEIGHT; - len = snprintf(NULL, 0, "%f", box->max_height); - s = pk_new<char>(len+1, h->bkt); - sprintf(s, "%f", box->max_height); - kve.val = s; - kve.end = SRLZTN_KVE_END; - pk_arr_append_t(&kvec.arr, kve); - } - if (box->flex_weight != 0.0) { + if (box->flex_weight != 0.f) { kve.key = SRLZTN_UI_BOX_FLEX_WEIGHT; len = snprintf(NULL, 0, "%f", box->flex_weight); s = pk_new<char>(len+1, h->bkt); @@ -157,33 +135,35 @@ pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) { kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); - } - if (box->type != PKE_UI_BOX_TYPE_STANDARD) { - kve.key = SRLZTN_UI_BOX_FLAGS; + // only serialize if we're using flex + kve.key = SRLZTN_UI_BOX_FLEX_DIRECTION; s = pk_new<char>(5, h->bkt); - sprintf(s, "0x%.2X", static_cast<PKE_UI_BOX_TYPE_T>(box->type)); + sprintf(s, "0x%.2X", box->flex_direction); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (box->flex_direction != 0) { - kve.key = SRLZTN_UI_BOX_FLEX_DIRECTION; + { + kve.key = SRLZTN_UI_BOX_TYPE; s = pk_new<char>(5, h->bkt); - sprintf(s, "%u", box->flex_direction); + sprintf(s, "0x%.2X", static_cast<PKE_UI_BOX_TYPE_T>(box->type)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } - if (box->layer != 0) { + { kve.key = SRLZTN_UI_BOX_LAYER; s = pk_new<char>(5, h->bkt); - sprintf(s, "%u", box->layer); + sprintf(s, "0x%.2X", box->layer); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } pk_arr_append_t(&h->kvp_containers, kvec); + kvec.arr.data = nullptr; + kvec.children.data = nullptr; + kvec.child_handles.data = nullptr; return kvec.srlztn_handle; } @@ -200,35 +180,34 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve * */ - uint32_t i; - uint64_t prefix_len; + uint32_t i, index; PK_STN_RES res; + const char *starting_char; char *stn_end; + pke_kve *kve; pke_ui_box bx{}; pke_ui_box *parent_box = nullptr; bx.type_data = nullptr; for (i = 0; i < kvec->arr.next; ++i) { - if (strstr(SRLZTN_UI_BOX_UUID, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_UUID); - (kvec->arr[i].val + prefix_len) >> bx.uuid; + kve = &kvec->arr[i]; + if (strstr(SRLZTN_UI_BOX_UUID, kve->key)) { + kve->val >> bx.uuid; continue; } - if (strstr(SRLZTN_UI_BOX_PARENT_UUID, kvec->arr[i].key)) { + if (strstr(SRLZTN_UI_BOX_PARENT_UUID, kve->key)) { uint32_t target_instance_index = -1; pk_uuid id; - prefix_len = strlen(SRLZTN_UI_BOX_PARENT_UUID); - (kvec->arr[i].val + prefix_len) >> id; + kve->val >> id; target_instance_index = pk_arr_find_first_index(&h->mapping, &id, srlztn_mapping_find_first_handle_by_uuid); if (target_instance_index != uint32_t(-1)) { parent_box = static_cast<pke_ui_box*>(h->mapping[target_instance_index].created_entity); } continue; } - if (strstr(SRLZTN_UI_BOX_FLAGS, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_FLAGS); + if (strstr(SRLZTN_UI_BOX_FLAGS, kve->key)) { PKE_UI_BOX_FLAG_T flags; - res = pk_stn(&flags, kvec->arr[i].val + prefix_len, &stn_end); + res = pk_stn(&flags, kve->val, &stn_end, 16); if (res != PK_STN_RES_SUCCESS) { fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_FLAGS, res); continue; @@ -236,125 +215,110 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve bx.flags = PKE_UI_BOX_FLAG(flags); continue; } - if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT_X, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_X); - res = pk_stn(&bx.pos_top_left_x, kvec->arr[i].val + prefix_len, &stn_end); - if (res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_POS_TOP_LEFT_X, res); - continue; - } - continue; - } - if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT_Y, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_Y); - res = pk_stn(&bx.pos_top_left_y, kvec->arr[i].val + prefix_len, &stn_end); - if (res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_POS_TOP_LEFT_Y, res); - continue; - } - continue; - } - if (strstr(SRLZTN_UI_BOX_MIN_WIDTH, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_MIN_WIDTH); - res = pk_stn(&bx.min_width, kvec->arr[i].val + prefix_len, &stn_end); - if (res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MIN_WIDTH, res); - continue; - } - continue; - } - if (strstr(SRLZTN_UI_BOX_MIN_HEIGHT, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_MIN_HEIGHT); - res = pk_stn(&bx.min_width, kvec->arr[i].val + prefix_len, &stn_end); + if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT, kve->key)) { + starting_char = kve->val; + index = 0; + do { + assert(index < 2); + res = pk_stn(&bx.pos_top_left[index], starting_char, &stn_end); + if (res != PK_STN_RES_SUCCESS) break; + starting_char = stn_end + 1; + ++index; + } while (*stn_end != '\0'); if (res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MIN_HEIGHT, res); - continue; + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_POS_TOP_LEFT, res); } continue; } - if (strstr(SRLZTN_UI_BOX_MAX_WIDTH, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_MAX_WIDTH); - res = pk_stn(&bx.max_width, kvec->arr[i].val + prefix_len, &stn_end); + if (strstr(SRLZTN_UI_BOX_MIN_SIZE, kve->key)) { + starting_char = kve->val; + index = 0; + do { + assert(index < 2); + res = pk_stn(&bx.min_size[index], starting_char, &stn_end); + if (res != PK_STN_RES_SUCCESS) break; + starting_char = stn_end + 1; + ++index; + } while (*stn_end != '\0'); if (res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MAX_WIDTH, res); - continue; + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MIN_SIZE, res); } continue; } - if (strstr(SRLZTN_UI_BOX_MAX_HEIGHT, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_MAX_HEIGHT); - res = pk_stn(&bx.max_width, kvec->arr[i].val + prefix_len, &stn_end); + if (strstr(SRLZTN_UI_BOX_MAX_SIZE, kve->key)) { + starting_char = kve->val; + index = 0; + do { + assert(index < 2); + res = pk_stn(&bx.max_size[index], starting_char, &stn_end); + if (res != PK_STN_RES_SUCCESS) break; + starting_char = stn_end + 1; + ++index; + } while (*stn_end != '\0'); if (res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MAX_HEIGHT, res); - continue; + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MAX_SIZE, res); } continue; } - if (strstr(SRLZTN_UI_BOX_FLEX_WEIGHT, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_FLEX_WEIGHT); - res = pk_stn(&bx.flex_weight, kvec->arr[i].val + prefix_len, &stn_end); + if (strstr(SRLZTN_UI_BOX_FLEX_WEIGHT, kve->key)) { + res = pk_stn(&bx.flex_weight, kve->val, &stn_end); if (res != PK_STN_RES_SUCCESS) { fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_FLEX_WEIGHT, res); continue; } continue; } - if (strstr(SRLZTN_UI_BOX_FLEX_DIRECTION, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_FLEX_DIRECTION); - res = pk_stn(&bx.flex_direction, kvec->arr[i].val + prefix_len, &stn_end); + if (strstr(SRLZTN_UI_BOX_FLEX_DIRECTION, kve->key)) { + res = pk_stn(&bx.flex_direction, kve->val, &stn_end); if (res != PK_STN_RES_SUCCESS) { fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_FLEX_DIRECTION, res); continue; } continue; } - if (strstr(SRLZTN_UI_BOX_LAYER, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_LAYER); - res = pk_stn(&bx.layer, kvec->arr[i].val + prefix_len, &stn_end); + if (strstr(SRLZTN_UI_BOX_LAYER, kve->key)) { + res = pk_stn(&bx.layer, kve->val, &stn_end); if (res != PK_STN_RES_SUCCESS) { fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_LAYER, res); continue; } continue; } - if (strstr(SRLZTN_UI_BOX_TYPE, kvec->arr[i].key)) { - prefix_len = strlen(SRLZTN_UI_BOX_TYPE); - res = pk_stn(&bx.type, kvec->arr[i].val + prefix_len, &stn_end); + if (strstr(SRLZTN_UI_BOX_TYPE, kve->key)) { + uint8_t v; + res = pk_stn<uint8_t>(&v, kve->val, &stn_end); if (res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_TYPE, res); + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse '%s' from '%s', err: %i\n", SRLZTN_UI_BOX_TYPE, kve->val, res); continue; } - // TODO specific bucket? + // log warning for unknown + bx.type = PKE_UI_BOX_TYPE{v}; switch (bx.type) { + case PKE_UI_BOX_TYPE_STANDARD: case PKE_UI_BOX_TYPE_TEXT: + case PKE_UI_BOX_TYPE_INPUT_TEXT: break; default: - fprintf(stderr, "[pke_deserialize_ui_box] Parsed unknown ui box data type from: '%s'\n", kvec->arr[i].val); + fprintf(stderr, "[pke_deserialize_ui_box] Parsed unknown ui box data type from: '%s'\n", kve->val); continue; } continue; } } - // get ready to deserialize children + // deserialize data + // TODO specific bucket? if (bx.type != PKE_UI_BOX_TYPE_STANDARD) { + bx.type_data = pk_new<pke_ui_box_type_data>(); switch (bx.type) { case PKE_UI_BOX_TYPE_TEXT: - bx.type_data = pk_new<pke_ui_box_type_data_text>(); + pke_deserialize_ui_box_internal(h, kvec->children[0], &bx.type_data->text); break; default: break; } } - // deserialize children - for (i = 0; i < kvec->children.next; ++i) { - pke_kve_container *child_kvec = kvec->children[i]; - if (strcmp(child_kvec->type_code.val, SRLZTN_OBJ_UI_BOX_TYPE_DATA) == 0) { - pke_deserialize_ui_box_internal(h, child_kvec, static_cast<pke_ui_box_type_data_text*>(bx.type_data)); - } - } - pke_ui_box *box; if (parent_box == nullptr) { box = pke_ui_box_new_root(bx.type, bx.uuid); @@ -362,31 +326,31 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve box = pke_ui_box_new_child(parent_box, bx.type, bx.uuid); } box->flags = bx.flags; - box->pos_top_left_x = bx.pos_top_left_x; - box->pos_top_left_y = bx.pos_top_left_y; - box->min_width = bx.min_width; - box->min_height = bx.min_height; - box->max_width = bx.max_width; - box->max_height = bx.max_height; + box->pos_top_left = bx.pos_top_left; + box->min_size = bx.min_size; + box->max_size = bx.max_size; box->flex_weight = bx.flex_weight; box->type = bx.type; box->flex_direction = bx.flex_direction; box->layer = bx.layer; - // TODO clone functions? - // might not be necessary if we refactor deserialization into their own ctors - if (bx.type != PKE_UI_BOX_TYPE_STANDARD) { - switch (bx.type) { - case PKE_UI_BOX_TYPE_TEXT: - reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data )->font_render_uuid - = reinterpret_cast<pke_ui_box_type_data_text*>(bx.type_data)->font_render_uuid; - reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data )->font_render_handle - = reinterpret_cast<pke_ui_box_type_data_text*>(bx.type_data)->font_render_handle; - reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data )->font_render_settings - = reinterpret_cast<pke_ui_box_type_data_text*>(bx.type_data)->font_render_settings; - break; - default: - break; + // TODO consider type-specific clone functions + if (box->type_data != nullptr && bx.type_data != nullptr) { + *box->type_data = *box->type_data; + pk_delete<pke_ui_box_type_data>(bx.type_data); + bx.type_data = nullptr; + } + + srlztn_ecs_mapping map{}; + map.serialized_uuid = bx.uuid; + map.created_entity = box; + pk_arr_append_t(&h->mapping, map); + + // recursively deserialize children + for (i = 0; i < kvec->children.next; ++i) { + pke_kve_container *child_kvec = kvec->children[i]; + if (strcmp(child_kvec->type_code.val, SRLZTN_OBJ_UI_BOX) == 0) { + pke_deserialize_ui_box(h, child_kvec); } } diff --git a/src/serialization.cpp b/src/serialization.cpp index ce2dbd3..352ecc9 100644 --- a/src/serialization.cpp +++ b/src/serialization.cpp @@ -1,13 +1,17 @@ #include "serialization.hpp" +#include "font.hpp" #include "pk.h" #include "serialization-component.hpp" #include "serialization-camera.hpp" #include "camera.hpp" #include "ecs.hpp" +#include "serialization-font.hpp" +#include "serialization-static-ui.hpp" +#include "static-ui.hpp" bool srlztn_mapping_find_first_handle_by_uuid(void *handle, void *mapping) { - srlztn_instance_mapping *inst_mapping = reinterpret_cast<srlztn_instance_mapping *>(mapping); + srlztn_ecs_mapping *inst_mapping = reinterpret_cast<srlztn_ecs_mapping *>(mapping); return inst_mapping->serialized_uuid == *reinterpret_cast<pk_uuid *>(handle); } bool srlztn_kvec_find_first_by_handle(void *handle, void *container) { @@ -27,10 +31,10 @@ srlztn_serialize_helper *pke_serialize_init(pk_membucket *bkt) { srlztn_deserialize_helper *pke_deserialize_init(pk_membucket *bkt) { srlztn_deserialize_helper *helper = pk_new<srlztn_deserialize_helper>(bkt); helper->bkt = bkt; + helper->kvp_containers = {}; helper->kvp_containers.bkt = bkt; + helper->mapping = {}; helper->mapping.bkt = bkt; - pk_arr_reset(&helper->kvp_containers); - pk_arr_reset(&helper->mapping); pk_arr_reserve(&helper->kvp_containers, 1); pk_arr_reserve(&helper->mapping, 1); return helper; @@ -60,6 +64,27 @@ void pke_deserialize_project_from_stream(std::istream &i, srlztn_deserialize_hel } void pke_serialize_scene(srlztn_serialize_helper *h) { + FontTypeIndex font_type_count; + FontType *fonts = FontType_GetFonts(font_type_count); + for (FontTypeIndex_T b = 0; b < (FontTypeIndex_T)font_type_count; ++b) { + FontType *fr = &fonts[b]; + if (PK_HAS_FLAG(fr->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) { + continue; + } + for (FontRenderIndex_T i = 0; i < (FontRenderIndex_T)fr->h_render; ++i) { + pke_serialize_font_render(h, &fr->renders[i]); + } + } + + pke_ui_box_count_T box_count; + pke_ui_box **ui_boxes = pke_ui_get_root_boxes(&box_count); + for (pke_ui_box_count_T i = 0; i < box_count; ++i) { + if (PK_HAS_FLAG(ui_boxes[i]->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) { + continue; + } + pke_serialize_ui_box(h, ui_boxes[i]); + } + pk_handle_bucket_index_T instanceBucketCount = ECS_GetInstances_BucketCount(); for (pk_handle_bucket_index_T b = 0; b < instanceBucketCount; ++b) { pk_handle_item_index_T count; @@ -91,11 +116,19 @@ void pke_deserialize_scene(srlztn_deserialize_helper *h) { for (i = 0; i < h->kvp_containers.next; ++i) { kvec = &h->kvp_containers[i]; - if (strstr(kvec->type_code.val, SRLZTN_OBJ_INSTANCE) != nullptr) { + if (strcmp(kvec->type_code.val, SRLZTN_OBJ_FONT_RENDER) == 0) { + pke_deserialize_font_render(h, kvec); + continue; + } + if (strcmp(kvec->type_code.val, SRLZTN_OBJ_UI_BOX) == 0) { + pke_deserialize_ui_box(h, kvec); + continue; + } + if (strcmp(kvec->type_code.val, SRLZTN_OBJ_INSTANCE) == 0) { pke_deserialize_instance(h, kvec); continue; } - if (strstr(kvec->type_code.val, SRLZTN_OBJ_CAMERA) != nullptr) { + if (strcmp(kvec->type_code.val, SRLZTN_OBJ_CAMERA) == 0) { pke_deserialize_camera(h, kvec); continue; } @@ -195,10 +228,13 @@ void pke_deserialize_scene_from_stream(std::istream &i, srlztn_deserialize_helpe } else if (state == 1 && strlen(read_line) > 0) { // kve start offset = strchr(read_line, ':') - read_line; s = pk_new<char>(strlen(read_line) + 1); - sprintf(s, "%.*s", (int)offset+1, read_line); - kve.key = s; if (strstr(read_line, "::")) { + offset += 1; state = 2; + } + sprintf(s, "%.*s", (int)offset+1, read_line); + kve.key = s; + if (state == 2) { continue; } read_line[offset] = '\0'; @@ -217,21 +253,23 @@ void pke_deserialize_scene_from_stream(std::istream &i, srlztn_deserialize_helpe state = 3; continue; } - if (state == 3) { - rl = pk_new<char>(strlen(s) + strlen(read_line) + 1, h->bkt); - sprintf(rl, "%s%s", s, read_line); - pk_delete<char>(s, strlen(s) + 1, h->bkt); - s = rl; - continue; - } // multiline end if (strstr(read_line, SRLZTN_MULTILINE_END)) { assert(state >= 2); + kve.val = s; kve.end = SRLZTN_MULTILINE_END; pk_arr_append_t(&kvec.arr, kve); state = 1; continue; } + if (state == 3) { + int sz = snprintf(NULL, 0, "%s%s", s, read_line); + rl = pk_new<char>(sz+1, h->bkt); + sprintf(rl, "%s%s", s, read_line); + pk_delete<char>(s, strlen(s) + 1, h->bkt); + s = rl; + continue; + } // end of object if (state != 2) { state = 0; diff --git a/src/serialization.hpp b/src/serialization.hpp index 93fd92a..1f9df48 100644 --- a/src/serialization.hpp +++ b/src/serialization.hpp @@ -49,19 +49,17 @@ iccsc SRLZTN_CAMERA_IS_PRIMARY = "IsPrimary:"; iccsc SRLZTN_UI_BOX_UUID = "UUID:"; iccsc SRLZTN_UI_BOX_PARENT_UUID = "ParentUUID:"; iccsc SRLZTN_UI_BOX_FLAGS = "Flags:"; -iccsc SRLZTN_UI_BOX_POS_TOP_LEFT_X = "PosTopLeftX:"; -iccsc SRLZTN_UI_BOX_POS_TOP_LEFT_Y = "PosTopLeftY:"; -iccsc SRLZTN_UI_BOX_MIN_WIDTH = "MinWidthX:"; -iccsc SRLZTN_UI_BOX_MIN_HEIGHT = "MinWidthY:"; -iccsc SRLZTN_UI_BOX_MAX_WIDTH = "MaxWidthX:"; -iccsc SRLZTN_UI_BOX_MAX_HEIGHT = "MaxWidthY:"; +iccsc SRLZTN_UI_BOX_POS_TOP_LEFT = "PosTopLeft:"; +iccsc SRLZTN_UI_BOX_MIN_SIZE = "MinSize:"; +iccsc SRLZTN_UI_BOX_MAX_SIZE = "MaxSize:"; iccsc SRLZTN_UI_BOX_FLEX_WEIGHT = "FlexWeight:"; -iccsc SRLZTN_UI_BOX_TYPE = "Type:"; iccsc SRLZTN_UI_BOX_FLEX_DIRECTION = "FlexDirection:"; iccsc SRLZTN_UI_BOX_LAYER = "Layer:"; +iccsc SRLZTN_UI_BOX_TYPE = "Type:"; iccsc SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID = "FontRenderUUID:"; iccsc SRLZTN_UI_FONT_RENDER_UUID = "UUID:"; +iccsc SRLZTN_UI_FONT_RENDER_FONT_TYPE_UUID = "FontTypeUUID:"; iccsc SRLZTN_UI_FONT_RENDER_TEXT_BEGIN = "TextBegin::"; iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE = "CharScale:"; iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE = "LineHeightScale:"; @@ -70,7 +68,7 @@ iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE = "SurfaceAreaSize:"; iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS = "SurfaceAreaPos:"; iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS = "SurfaceAreaFlags:"; -struct srlztn_instance_mapping { +struct srlztn_ecs_mapping { pk_uuid serialized_uuid = pk_uuid_zed; Entity_Base *created_entity = nullptr; CompInstance *created_instance = nullptr; @@ -85,7 +83,7 @@ struct srlztn_serialize_helper { struct srlztn_deserialize_helper { pk_membucket *bkt; pke_scene *scene; - pk_arr_t<srlztn_instance_mapping> mapping; + pk_arr_t<srlztn_ecs_mapping> mapping; pk_arr_t<pke_kve_container> kvp_containers; }; diff --git a/src/static-ui.cpp b/src/static-ui.cpp index 823c015..2f2ce11 100644 --- a/src/static-ui.cpp +++ b/src/static-ui.cpp @@ -3,6 +3,7 @@ #include "dynamic-array.hpp" #include "ecs.hpp" +#include "font.hpp" #include "game-settings.hpp" #include "pk.h" #include "static-plane.hpp" @@ -100,14 +101,14 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl glm::vec2 parent_size_padded; glm::vec2 parent_pos_and_offset; - assert(box->pos_top_left_x >= 0.0); - assert(box->pos_top_left_y >= 0.0); - assert(box->max_width >= 0.0); - assert(box->max_height >= 0.0); - assert(box->min_width >= 0.0); - assert(box->min_height >= 0.0); - assert(box->min_width <= box->max_width); - assert(box->min_height <= box->max_height); + assert(box->pos_top_left.x >= 0.0); + assert(box->pos_top_left.y >= 0.0); + assert(box->max_size.x >= 0.0); + assert(box->max_size.y >= 0.0); + assert(box->min_size.x >= 0.0); + assert(box->min_size.y >= 0.0); + assert(box->min_size.x <= box->max_size.x); + assert(box->min_size.y <= box->max_size.y); if (box->internal.parent != nullptr) { parent_pos_and_offset.x = box->internal.parent->internal.px_corner.x @@ -128,16 +129,16 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl px_size = glm::vec2(Extent.width, Extent.height); } - px_min_size.x = box->min_width; - px_min_size.y = box->min_height; - px_max_size.x = box->max_width; - px_max_size.y = box->max_height; + px_min_size.x = box->min_size.x; + px_min_size.y = box->min_size.y; + px_max_size.x = box->max_size.x; + px_max_size.y = box->max_size.y; box->internal.px_corner.x = 0 + parent_pos_and_offset.x - + box->pos_top_left_x; + + box->pos_top_left.x; box->internal.px_corner.y = 0 + parent_pos_and_offset.y - + box->pos_top_left_y; + + box->pos_top_left.y; if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX)) { assert(flex_params != nullptr); @@ -148,23 +149,23 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl px_size.y = flex_params->px_per_unit * box->flex_weight; } } else if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC)) { - px_size.x -= box->pos_top_left_x; - px_size.y -= box->pos_top_left_y; + px_size.x -= box->pos_top_left.x; + px_size.y -= box->pos_top_left.y; } else { - assert(box->pos_top_left_x < 1.0); - assert(box->pos_top_left_y < 1.0); + assert(box->pos_top_left.x < 1.0); + assert(box->pos_top_left.y < 1.0); box->internal.px_corner.x = parent_pos_and_offset.x; box->internal.px_corner.y = parent_pos_and_offset.y; - float px_left = px_size.x * box->pos_top_left_x; - float px_top = px_size.y * box->pos_top_left_y; + float px_left = px_size.x * box->pos_top_left.x; + float px_top = px_size.y * box->pos_top_left.y; box->internal.px_corner.x += px_left; box->internal.px_corner.y += px_top; px_size.x -= px_left; px_size.y -= px_top; - px_min_size.x = box->min_width * parent_size_padded.x; - px_min_size.y = box->min_height * parent_size_padded.y; - px_max_size.x = box->max_width * parent_size_padded.x; - px_max_size.y = box->max_height * parent_size_padded.y; + px_min_size.x = box->min_size.x * parent_size_padded.x; + px_min_size.y = box->min_size.y * parent_size_padded.y; + px_max_size.x = box->max_size.x * parent_size_padded.x; + px_max_size.y = box->max_size.y * parent_size_padded.y; } px_size = glm::clamp(px_size, px_min_size, px_max_size); @@ -202,10 +203,11 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl if (box->type_data != nullptr) { // type-specific changes if (box->type == PKE_UI_BOX_TYPE_TEXT) { - pke_ui_box_type_data_text *data_text = reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data); - data_text->font_render_settings.surface_area_pos = box->internal.px_corner; - data_text->font_render_settings.surface_area_size = box->internal.px_size; - FontType_UpdateStringRender(data_text->font_render_handle, &data_text->font_render_settings); + FontRender *fr = FontType_GetFontRender(box->type_data->text.font_render_handle); + FontRenderSettings frs = fr->settings; + frs.surface_area_pos = box->internal.px_corner; + frs.surface_area_size = box->internal.px_size; + FontType_UpdateStringRender(box->type_data->text.font_render_handle, &frs); } } @@ -443,13 +445,19 @@ void pke_ui_teardown() { pke_ui_master.bindings.deviceMemoryVert = VK_NULL_HANDLE; } +pke_ui_box **pke_ui_get_root_boxes(pke_ui_box_count_T *count) { + assert(count != nullptr); + *count = pke_ui_master.h_root_boxes; + return pke_ui_master.root_boxes; +} + void pke_ui_internal_new_typed_box(pke_ui_box *box, const PKE_UI_BOX_TYPE type) { assert(box->type == type); switch (type) { case PKE_UI_BOX_TYPE_STANDARD: break; case PKE_UI_BOX_TYPE_TEXT: - box->type_data = pk_new<pke_ui_box_type_data_text>(pke_ui_master.bkt); + box->type_data = pk_new<pke_ui_box_type_data>(pke_ui_master.bkt); box->flags |= PKE_UI_BOX_FLAG_VISIBILITY_INVISIBLE; break; case PKE_UI_BOX_TYPE_INPUT_TEXT: diff --git a/src/static-ui.hpp b/src/static-ui.hpp index 149d588..1b53935 100644 --- a/src/static-ui.hpp +++ b/src/static-ui.hpp @@ -67,14 +67,14 @@ struct pke_ui_box; struct pke_ui_box : public Entity_Base { PKE_UI_BOX_FLAG flags; - float pos_top_left_x, pos_top_left_y; - float min_width, min_height; - float max_width, max_height; + glm::vec2 pos_top_left; + glm::vec2 min_size; + glm::vec2 max_size; float flex_weight; PKE_UI_BOX_TYPE type; uint8_t flex_direction; uint8_t layer; - void *type_data; + union pke_ui_box_type_data *type_data; struct pke_ui_box_internals { // the exact px to translate (shader) glm::vec2 px_corner; @@ -90,10 +90,11 @@ struct pke_ui_box : public Entity_Base { } internal; }; -struct pke_ui_box_type_data_text { - pk_uuid font_render_uuid = pk_uuid_zed; - FontRenderHandle font_render_handle; - FontRenderSettings font_render_settings; +// separate these if they become silly +union pke_ui_box_type_data { + struct pke_ui_box_type_data_text { + FontRenderHandle font_render_handle; + } text; }; struct pke_ui_graphics_bindings { @@ -113,6 +114,8 @@ void pke_ui_init_bindings(); void pke_ui_tick(double delta); void pke_ui_teardown(); +pke_ui_box **pke_ui_get_root_boxes(pke_ui_box_count_T *count); + pke_ui_box *pke_ui_box_new_root(const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD, pk_uuid uuid = pk_uuid_zed); pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD, pk_uuid uuid = pk_uuid_zed); diff --git a/src/vendor-pkh-include.cpp b/src/vendor-pkh-include.cpp index 0d72dcb..75b3fba 100644 --- a/src/vendor-pkh-include.cpp +++ b/src/vendor-pkh-include.cpp @@ -1,5 +1,5 @@ #define PK_MEMORY_DEBUGGER #define PK_IMPL_ALL - +#define PK_ARR_MOVE_IN_PLACE #include "./pk.h" |
