summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile52
-rw-r--r--editor/editor-main.cpp (renamed from editor/main.cpp)0
-rw-r--r--editor/editor.cpp8
-rw-r--r--example/example-export.h (renamed from example/example_export.h)0
-rw-r--r--example/example.cpp2
-rw-r--r--src/array.hpp2
-rw-r--r--src/asset-manager.cpp2
-rw-r--r--src/asset-manager.hpp2
-rw-r--r--src/bucketed-array.hpp2
-rw-r--r--src/camera.hpp4
-rw-r--r--src/components.hpp2
-rw-r--r--src/dynamic-array.hpp2
-rw-r--r--src/ecs.cpp2
-rw-r--r--src/ecs.hpp2
-rw-r--r--src/entities.cpp2
-rw-r--r--src/entities.hpp6
-rw-r--r--src/game-settings.hpp2
-rw-r--r--src/game.cpp6
-rw-r--r--src/level-types.hpp2
-rw-r--r--src/math-helpers.hpp2
-rw-r--r--src/physics.hpp2
-rw-r--r--src/pk.h (renamed from src/vendor/pk.h)728
-rw-r--r--src/player-input.hpp2
-rw-r--r--src/plugins.cpp2
-rw-r--r--src/project-settings.hpp2
-rw-r--r--src/project.cpp17
-rw-r--r--src/static-cube.cpp (renamed from src/static/cube.cpp)2
-rw-r--r--src/static-cube.hpp (renamed from src/static/cube.hpp)0
-rw-r--r--src/static-missing-texture.hpp (renamed from src/static/missing-texture.hpp)0
-rw-r--r--src/thread-pool.cpp (renamed from src/thread_pool.cpp)2
-rw-r--r--src/thread-pool.hpp (renamed from src/thread_pool.hpp)2
-rw-r--r--src/tinyfiledialogs.LICENSE (renamed from src/vendor/tinyfiledialogs/LICENSE)0
-rw-r--r--src/vendor-cgltf-include.cpp5
-rw-r--r--src/vendor-cgltf-include.hpp (renamed from src/vendor/cgltf-include.hpp)0
-rw-r--r--src/vendor-glm-include.hpp (renamed from src/vendor/glm_include.hpp)0
-rw-r--r--src/vendor-pkh-include.cpp (renamed from src/vendor/pkh_include.cpp)0
-rw-r--r--src/vendor-stb-image-include.cpp (renamed from src/vendor/stb_image_include.cpp)2
-rw-r--r--src/vendor-stb-image-include.hpp (renamed from src/vendor/stb_image_include.hpp)0
-rw-r--r--src/vendor-tinyfiledialogs.c (renamed from src/vendor/tinyfiledialogs/tinyfiledialogs.c)2
-rw-r--r--src/vendor-tinyfiledialogs.h (renamed from src/vendor/tinyfiledialogs/tinyfiledialogs.h)0
-rw-r--r--src/vendor/cgltf-include.cpp5
-rw-r--r--src/window.cpp4
-rw-r--r--src/window.hpp2
43 files changed, 777 insertions, 104 deletions
diff --git a/Makefile b/Makefile
index 93c95fb..b29bf4d 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@ DIR_BIN=bin
DIR_DBG=dbg
SRC = \
- src/vendor/pkh_include.cpp \
+ src/vendor-pkh-include.cpp \
src/arg-handler.cpp \
src/camera.cpp \
src/ecs.cpp \
@@ -47,18 +47,18 @@ SRC = \
src/plugins.cpp \
src/project.cpp \
src/project-settings.cpp \
- src/static/cube.cpp \
- src/thread_pool.cpp \
- src/vendor/cgltf-include.cpp \
- src/vendor/stb_image_include.cpp \
- src/vendor/tinyfiledialogs/tinyfiledialogs.c \
+ src/static-cube.cpp \
+ src/thread-pool.cpp \
+ src/vendor-cgltf-include.cpp \
+ src/vendor-stb-image-include.cpp \
+ src/vendor-tinyfiledialogs.c \
src/window.cpp \
DST_SHADERS = \
- $(DIR_OBJ)/vertex.vert.spv \
- $(DIR_OBJ)/present.vert.spv \
- $(DIR_OBJ)/texture.frag.spv \
- $(DIR_OBJ)/present.frag.spv \
+ $(DIR_OBJ)/shaders/vertex.vert.spv \
+ $(DIR_OBJ)/shaders/present.vert.spv \
+ $(DIR_OBJ)/shaders/texture.frag.spv \
+ $(DIR_OBJ)/shaders/present.frag.spv \
SRC_C = $(filter %.c,$(SRC))
SRC_CXX = $(filter %.cpp,$(SRC))
@@ -75,11 +75,17 @@ OUT_SOBJ = $(TMP_OUT_SOBJ:%.so=$(DIR_OBJ)/%.so)
OUT_CXXOBJ = $(TMP_OUT_CXXOBJ:%.o=$(DIR_OBJ)/%.o)
OUT_CXXSOBJ = $(TMP_OUT_CXXSOBJ:%.so=$(DIR_OBJ)/%.so)
+.PHONY: default
+default: options $(DIR_BIN)/pke-editor $(DIR_BIN)/libpke-example.a $(DIR_BIN)/pke-runtime ;
+
+.PHONY: default-dbg
+default-dbg: options $(DIR_DBG)/pke-editor $(DIR_DBG)/libpke-example.a $(DIR_DBG)/pke-runtime ;
+
.PHONY: prepare
prepare:
- mkdir -p $(DIR_BIN) $(DIR_DBG) $(DIR_OBJ) $(DIR_DBG)/bullet3 $(DIR_BIN)/bullet3
- mkdir -p $(DIR_BIN)/bullet3 $(DIR_BIN)/assets/shaders
- mkdir -p $(DIR_DBG)/bullet3 $(DIR_DBG)/assets/shaders
+ mkdir -p $(DIR_BIN) $(DIR_DBG) $(DIR_OBJ) $(DIR_OBJ)/shaders $(DIR_DBG)/bullet3 $(DIR_BIN)/bullet3
+ mkdir -p $(DIR_BIN)/bullet3
+ mkdir -p $(DIR_DBG)/bullet3
.PHONY: options
options: prepare .WAIT
@@ -111,9 +117,9 @@ $(DIR_OBJ)/%.o: sub/imgui/misc/cpp/%.cpp
$(DIR_OBJ)/%.so: sub/imgui/misc/cpp/%.cpp
$(cxx-dbg-command) -Isub/imgui
-$(DIR_OBJ)/%.vert.spv: assets/shaders/%.vert
+$(DIR_OBJ)/shaders/%.vert.spv: assets/shaders/%.vert
$(GLSLC) $^ -o $@
-$(DIR_OBJ)/%.frag.spv: assets/shaders/%.frag
+$(DIR_OBJ)/shaders/%.frag.spv: assets/shaders/%.frag
$(GLSLC) $^ -o $@
$(DIR_OBJ)/%.o : src/%.c
@@ -129,14 +135,6 @@ $(DIR_OBJ)/%.o : src/%.cpp
$(cxx-bin-command) $(FLG_PKE)
$(DIR_OBJ)/%.so : src/%.cpp
$(cxx-dbg-command) $(FLG_PKE)
-$(DIR_OBJ)/%.o : src/static/%.cpp
- $(cxx-bin-command) $(FLG_PKE)
-$(DIR_OBJ)/%.so : src/static/%.cpp
- $(cxx-dbg-command) $(FLG_PKE)
-$(DIR_OBJ)/%.o : src/vendor/%.cpp
- $(cxx-bin-command) $(FLG_PKE)
-$(DIR_OBJ)/%.so : src/vendor/%.cpp
- $(cxx-dbg-command) $(FLG_PKE)
$(DIR_OBJ)/%.o : editor/%.cpp
$(cxx-bin-command) $(FLG_EDT)
$(DIR_OBJ)/%.so : editor/%.cpp
@@ -200,16 +198,20 @@ $(DIR_DBG)/libpke.a:
ar rc $@ $(filter %.so,$^)
ranlib $@
+$(DIR_BIN)/libpke-example.a: $(DIR_OBJ)/example.o
+ ar rc $@ $(filter %.o,$^)
+ ranlib $@
+
$(DIR_DBG)/libpke-example.a: $(DIR_OBJ)/example.so
ar rc $@ $(filter %.so,$^)
ranlib $@
$(DIR_BIN)/pke-editor: $(DIR_BIN)/libpke.a $(DIR_BIN)/libImgui.a $(DIR_BIN)/libBullet3.a
-$(DIR_BIN)/pke-editor: $(DIR_OBJ)/main.o $(DIR_OBJ)/editor.o
+$(DIR_BIN)/pke-editor: $(DIR_OBJ)/editor-main.o $(DIR_OBJ)/editor.o
$(CXX) -v -std=c++23 $(INCS) $^ $(LDFLAGS) $(CXXFLAGS) -g -O0 -o $@
$(DIR_DBG)/pke-editor: $(DIR_DBG)/libpke.a $(DIR_DBG)/libImgui.a $(DIR_DBG)/libBullet3.a
-$(DIR_DBG)/pke-editor: $(DIR_OBJ)/main.so $(DIR_OBJ)/editor.so
+$(DIR_DBG)/pke-editor: $(DIR_OBJ)/editor-main.so $(DIR_OBJ)/editor.so
@echo $^
$(CXX) -v -std=c++23 $(INCS) $^ $(LDFLAGS) $(CXXFLAGS) -g -O0 -o $@
diff --git a/editor/main.cpp b/editor/editor-main.cpp
index 2dee016..2dee016 100644
--- a/editor/main.cpp
+++ b/editor/editor-main.cpp
diff --git a/editor/editor.cpp b/editor/editor.cpp
index 86fae96..8a2390b 100644
--- a/editor/editor.cpp
+++ b/editor/editor.cpp
@@ -14,11 +14,11 @@
#include "player-input.hpp"
#include "plugins.hpp"
#include "project.hpp"
-#include "thread_pool.hpp"
-#include "vendor/glm_include.hpp"
-#include "vendor/tinyfiledialogs//tinyfiledialogs.h"
+#include "thread-pool.hpp"
+#include "vendor-glm-include.hpp"
+#include "vendor-tinyfiledialogs.h"
#include "window.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <GLFW/glfw3.h>
#include <compare>
diff --git a/example/example_export.h b/example/example-export.h
index 53bf208..53bf208 100644
--- a/example/example_export.h
+++ b/example/example-export.h
diff --git a/example/example.cpp b/example/example.cpp
index 17a79a3..911c2cd 100644
--- a/example/example.cpp
+++ b/example/example.cpp
@@ -2,7 +2,7 @@
#include "example.hpp"
#include "components.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
void OnEntityTypeCollision(const void *lhs, const void *rhs) {
fprintf(stdout, "[Example::OnEntityTypeCollision] Called\n");
diff --git a/src/array.hpp b/src/array.hpp
index 8878ce4..a1fa69f 100644
--- a/src/array.hpp
+++ b/src/array.hpp
@@ -1,7 +1,7 @@
#ifndef PKE_ARRAY_HPP
#define PKE_ARRAY_HPP
-#include "vendor/pk.h"
+#include "pk.h"
#include <cstdint>
#include <cstring>
diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp
index fc24a48..dbc74ca 100644
--- a/src/asset-manager.cpp
+++ b/src/asset-manager.cpp
@@ -2,7 +2,7 @@
#include "asset-manager.hpp"
#include "bucketed-array.hpp"
-#include "thread_pool.hpp"
+#include "thread-pool.hpp"
#include <chrono>
#include <filesystem>
diff --git a/src/asset-manager.hpp b/src/asset-manager.hpp
index 4d96c59..25ebffb 100644
--- a/src/asset-manager.hpp
+++ b/src/asset-manager.hpp
@@ -1,7 +1,7 @@
#ifndef PKE_ASSET_MANAGER_HPP
#define PKE_ASSET_MANAGER_HPP
-#include "vendor/pk.h"
+#include "pk.h"
#include <cstdint>
#include <future>
diff --git a/src/bucketed-array.hpp b/src/bucketed-array.hpp
index 0f8b395..cf34bdd 100644
--- a/src/bucketed-array.hpp
+++ b/src/bucketed-array.hpp
@@ -4,7 +4,7 @@
#include <cstddef>
#include <cassert>
-#include "vendor/pk.h"
+#include "pk.h"
constexpr pk_handle_bucket_index_T BucketContainerDefaultBucketCount = 16;
constexpr pk_handle_item_index_T BucketContainerDefaultItemCount = 256;
diff --git a/src/camera.hpp b/src/camera.hpp
index 156aa5c..f4cc986 100644
--- a/src/camera.hpp
+++ b/src/camera.hpp
@@ -1,9 +1,9 @@
#ifndef PKE_CAMERA_HPP
#define PKE_CAMERA_HPP
-#include "vendor/pk.h"
+#include "pk.h"
#include "components.hpp"
-#include "vendor/glm_include.hpp"
+#include "vendor-glm-include.hpp"
#include <cstdint>
diff --git a/src/components.hpp b/src/components.hpp
index 025d5f0..50d1487 100644
--- a/src/components.hpp
+++ b/src/components.hpp
@@ -2,7 +2,7 @@
#define PKE_COMPONENTS_HPP
#include "dynamic-array.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include "physics.hpp"
#include "plugin-types.hpp"
diff --git a/src/dynamic-array.hpp b/src/dynamic-array.hpp
index a676b40..06479db 100644
--- a/src/dynamic-array.hpp
+++ b/src/dynamic-array.hpp
@@ -1,7 +1,7 @@
#ifndef PKE_DYNAMIC_ARRAY_HPP
#define PKE_DYNAMIC_ARRAY_HPP
-#include "vendor/pk.h"
+#include "pk.h"
#include <cstdint>
#include <cstring>
diff --git a/src/ecs.cpp b/src/ecs.cpp
index d6bf8df..7f3410d 100644
--- a/src/ecs.cpp
+++ b/src/ecs.cpp
@@ -6,7 +6,7 @@
#include "game-settings.hpp"
#include "math-helpers.hpp"
#include "physics.hpp"
-#include "vendor/glm_include.hpp"
+#include "vendor-glm-include.hpp"
#include "window.hpp"
#include <btBulletDynamicsCommon.h>
diff --git a/src/ecs.hpp b/src/ecs.hpp
index 07972d3..6a8ad8f 100644
--- a/src/ecs.hpp
+++ b/src/ecs.hpp
@@ -3,7 +3,7 @@
#include "array.hpp"
#include "dynamic-array.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include "components.hpp"
#include "glm/vec3.hpp"
diff --git a/src/entities.cpp b/src/entities.cpp
index 609fc51..e955578 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -6,7 +6,7 @@
#include "math-helpers.hpp"
#include "physics.hpp"
#include "plugins.hpp"
-#include "static/missing-texture.hpp"
+#include "static-missing-texture.hpp"
#include "window.hpp"
#include <BulletCollision/CollisionShapes/btConvexHullShape.h>
diff --git a/src/entities.hpp b/src/entities.hpp
index d81b90b..b711935 100644
--- a/src/entities.hpp
+++ b/src/entities.hpp
@@ -1,13 +1,13 @@
#ifndef PKE_ENTITIES_HPP
#define PKE_ENTITIES_HPP
-#include "vendor/cgltf-include.hpp"
-#include "vendor/stb_image_include.hpp"
+#include "vendor-cgltf-include.hpp"
+#include "vendor-stb-image-include.hpp"
#include "ecs.hpp"
#include "components.hpp"
#include "asset-manager.hpp"
#include "window.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
#include <vulkan/vulkan_core.h>
diff --git a/src/game-settings.hpp b/src/game-settings.hpp
index 89862a8..f5f6301 100644
--- a/src/game-settings.hpp
+++ b/src/game-settings.hpp
@@ -2,7 +2,7 @@
#define PKE_GAME_SETTINGS_HPP
#include "level-types.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <chrono>
#include <cstdint>
diff --git a/src/game.cpp b/src/game.cpp
index 8fb24e4..1a95a79 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -17,10 +17,10 @@
#include "player-input.hpp"
#include "plugins.hpp"
#include "project.hpp"
-#include "thread_pool.hpp"
-#include "vendor/glm_include.hpp"
+#include "thread-pool.hpp"
+#include "vendor-glm-include.hpp"
#include "window.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <BulletCollision/CollisionShapes/btConvexHullShape.h>
#include <BulletCollision/NarrowPhaseCollision/btRaycastCallback.h>
diff --git a/src/level-types.hpp b/src/level-types.hpp
index a70282f..b0abce6 100644
--- a/src/level-types.hpp
+++ b/src/level-types.hpp
@@ -2,7 +2,7 @@
#define PKE_LEVEL_TYPES_HPP
#include "array.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include "camera.hpp"
#include "components.hpp"
diff --git a/src/math-helpers.hpp b/src/math-helpers.hpp
index 9276df8..2039348 100644
--- a/src/math-helpers.hpp
+++ b/src/math-helpers.hpp
@@ -1,7 +1,7 @@
#ifndef PKE_MATH_HELPERS_HPP
#define PKE_MATH_HELPERS_HPP
-#include "vendor/glm_include.hpp"
+#include "vendor-glm-include.hpp"
#include <LinearMath/btQuaternion.h>
#include <LinearMath/btVector3.h>
#include <LinearMath/btTransform.h>
diff --git a/src/physics.hpp b/src/physics.hpp
index 0cfe49a..38a90cd 100644
--- a/src/physics.hpp
+++ b/src/physics.hpp
@@ -1,7 +1,7 @@
#ifndef PKE_PHYSICS_HPP
#define PKE_PHYSICS_HPP
-#include "vendor/pk.h"
+#include "pk.h"
#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
diff --git a/src/vendor/pk.h b/src/pk.h
index 8d788d1..49b735f 100644
--- a/src/vendor/pk.h
+++ b/src/pk.h
@@ -1,30 +1,184 @@
#ifndef PK_SINGLE_HEADER_FILE_H
#define PK_SINGLE_HEADER_FILE_H
-/******************************************************************************
-* PK Single-Header-Library V0.0.2
+/*******************************************************************************
+* PK Single-Header-Library V0.1.1
*
* Author: Jonathan Bradley
-* Copyright: © 2024-2024 Jonathan Bradley
+* Copyright: © 2024-2025 Jonathan Bradley
* Description:
*
-*******************************************************************************
+* A collection of useful programming tools, available for C and C++ as a
+* single-header file. To enable, in ONE single C or C++ file, declare
+* PK_IMPL_ALL before including pk.h.
+*
+* Example:
+*
+* pk.h.include.c
+* ``` c
+* #define PK_IMPL_ALL
+* #include "pk.h"
+* ```
+*
+* It is also possible to enable modules ad-hoc by defining each IMPL
+* individually:
+*
+* pk.h.include.c
+* ``` c
+* # define PK_IMPL_MEM_TYPES
+* # define PK_IMPL_MEM
+* # define PK_IMPL_STR
+* # define PK_IMPL_EV
+* # define PK_IMPL_ARR
+* # define PK_IMPL_STN
+* #include "pk.h"
+* ```
+*
+********************************************************************************
* pkmacros.h:
*
-*******************************************************************************
-* pkmem-types.h:
+* Provides a set of useful macros for a variety of uses.
+*
+* The macros PK_LOG* provide simple logging utilities. These can be overridden
+* by providing your own implementations of each and defining PK_LOG_OVERRIDE
+* before including pk.h Note that each of these are no-op'd if NDEBUG is
+* defined.
+*
+* The TypeSafeInt_H and TypeSafeInt_B macros provide a way to define
+* type-specific integers, implemented via enums.
+*
+********************************************************************************
+* pkmem-types.h: def PK_IMPL_MEM_TYPES before including pk.h to enable ad-hoc.
+*
+* Provides the types needed by pkmem, as well as a generic pk_handle featuring a
+* bucket+item indexing system.
+*
+********************************************************************************
+* pkmem.h: def PK_IMPL_MEM before including pk.h to enable ad-hoc.
+*
+* A bucketed memory manager. Allows for the creation and management of up to a
+* well-defined number of buckets.
+*
+* Thread safety: Bucket creation and destruction is *not* thread-safe. On the
+* other hand, the "pk_new" and "pk_delete" methods *are* thread-safe, but
+* thread-safety is implemented per-bucket via a single mutex with long-running
+* lock times. PRs for a more performant thread-safe strategy are welcome,
+* complexity and benchmark depending.
+*
+* The following definitions (shown with defaults) can be overridden:
+* PK_DEFAULT_BUCKET_SIZE 256MB (used when bkt is NULL on first call)
+* PK_MINIMUM_ALIGNMENT 1
+* PK_MAXIMUM_ALIGNMENT 64
+* PK_MAX_BUCKET_COUNT 8
+*
+* For debugging purposes, define the following:
+* PK_MEMORY_DEBUGGER : enables a tracking system for all allocs and frees to
+* ensure bucket validity and consistency.
+* PK_MEMORY_FORCE_MALLOC : completely disables pkmem and its debugging features
+* in favor of directly using malloc and free. Useful for out-of-bounds
+* checking.
+*
+********************************************************************************
+* pkstr.h: def PK_IMPL_STR before including pk.h to enable ad-hoc.
+*
+* Provides a simple string structure, allowing the user to track the string
+* length and reserved buffer length. Limits max string length to uint32_t max
+* size, which is roughly 4GB.
+*
+* Tip: set reserved to 0 for compile-time strings as well as for strings alloc'd
+* in a larger buffer (such as bulk-loaded data).
+*
+********************************************************************************
+* pkev.h: def PK_IMPL_EV before including pk.h to enable ad-hoc.
+*
+* Provides a simple event callback system. While the _init and _teardown
+* functions are NOT thread-safe, the _register and _emit functions are.
+* Note: uses malloc.
+*
+* Each mgr is stored contiguously with its data. Consider the following layout:
+* [[mgr][ev 0][ev 1][..][ev N][ev 1 cb array][ev 2 cb array][..][ev N cb array]]
+*
+* The following definitions (shown with defaults) can be overridden:
+* PK_EV_INIT_MGR_COUNT 1
+* PK_EV_INIT_EV_COUNT 16
+* PK_EV_INIT_CB_COUNT 8
+* PK_EV_GROW_RATIO 1.5
+*
+* The number of evs and cbs (per ev) is stored as a uint8_t, so a hard-limit of
+* 255 is to be observed for each. The number of mgrs is stored as a uint64_t.
+*
+* Note that PK_EV_GROW_RATIO is used in two scenarios:
+* 1. When registering an ev on a full mgr.
+* 2. When registering a cb on a full ev.
+* The grow ratio is applied to the ev count and cb count in their respective
+* scenarios. This causes a new allocation for the entire mgr. The existing
+* mgr and its evs and cbs are copied to the new larger buffer space.
+* Explicitly, the number of mgrs does not grow dynamically. Use
+* PK_EV_INIT_MGR_COUNT to control the number of mgrs.
+*
+* Note that increasing PK_EV_INIT_MGR_COUNT isn't recommended, but you may
+* consider doing so if you have specific size or contiguity requirements. For
+* example, you could -DPK_EV_INIT_EV_COUNT=1 to reduce the memory footprint of
+* each event/mgr, and simply create a new mgr for each needed event. Be aware
+* that in this provided scenario a given mgr will still grow if a second EV is
+* registered.
+*
+********************************************************************************
+* pkarr.h: def PK_IMPL_ARR before including pk.h to enable ad-hoc
+*
+* Provides a structure for managing contiguous lists
*
-*******************************************************************************
-* pkmem.h:
+* The following definitions (shown with defaults) can be overridden:
+* PK_ARR_INITIAL_COUNT 16
+* PK_ARR_GROW_RATIO 1.5
+* PK_ARR_MOVE_IN_PLACE (not defined)
*
-*******************************************************************************
-* pkstr.h:
+* The macro `PK_ARR_MOVE_IN_PLACE` ensures that when possible, the pointer value
+* of `arr->data` is preserved.
+* It is used in the following methods:
+* `pk_arr_move_to_back`
+* `pk_arr_remove_at`
+* This has two additinal benefits:
+* 1. Minimizing the number and `sz` of calls to `pk_new`
+* 2. Ensuring `data[0]` to `data[(N - 1) * stride]` is not copied extraneously
+* to a new buffer.
+* The speed of this will vary depending on usage, platform, and compiler.
*
-*******************************************************************************
-* pkev.h:
+* Initialize `stride`, `alignment`, and `bkt` (optional) members
+* *before* calling any `pk_arr_*` methods.
*
-******************************************************************************/
+* Examples:
+* ``` c
+* struct pk_arr arr = {0};
+* arr.stride = sizeof(obj); // required
+* arr.alignment = alignof(obj); // required
+* arr.bkt = bkt; // optional
+* pk_arr_reserve(&arr, 10); // optional
+* pk_arr_append(&arr, &obj);
+* ```
+* ``` c
+* struct pk_arr arr = {0};
+* arr.stride = sizeof(obj); // required
+* arr.alignment = alignof(obj); // required
+* arr.bkt = bkt; // optional
+* pk_arr_resize(&arr, 10);
+* obj* d = (obj*)arr->data;
+* d[0] = ...;
+* ```
+*
+********************************************************************************
+* pkstn.h: def PK_IMPL_STN before including pk.h to enable ad-hoc.
+*
+* Provides a thorough interface for interacting with the `stoi` family of
+* procedures.
+*
+********************************************************************************
+* pktmr.h: No IMPL define, all methods are macros.
+*
+* Offers a set of `pk_tmr*` macros for elapsed time checking.
+*
+*******************************************************************************/
-#define PK_VERSION "0.0.2"
+#define PK_VERSION "0.1.1"
#ifdef PK_IMPL_ALL
# ifndef PK_IMPL_MEM_TYPES
@@ -39,6 +193,12 @@
# ifndef PK_IMPL_EV
# define PK_IMPL_EV
# endif
+# ifndef PK_IMPL_ARR
+# define PK_IMPL_ARR
+# endif
+# ifndef PK_IMPL_STN
+# define PK_IMPL_STN
+# endif
#endif
#ifndef PK_MACROS_H
#define PK_MACROS_H
@@ -279,7 +439,6 @@ struct pk_handle {
enum PK_HANDLE_VALIDATION pk_handle_validate(const struct pk_handle handle, const struct pk_handle bucketHandle, const uint64_t maxItems);
-
#if defined(__cplusplus)
constexpr struct pk_handle pk_handle_MAX_constexpr = (struct pk_handle){ .bucketIndex = 0xFFFFFFFF, .itemIndex = 0xFFFFFFFF };
@@ -354,8 +513,10 @@ bool pk_memory_is_in_bucket(const void* ptr, const struct pk_membucket* bkt);
void* pk_new_base(size_t sz, size_t alignment);
void* pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt);
+void* pk_new(size_t sz, size_t alignment, struct pk_membucket* bkt);
void pk_delete_base(const void* ptr, size_t sz);
void pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt);
+void pk_delete(const void* ptr, size_t sz, struct pk_membucket* bkt);
#if defined(__cplusplus)
@@ -447,6 +608,10 @@ static inline void pkmem_stupid_header_warnings() { (void)stdout; }
*/
#endif
+#ifndef PK_MAX_BUCKET_COUNT
+# define PK_MAX_BUCKET_COUNT 8
+#endif
+
struct pk_memblock {
char* data;
size_t size;
@@ -479,7 +644,7 @@ struct pk_membucket {
bool transient;
};
-static struct pk_membucket pk_buckets[8];
+static struct pk_membucket pk_buckets[PK_MAX_BUCKET_COUNT];
static int64_t pk_bucket_head = 0;
#ifdef PK_MEMORY_DEBUGGER
@@ -531,22 +696,22 @@ pk_memory_debug_print()
void
pk_memory_flush()
{
- for (long i = pk_bucket_head - 2; i > -1; --i) {
+ for (long i = pk_bucket_head - 1; i > -1; --i) {
if (pk_buckets[i].head != 0) break;
- if (pk_buckets[i+1].head != 0) break;
if (pk_buckets[i].transient == true) break;
- if (pk_buckets[i+1].transient == true) break;
pk_bucket_head--;
- pk_bucket_destroy(&pk_buckets[i + 1]);
+ if (pk_buckets[i].raw == CAFE_BABE(void)) continue;
+ pk_bucket_destroy(&pk_buckets[i]);
}
}
void
pk_memory_teardown_all()
{
- for (int64_t i = pk_bucket_head - 1; i > 0; --i) {
- if (pk_buckets[i].ptr == nullptr) continue;
- pk_bucket_destroy(&pk_buckets[i]);
+ for (int64_t i = pk_bucket_head; i > 0; --i) {
+ if (pk_buckets[i - 1].ptr == nullptr) continue;
+ if (pk_buckets[i - 1].ptr == CAFE_BABE(char)) continue;
+ pk_bucket_destroy(&pk_buckets[i - 1]);
}
pk_bucket_head = 0;
}
@@ -554,6 +719,7 @@ pk_memory_teardown_all()
static int64_t
pk_bucket_create_inner(int64_t sz, bool transient, const char* description)
{
+ assert(pk_bucket_head < PK_MAX_BUCKET_COUNT && "pkmem.h: reserved bucket count exceeded");
#ifdef PK_MEMORY_DEBUGGER
if (has_init_debug == false) {
has_init_debug = true;
@@ -569,6 +735,7 @@ pk_bucket_create_inner(int64_t sz, bool transient, const char* description)
bkt->lastEmptyBlockIndex = 0;
bkt->maxBlockCount = blockCount < 10 ? 10 : blockCount;
bkt->blocks = (struct pk_memblock*)malloc(sz);
+ mtx_init(&bkt->mtx, mtx_plain);
assert(bkt->blocks != nullptr && "failed to allocate memory");
#if 1
memset(bkt->blocks, 0, sz);
@@ -600,7 +767,7 @@ pk_bucket_destroy(struct pk_membucket* bkt)
int64_t i;
for (i = 0; i < pk_bucket_head; ++i) {
if (&pk_buckets[i] == bkt) {
- if (pk_bucket_head == i)
+ if (pk_bucket_head == i + 1)
pk_bucket_head--;
break;
}
@@ -615,6 +782,7 @@ pk_bucket_destroy(struct pk_membucket* bkt)
bkt->blocks = CAFE_BABE(struct pk_memblock);
bkt->ptr = CAFE_BABE(char);
bkt->transient = false;
+ mtx_destroy(&bkt->mtx);
#ifdef PK_MEMORY_DEBUGGER
for (i = debug_alloc_head; i > -1; --i) {
if (debug_all_allocs[i].bkt == bkt) {
@@ -628,7 +796,9 @@ pk_bucket_destroy(struct pk_membucket* bkt)
void
pk_bucket_reset(struct pk_membucket* bkt)
{
+#ifdef PK_MEMORY_DEBUGGER
int64_t i;
+#endif
if (bkt->transient != true) {
PK_LOG_ERR("WARNING: pk_bucket_reset called on non-transient pk_membucket\n");
}
@@ -717,7 +887,10 @@ pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt)
break;
}
}
- assert(block != nullptr && "memory corruption: failed to find bucket with enough space");
+ if (block == nullptr) {
+ mtx_unlock(&bkt->mtx);
+ assert(block != nullptr && "memory corruption: not enough space in chosen bkt");
+ }
data = block->data + misalignment;
#ifdef PK_MEMORY_DEBUGGER
bool handled = bkt->transient;
@@ -805,6 +978,13 @@ pk_new_base(size_t sz, size_t alignment)
return pk_new_bkt(sz, alignment, bkt);
}
+void*
+pk_new(size_t sz, size_t alignment, struct pk_membucket* bkt)
+{
+ if (bkt != NULL) return pk_new_bkt(sz, alignment, bkt);
+ return pk_new_base(sz, alignment);
+}
+
void
pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt)
{
@@ -822,7 +1002,7 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt)
if (mb->bkt != bkt) continue;
if (mb->blk.size == 0) continue;
if ((void*)(mb->blk.data) == ptr) {
- assert(mb->blk.size == sz && "[PK_MEMORY_HPP] incorrect free size");
+ assert(mb->blk.size == sz && "[pkmem.h] incorrect free size");
mb->blk.size = 0;
mb->bkt = NULL;
found = true;
@@ -833,7 +1013,7 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt)
}
}
}
- assert(found && "[PK_MEMORY_HPP] double free or invalid ptr");
+ assert(found && "[pkmem.h] double free or invalid ptr");
#endif
bkt->allocs--;
if (bkt->allocs == 0) {
@@ -912,6 +1092,13 @@ pk_delete_base(const void* ptr, size_t sz)
pk_delete_bkt(ptr, sz, bkt);
}
+void
+pk_delete(const void* ptr, size_t sz, struct pk_membucket* bkt)
+{
+ if (bkt != NULL) return pk_delete_bkt(ptr, sz, bkt);
+ return pk_delete_base(ptr, sz);
+}
+
#endif /* PK_IMPL_MEM */
#ifndef PK_STR_H
#define PK_STR_H
@@ -1021,6 +1208,7 @@ void pk_ev_emit(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, void *user_emit_data);
#ifdef PK_IMPL_EV
+
#include <assert.h>
#include <stdatomic.h>
#include <stdio.h>
@@ -1108,6 +1296,8 @@ pk_ev_teardown()
static struct pk_ev_mgr*
pk_ev_inner_ev_mgr_create(uint64_t ev_count, uint64_t cb_count)
{
+ assert(ev_count < 0x100);
+ assert(cb_count < 0x100);
int i;
struct pk_ev *ev;
size_t sz = sizeof(struct pk_ev_mgr) + ((sizeof(struct pk_ev) * ev_count)) + (sizeof (struct pk_ev_cb) * ev_count * cb_count);
@@ -1194,11 +1384,18 @@ const pk_ev_id_T
pk_ev_register_ev(pk_ev_mgr_id_T evmgr, void *user_ev_data)
{
assert(evmgr < 64);
+ uint64_t new_size;
pk_ev_id_T id;
struct pk_ev_mgr *mgr;
mtx_lock(&pk_ev_mstr.mtxs[evmgr]);
if (pk_ev_mstr.mgrs[evmgr]->n_ev == pk_ev_mstr.mgrs[evmgr]->rn_ev) {
- mgr = pk_ev_inner_ev_mgr_create(pk_ev_mstr.mgrs[evmgr]->rn_ev * PK_EV_GROW_RATIO, pk_ev_mstr.mgrs[evmgr]->rn_cb);
+ new_size = PK_MAX(2, PK_MIN(255, pk_ev_mstr.mgrs[evmgr]->rn_ev * PK_EV_GROW_RATIO));
+ if (new_size == pk_ev_mstr.mgrs[evmgr]->rn_ev) {
+ PK_LOG_ERR("[pkev.h] need more room, but failed to grow ev count.\n");
+ mtx_unlock(&pk_ev_mstr.mtxs[evmgr]);
+ exit(1);
+ }
+ mgr = pk_ev_inner_ev_mgr_create(new_size, pk_ev_mstr.mgrs[evmgr]->rn_cb);
pk_ev_inner_ev_mgr_clone(pk_ev_mstr.mgrs[evmgr], mgr);
free(pk_ev_mstr.mgrs[evmgr]);
pk_ev_mstr.mgrs[evmgr] = mgr;
@@ -1213,11 +1410,18 @@ bool
pk_ev_register_cb(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, pk_ev_cb_fn *cb, void *user_cb_data)
{
assert(evmgr < 64);
+ uint64_t new_size;
struct pk_ev_mgr *mgr;
uint8_t cb_index;
mtx_lock(&pk_ev_mstr.mtxs[evmgr]);
if (pk_ev_mstr.mgrs[evmgr]->ev[evid].n_ev_cbs == pk_ev_mstr.mgrs[evmgr]->rn_cb) {
- mgr = pk_ev_inner_ev_mgr_create(pk_ev_mstr.mgrs[evmgr]->rn_ev, pk_ev_mstr.mgrs[evmgr]->rn_cb * PK_EV_GROW_RATIO);
+ new_size = PK_MAX(2, PK_MIN(255, pk_ev_mstr.mgrs[evmgr]->rn_cb * PK_EV_GROW_RATIO));
+ if (new_size == pk_ev_mstr.mgrs[evmgr]->rn_cb) {
+ PK_LOG_ERR("[pkev.h] need more room, but failed to grow cb count.\n");
+ mtx_unlock(&pk_ev_mstr.mtxs[evmgr]);
+ exit(1);
+ }
+ mgr = pk_ev_inner_ev_mgr_create(pk_ev_mstr.mgrs[evmgr]->rn_ev, new_size);
pk_ev_inner_ev_mgr_clone(pk_ev_mstr.mgrs[evmgr], mgr);
free(pk_ev_mstr.mgrs[evmgr]);
pk_ev_mstr.mgrs[evmgr] = mgr;
@@ -1243,4 +1447,470 @@ pk_ev_emit(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, void *user_emit_data)
}
#endif /* PK_IMPL_EV */
+#ifndef PK_PKARR_H
+#define PK_PKARR_H
+
+#include <stdint.h>
+
+struct pk_arr {
+ uint32_t next;
+ uint32_t reserved;
+ uint32_t stride;
+ uint32_t alignment;
+ struct pk_membucket *bkt;
+ void *data;
+};
+
+typedef bool(pk_arr_item_compare)(void *user_data, void *item);
+
+void pk_arr_clear(struct pk_arr *arr);
+void pk_arr_reset(struct pk_arr *arr);
+void pk_arr_reserve(struct pk_arr *arr, uint32_t count);
+void pk_arr_resize(struct pk_arr *arr, uint32_t count);
+void pk_arr_move_to_back(struct pk_arr *arr, uint32_t index);
+void pk_arr_append(struct pk_arr *arr, void *data);
+void pk_arr_remove_at(struct pk_arr *arr, uint32_t index);
+uint32_t pk_arr_find_first_index(struct pk_arr *arr, void *user_data, pk_arr_item_compare *fn);
+
+#endif /* PK_PKARR_H */
+#ifdef PK_IMPL_ARR
+
+
+#ifndef PK_ARR_GROW_RATIO
+#define PK_ARR_GROW_RATIO 1.5
+#endif
+#ifndef PK_ARR_INITIAL_COUNT
+#define PK_ARR_INITIAL_COUNT 16
+#endif
+
+void
+pk_arr_clear(struct pk_arr *arr)
+{
+ arr->next = 0;
+}
+
+void
+pk_arr_reset(struct pk_arr *arr)
+{
+ if (arr->data != NULL) pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt);
+ arr->data = NULL;
+ arr->next = 0;
+ arr->reserved = 0;
+}
+
+void
+pk_arr_reserve(struct pk_arr *arr, uint32_t count)
+{
+ if (arr->reserved >= count) return;
+ void *new_data = pk_new(arr->stride * count, arr->alignment, arr->bkt);
+ if (arr->data != NULL) {
+ if (arr->next != 0) {
+ memcpy(new_data, arr->data, arr->stride * arr->reserved);
+ }
+ pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt);
+ }
+ arr->reserved = count;
+ arr->data = new_data;
+}
+
+void
+pk_arr_resize(struct pk_arr *arr, uint32_t count)
+{
+ pk_arr_reserve(arr, count);
+ arr->next = count;
+}
+
+void
+pk_arr_move_to_back(struct pk_arr *arr, uint32_t index)
+{
+ if (arr->reserved == 0) return;
+ if (arr->next <= 1) return;
+#ifdef PK_ARR_MOVE_IN_PLACE
+ uint32_t i, ii;
+ uint8_t *target = (uint8_t *)pk_new(arr->stride, arr->alignment, arr->bkt);
+ uint8_t *buffer = (uint8_t *)arr->data;
+ for (ii = 0, i = arr->stride * index; ii < arr->stride; ++ii, ++i) {
+ target[ii] = buffer[i];
+ }
+ for (i = arr->stride * index; i < (arr->stride * (arr->next - 1)); ++i) {
+ buffer[i] = buffer[i + arr->stride];
+ }
+ for (ii = 0, i = arr->stride * (arr->next - 1); ii < arr->stride; ++ii, ++i) {
+ buffer[i] = target[ii];
+ }
+ pk_delete(target, arr->stride, arr->bkt);
+#else
+ char *new_data = (char *)pk_new(arr->stride * arr->reserved, arr->alignment, arr->bkt);
+ if (index > 0) {
+ memcpy(new_data, arr->data, arr->stride * index);
+ }
+ memcpy(
+ new_data + (arr->stride * (arr->next - 1)),
+ ((char *)arr->data) + (arr->stride * index),
+ arr->stride);
+ memcpy(
+ new_data + (arr->stride * index),
+ ((char *)arr->data) + (arr->stride * (index + 1)),
+ arr->stride * (arr->next - index - 1));
+ pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt);
+ arr->data = (void *)new_data;
+#endif
+}
+
+void
+pk_arr_append(struct pk_arr *arr, void *data)
+{
+ if (arr->reserved == arr->next) {
+ uint32_t new_count = PK_MAX(arr->reserved == 0 ? PK_ARR_INITIAL_COUNT : arr->reserved * PK_ARR_GROW_RATIO, arr->reserved + 1);
+ void *new_data = pk_new(arr->stride * new_count, arr->alignment, arr->bkt);
+ if (arr->data != NULL) {
+ memcpy(new_data, arr->data, arr->stride * arr->reserved);
+ pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt);
+ }
+ arr->data = new_data;
+ arr->reserved = new_count;
+ }
+ memcpy(((char *)arr->data) + (arr->stride * arr->next), data, arr->stride);
+ arr->next += 1;
+ return;
+}
+
+void
+pk_arr_remove_at(struct pk_arr *arr, uint32_t index)
+{
+ if (arr->reserved == 0) return;
+ if (index == arr->next - 1) {
+ arr->next -=1;
+ return;
+ }
+#ifdef PK_ARR_MOVE_IN_PLACE
+ uint32_t i;
+ uint8_t *buffer = (uint8_t *)arr->data;
+ for (i = arr->stride * index; i < (arr->stride * (arr->next - 1)); ++i) {
+ buffer[i] = buffer[i + arr->stride];
+ }
+#else
+ char *new_data = (char *)pk_new(arr->stride * arr->reserved, arr->alignment, arr->bkt);
+ if (index > 0) {
+ memcpy(new_data, arr->data, arr->stride * index);
+ }
+ memcpy(
+ new_data + (arr->stride * index),
+ ((char *)arr->data) + (arr->stride * (index + 1)),
+ arr->stride * (arr->next - index - 1));
+ pk_delete(arr->data, arr->stride * arr->reserved, arr->bkt);
+ arr->data = (void *)new_data;
+#endif
+ arr->next -= 1;
+}
+
+uint32_t
+pk_arr_find_first_index(struct pk_arr *arr, void *user_data, pk_arr_item_compare *fn)
+{
+ uint32_t i;
+ char *char_data = (char *)arr->data;
+ for (i = 0; i < arr->next; ++i) {
+ if (fn(user_data, char_data + (arr->stride * i))) return i;
+ }
+ return -1;
+}
+
+#endif /* PK_IMPL_ARR */
+#ifndef PK_PK_STN_H
+#define PK_PK_STN_H
+
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+enum PK_STN_RES {
+ PK_STN_RES_SUCCESS,
+ PK_STN_RES_OVERFLOW,
+ PK_STN_RES_UNDERFLOW,
+ PK_STN_RES_INCONVERTIBLE
+};
+
+enum PK_STN_RES pk_stn_int64_t(int64_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_uint64_t(uint64_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_int32_t(int32_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_uint32_t(uint32_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_int16_t(int16_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_uint16_t(uint16_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_int8_t(int8_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_uint8_t(uint8_t *i, char const *s, int base);
+enum PK_STN_RES pk_stn_float(float *f, char const *s);
+enum PK_STN_RES pk_stn_double(double *d, char const *s);
+enum PK_STN_RES pk_stn_float_e(float *f, char const *s, char **pEnd);
+enum PK_STN_RES pk_stn_double_e(double *d, char const *s, char **pEnd);
+
+#if defined(__cplusplus)
+
+template <typename T>
+enum PK_STN_RES pk_stn(T *n, char const *s, int base = 0)
+{
+ if constexpr(std::is_same<T, int64_t>::value) {
+ return pk_stn_int64_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint64_t>::value) {
+ return pk_stn_uint64_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, int32_t>::value) {
+ return pk_stn_int32_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint32_t>::value) {
+ return pk_stn_uint32_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, int16_t>::value) {
+ return pk_stn_int16_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint16_t>::value) {
+ return pk_stn_uint16_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, int8_t>::value) {
+ return pk_stn_int8_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint8_t>::value) {
+ return pk_stn_uint8_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, float>::value) {
+ return pk_stn_float(n, s);
+ }
+ if constexpr(std::is_same<T, double>::value) {
+ return pk_stn_double(n, s);
+ }
+ return (PK_STN_RES)-1;
+}
+
+#endif /* defined(__cplusplus) */
+
+#endif /* PK_PK_STN_H */
+
+#ifdef PK_IMPL_STN
+
+enum PK_STN_RES
+pk_stn_int64_t(int64_t *i, char const *s, int base)
+{
+ char *end;
+ long long l;
+ errno = 0;
+ l = strtoll(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == LLONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_uint64_t(uint64_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long long l;
+ errno = 0;
+ l = strtoull(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == ULLONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_int32_t(int32_t *i, char const *s, int base)
+{
+ char *end;
+ long l;
+ errno = 0;
+ l = strtol(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == LONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_uint32_t(uint32_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long l;
+ errno = 0;
+ l = strtoul(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == ULONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_int16_t(int16_t *i, char const *s, int base)
+{
+ char *end;
+ long l;
+ errno = 0;
+ l = strtol(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == LONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_uint16_t(uint16_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long l;
+ errno = 0;
+ l = strtoul(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == ULONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_int8_t(int8_t *i, char const *s, int base)
+{
+ char *end;
+ long l;
+ errno = 0;
+ l = strtol(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == LONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_uint8_t(uint8_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long l;
+ errno = 0;
+ l = strtoul(s, &end, base);
+ if (errno == ERANGE) {
+ if (l == ULONG_MAX) return PK_STN_RES_OVERFLOW;
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_float(float *f, char const *s)
+{
+ char *end;
+ return pk_stn_float_e(f, s, &end);
+}
+
+enum PK_STN_RES
+pk_stn_double(double *d, char const *s)
+{
+ char *end;
+ return pk_stn_double_e(d, s, &end);
+}
+
+enum PK_STN_RES
+pk_stn_float_e(float *f, char const *s, char **pEnd)
+{
+ float l;
+ errno = 0;
+ l = strtof(s, pEnd);
+ if (errno == ERANGE && l == HUGE_VALF) {
+ return PK_STN_RES_OVERFLOW;
+ }
+ if (errno == ERANGE && l == -HUGE_VALF) {
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || &s == (const char **)pEnd) {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *f = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+enum PK_STN_RES
+pk_stn_double_e(double *d, char const *s, char **pEnd)
+{
+ double l;
+ errno = 0;
+ l = strtod(s, pEnd);
+ if (errno == ERANGE && l == HUGE_VAL) {
+ return PK_STN_RES_OVERFLOW;
+ }
+ if (errno == ERANGE && l == -HUGE_VAL) {
+ return PK_STN_RES_UNDERFLOW;
+ }
+ if (*s == '\0' || &s == (const char **)pEnd) {
+ return PK_STN_RES_INCONVERTIBLE;
+ }
+ *d = l;
+ return PK_STN_RES_SUCCESS;
+}
+
+#endif /* PK_IMPL_STN */
+#ifndef PK_PKTMR_H
+#define PK_PKTMR_H
+
+#include <time.h>
+
+/* 2024-12-17 JCB
+ * I have read that in more recent Linux kernels, _MONOTONIC and _REALTIME
+ * do not require syscalls, while all of the other calls can.
+ * In testing on my personal machine, this seems to hold true. Using
+ * CLOCK_PROCESS_CPUTIME_ID consistently elapsed thousands of nanoseconds,
+ * even with no work between sequential _start() and _stop() calls.
+ * Meanwhile, the same test with _MONOTONIC elapsed only tens of nanoseconds.
+ * Consider replacing explicit usage with a define for more user control.
+ */
+
+/* struct pk_tmr */
+struct pk_tmr {
+ struct timespec b; // begin
+ struct timespec e; // end
+};
+
+#define pk_tmr_start(tmr) { clock_gettime(CLOCK_MONOTONIC, &tmr.b); }
+#define pk_tmr_stop(tmr) { clock_gettime(CLOCK_MONOTONIC, &tmr.e); }
+#define pk_tmr_duration_double(tmr) ((1000.0 * tmr.e.tv_sec + 1e-6 * tmr.e.tv_nsec) - (1000.0 * tmr.b.tv_sec + 1e-6 * tmr.b.tv_nsec))
+#define pk_tmr_duration_nano(tmr) ((((uint64_t)tmr.e.tv_sec * (uint64_t)1000000000) + tmr.e.tv_nsec) - (((uint64_t)tmr.b.tv_sec * (uint64_t)1000000000) + (uint64_t)tmr.b.tv_nsec))
+
+#endif /* PK_PKTMR_H */
#endif /* PK_SINGLE_HEADER_FILE_H */
diff --git a/src/player-input.hpp b/src/player-input.hpp
index 392e675..b8bd9a4 100644
--- a/src/player-input.hpp
+++ b/src/player-input.hpp
@@ -2,7 +2,7 @@
#define PKE_PLAYER_INPUT_HPP
#include "game-type-defs.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <cstdint>
diff --git a/src/plugins.cpp b/src/plugins.cpp
index ac07e93..b6acc63 100644
--- a/src/plugins.cpp
+++ b/src/plugins.cpp
@@ -2,7 +2,7 @@
#include "plugins.hpp"
#include "array.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <cassert>
#include <cstdio>
diff --git a/src/project-settings.hpp b/src/project-settings.hpp
index d999948..14005a5 100644
--- a/src/project-settings.hpp
+++ b/src/project-settings.hpp
@@ -2,7 +2,7 @@
#define PKE_PROJECT_SETTINGS_HPP
#include "dynamic-array.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <cstdint>
struct PkeProjectSettings {
diff --git a/src/project.cpp b/src/project.cpp
index 1c5572d..48c511b 100644
--- a/src/project.cpp
+++ b/src/project.cpp
@@ -120,7 +120,7 @@ void Proj_SerializeAsset(std::ofstream &stream, const Asset &asset) {
/*
void Proj_ParseProjectSettings(std::ifstream &stream) {
- while (stream.getline(projReadLine, projReadLineLength)) {
+ while (memset(projReadLine, 0, projReadLineLength), stream.getline(projReadLine, projReadLineLength)) {
if (strcmp(PKE_PROJ_FILE_OBJ_END, projReadLine) == 0) {
return;
}
@@ -135,7 +135,7 @@ void Proj_ParseProjectSettings(std::ifstream &stream) {
}
if (strncmp(projReadLine, PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_BEGIN, strlen(PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_BEGIN)) == 0) {
DynArray<pkstr> sceneFiles{16};
- while (stream.getline(projReadLine, projReadLineLength)) {
+ while (memset(projReadLine, 0, projReadLineLength), stream.getline(projReadLine, projReadLineLength)) {
if (strcmp(PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_END, projReadLine) == 0) {
pkeProjectSettings.sceneCount = sceneFiles.Count();
pkeProjectSettings.scenes = pk_new<cpkstr>(sceneFiles.Count());
@@ -163,7 +163,7 @@ void Proj_ParseEntityType(std::ifstream &stream) {
createInstanceSig[0] = '\0';
EntityType et{};
int64_t detailCount = 0;
- while (stream.getline(projReadLine, projReadLineLength)) {
+ while (memset(projReadLine, 0, projReadLineLength), stream.getline(projReadLine, projReadLineLength)) {
if (strcmp(PKE_PROJ_FILE_OBJ_END, projReadLine) == 0) {
EntityType *existingPtr = EntityType_FindByTypeCode(et.entityTypeCode.val);
if (existingPtr != nullptr) {
@@ -212,8 +212,9 @@ void Proj_ParseEntityType(std::ifstream &stream) {
if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE)) {
uint64_t prefixLen = strlen(PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE);
// 0x00000000 0x00000000
- STR2NUM_ERROR result1 = str2num(et.handle.bucketIndex, projReadLine + prefixLen);
- STR2NUM_ERROR result2 = str2num(et.handle.itemIndex, projReadLine + prefixLen + 11);
+ projReadLine[prefixLen + 10] = '\0';
+ STR2NUM_ERROR result1 = str2num(et.handle.bucketIndex, projReadLine + prefixLen + 2, 16);
+ STR2NUM_ERROR result2 = str2num(et.handle.itemIndex, projReadLine + prefixLen + 11, 16);
assert(result1 == STR2NUM_ERROR::SUCCESS);
assert(result2 == STR2NUM_ERROR::SUCCESS);
continue;
@@ -225,7 +226,7 @@ void Proj_ParseEntityType(std::ifstream &stream) {
}
if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_BEGIN)) {
EntityTypeDetails &etd = et.details[detailCount];
- while (stream.getline(projReadLine, projReadLineLength)) {
+ while (memset(projReadLine, 0, projReadLineLength), stream.getline(projReadLine, projReadLineLength)) {
if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_END)) {
detailCount += 1;
break;
@@ -281,7 +282,7 @@ void Proj_ParseAssset(std::ifstream &stream) {
basePath[0] = '\0';
basePath[255] = '\0';
AssetType at{PKE_ASSET_TYPE_UNSET};
- while (stream.getline(projReadLine, projReadLineLength)) {
+ while (memset(projReadLine, 0, projReadLineLength), stream.getline(projReadLine, projReadLineLength)) {
if (strcmp(projReadLine, PKE_PROJ_FILE_OBJ_END) == 0) {
AM_Register(keyStr, at, basePath);
return;
@@ -317,7 +318,7 @@ void PkeProject_Load(const char *filePath) {
}
memset(projReadLine, '\0', projReadLineLength);
- while (f.getline(projReadLine, projReadLineLength)) {
+ while (memset(projReadLine, 0, projReadLineLength), f.getline(projReadLine, projReadLineLength)) {
/*
if (strcmp(PKE_PROJ_FILE_OBJ_PROJECT_SETTINGS, projReadLine) == 0) {
Proj_ParseProjectSettings(f);
diff --git a/src/static/cube.cpp b/src/static-cube.cpp
index 2d9e6d7..0c8e326 100644
--- a/src/static/cube.cpp
+++ b/src/static-cube.cpp
@@ -1,5 +1,5 @@
-#include "./cube.hpp"
+#include "static-cube.hpp"
IntrinsicShapeCube pkeIntrinsicsCube {
.vert = {
diff --git a/src/static/cube.hpp b/src/static-cube.hpp
index 77ff439..77ff439 100644
--- a/src/static/cube.hpp
+++ b/src/static-cube.hpp
diff --git a/src/static/missing-texture.hpp b/src/static-missing-texture.hpp
index 83f7162..83f7162 100644
--- a/src/static/missing-texture.hpp
+++ b/src/static-missing-texture.hpp
diff --git a/src/thread_pool.cpp b/src/thread-pool.cpp
index e2ef3cd..061ae68 100644
--- a/src/thread_pool.cpp
+++ b/src/thread-pool.cpp
@@ -1,5 +1,5 @@
-#include "thread_pool.hpp"
+#include "thread-pool.hpp"
#include "bucketed-array.hpp"
diff --git a/src/thread_pool.hpp b/src/thread-pool.hpp
index 30ee516..dcb7a13 100644
--- a/src/thread_pool.hpp
+++ b/src/thread-pool.hpp
@@ -2,7 +2,7 @@
#define PKE_THREADING_HPP
#include "dynamic-array.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include <cstdint>
#include <future>
diff --git a/src/vendor/tinyfiledialogs/LICENSE b/src/tinyfiledialogs.LICENSE
index 480c61e..480c61e 100644
--- a/src/vendor/tinyfiledialogs/LICENSE
+++ b/src/tinyfiledialogs.LICENSE
diff --git a/src/vendor-cgltf-include.cpp b/src/vendor-cgltf-include.cpp
new file mode 100644
index 0000000..9a24e40
--- /dev/null
+++ b/src/vendor-cgltf-include.cpp
@@ -0,0 +1,5 @@
+
+#define CGLTF_IMPLEMENTATION
+
+#include "vendor-cgltf-include.hpp"
+
diff --git a/src/vendor/cgltf-include.hpp b/src/vendor-cgltf-include.hpp
index 7f69ca0..7f69ca0 100644
--- a/src/vendor/cgltf-include.hpp
+++ b/src/vendor-cgltf-include.hpp
diff --git a/src/vendor/glm_include.hpp b/src/vendor-glm-include.hpp
index 9e99b2a..9e99b2a 100644
--- a/src/vendor/glm_include.hpp
+++ b/src/vendor-glm-include.hpp
diff --git a/src/vendor/pkh_include.cpp b/src/vendor-pkh-include.cpp
index 0d72dcb..0d72dcb 100644
--- a/src/vendor/pkh_include.cpp
+++ b/src/vendor-pkh-include.cpp
diff --git a/src/vendor/stb_image_include.cpp b/src/vendor-stb-image-include.cpp
index 10a18b4..5583564 100644
--- a/src/vendor/stb_image_include.cpp
+++ b/src/vendor-stb-image-include.cpp
@@ -2,4 +2,4 @@
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
-#include "stb_image_include.hpp"
+#include "vendor-stb-image-include.hpp"
diff --git a/src/vendor/stb_image_include.hpp b/src/vendor-stb-image-include.hpp
index bd8658c..bd8658c 100644
--- a/src/vendor/stb_image_include.hpp
+++ b/src/vendor-stb-image-include.hpp
diff --git a/src/vendor/tinyfiledialogs/tinyfiledialogs.c b/src/vendor-tinyfiledialogs.c
index ebab836..d8c7fa2 100644
--- a/src/vendor/tinyfiledialogs/tinyfiledialogs.c
+++ b/src/vendor-tinyfiledialogs.c
@@ -95,7 +95,7 @@ misrepresented as being the original software.
#define SLASH "/"
#endif /* _WIN32 */
-#include "tinyfiledialogs.h"
+#include "vendor-tinyfiledialogs.h"
#define MAX_PATH_OR_CMD 1024 /* _MAX_PATH or MAX_PATH */
diff --git a/src/vendor/tinyfiledialogs/tinyfiledialogs.h b/src/vendor-tinyfiledialogs.h
index 08d133a..08d133a 100644
--- a/src/vendor/tinyfiledialogs/tinyfiledialogs.h
+++ b/src/vendor-tinyfiledialogs.h
diff --git a/src/vendor/cgltf-include.cpp b/src/vendor/cgltf-include.cpp
deleted file mode 100644
index 9df78c9..0000000
--- a/src/vendor/cgltf-include.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-#define CGLTF_IMPLEMENTATION
-
-#include "cgltf-include.hpp"
-
diff --git a/src/window.cpp b/src/window.cpp
index 1be148f..f5821ae 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1,6 +1,6 @@
#include "backends/imgui_impl_vulkan.h"
#include "math-helpers.hpp"
-#include "static/missing-texture.hpp"
+#include "static-missing-texture.hpp"
#define GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_VULKAN
@@ -14,7 +14,7 @@
#include "game-settings.hpp"
#include "helpers.hpp"
#include "plugins.hpp"
-#include "static/cube.hpp"
+#include "static-cube.hpp"
#include "window-types.hpp"
#include "glm/ext/matrix_transform.hpp"
diff --git a/src/window.hpp b/src/window.hpp
index 2ceebec..1af7eed 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -8,7 +8,7 @@
#include "imgui.h"
#include "ecs.hpp"
#include "window-types.hpp"
-#include "vendor/pk.h"
+#include "pk.h"
#include "glm/mat4x4.hpp"
#include <cstring>