54 Commits
Author SHA1 Message Date
rboullard 7804647768 Format
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 32s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 33s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 51s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 43s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 56s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 46s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 34s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 34s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 24s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 53s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 55s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 45s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 26s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 39s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 33s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 37s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 35s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 40s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 38s
Bigfoot / Clang Format Checks (push) Successful in 10s
2026-08-28 22:05:44 +02:00
rboullard 793dfe6a87 static_assert payload 2026-08-28 01:19:19 +02:00
rboullard e51afcbdf5 set file size in linux if needed
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 31s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 33s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 55s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 54s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 42s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 45s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 33s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 34s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 24s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 52s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 54s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 45s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 27s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 38s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 32s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 41s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 34s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 41s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 37s
Bigfoot / Clang Format Checks (push) Failing after 10s
2026-08-28 01:14:02 +02:00
rboullard 9ae55ac60f Fix linux truncating
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 31s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 32s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 53s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
2026-08-28 01:10:48 +02:00
rboullard 841ba38be8 cleanup
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 25s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 34s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 33s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 53s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 45s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 19s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
2026-08-28 01:06:23 +02:00
rboullard 6ccf56eb38 EASTL codecs for string_view and string 2026-08-28 01:06:13 +02:00
rboullard fc5794b5c7 Moving AssetContainer/SlotMap/Reference benchmarks to appropriate place + testing in game mode too 2026-08-28 01:01:40 +02:00
rboullard 3e3e3798ae MemoryMappedFile + File + BigFIle more representative numbers 2026-08-28 01:00:38 +02:00
rboullard ed5061dc52 More dependencies 2026-08-27 23:48:25 +02:00
rboullard f518bf7c8a use efoolkronium random
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 34s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 25s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 22s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 52s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 45s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 35s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 30s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 52s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 52s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 40s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 52s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 28s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 39s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 33s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 39s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 33s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 43s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 37s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 33s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 36s
Bigfoot / Clang Format Checks (push) Successful in 9s
2026-08-26 10:44:08 +02:00
rboullard eb2af20abd byte_per_sec in benchmarks
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 32s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 21s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 53s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 31s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 24s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 20s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 39s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 52s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 49s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 39s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 54s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 43s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 26s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 37s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 34s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 29s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 33s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 39s
Bigfoot / Clang Format Checks (push) Successful in 12s
2026-08-25 23:18:50 +02:00
rboullard 8f047767ae fixing formatting
Bigfoot / Clang Format Checks (push) Successful in 10s
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 30s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 22s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 53s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 41s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 54s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 31s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 52s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 26s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 20s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 38s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 31s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 33s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 50s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 43s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 37s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 36s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 37s
2026-08-25 23:12:22 +02:00
rboullard 02e587bf86 clang format
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
2026-08-25 23:02:51 +02:00
rboullard fff7733cdb uuid hash consolidation
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
2026-08-25 22:56:09 +02:00
rboullard c6e801abb6 use map in asset_library
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 28s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 20s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 41s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 43s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 30s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 51s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 52s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 32s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 23s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 19s
2026-08-25 22:54:50 +02:00
rboullard 77e26cfa83 AssetContainer/Reference optim
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 30s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 52s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 21s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 30s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 44s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 32s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 50s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 40s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 52s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 26s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 40s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 54s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 31s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 23s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 43s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 32s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 36s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 34s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 39s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 35s
Bigfoot / Clang Format Checks (push) Failing after 9s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 36s
2026-08-25 22:51:38 +02:00
rboullard be85c650b9 More optimizations for BigFile
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 32s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 29s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 21s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 51s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 40s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 53s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 43s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 30s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 43s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 43s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 36s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 23s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 51s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 53s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 25s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 21s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 36s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 36s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 34s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 40s
Bigfoot / Clang Format Checks (push) Failing after 10s
2026-08-25 22:22:23 +02:00
rboullard d32d1d7229 Optimize BigFile access
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 21s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 22s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 49s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 52s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 30s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 36s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 32s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 28s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 29s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 39s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 21s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 50s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 40s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 48s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 41s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 21s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 34s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 27s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 36s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 35s
Bigfoot / Clang Format Checks (push) Successful in 11s
2026-08-25 19:06:39 +02:00
rboullard 65da7522ef format
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 5m21s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 2m14s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 29s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 20s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 29s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 21s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 40s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 51s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 2m26s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 20s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 3m40s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 40s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 50s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 42s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 2m10s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 19s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 31s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 27s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 3m13s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 31s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 38s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 34s
Bigfoot / Clang Format Checks (push) Successful in 9s
2026-08-25 18:49:34 +02:00
rboullard 2572922af9 BigFile access
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 4m13s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
2026-08-25 18:46:23 +02:00
rboullard 03e501f1b2 use conan cache
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 35s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 37s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 1m28s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 57s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 3m27s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 3m6s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 38s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 56s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 49s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 58s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 1m1s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 57s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 1m24s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 2m37s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 4m24s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 5m6s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 4m57s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 1m11s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 1m6s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 1m7s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 47s
Bigfoot / Clang Format Checks (push) Successful in 12s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 47s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 1m6s
2026-08-25 14:13:29 +02:00
rboullard e78d5378a4 Update profiles to pickup changes in flags and toolchains
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m13s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m36s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 13m38s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 14m39s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 14m24s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m34s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 14m50s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m48s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 15m29s
Bigfoot / Clang Format Checks (push) Successful in 10s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 1m38s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 1m38s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 1m38s
2026-08-25 11:50:49 +02:00
rboullard 1b9e17d6bc Fix tests
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 14m24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m25s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 8m4s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 8m28s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 8m3s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 4s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 4s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 4s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 10s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 10s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 11s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 10s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 10s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 10s
Bigfoot / Clang Format Checks (push) Successful in 17s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 23m56s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 8s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 10s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 11s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 8s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 34s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 23m40s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 23m50s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 16m37s
2026-08-25 11:36:59 +02:00
rboullard 4b07aa7fa2 Rule of 0/3/5
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 14m21s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 13m46s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 14m11s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 13m51s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 14m45s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 14m18s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 15m3s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 14m28s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 15m30s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 15m16s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 15m43s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 15m20s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 17m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 16m42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 17m18s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 15m3s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 16m39s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 14m43s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 15m15s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 14m55s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 16m6s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 15m54s
Bigfoot / Clang Format Checks (push) Successful in 10s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 16m4s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 15m47s
2026-08-24 00:49:01 +02:00
rboullard 081e23360f BigFile implementing DataAccessor
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 13m52s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 14m16s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m17s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 13m52s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 14m22s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 14m48s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 14m30s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m27s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 15m5s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 16m44s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m45s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m28s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 14m57s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 17m22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 17m23s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m12s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 16m53s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 15m1s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 16m9s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 16m7s
Bigfoot / Clang Format Checks (push) Failing after 10s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 16m20s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 16m1s
2026-08-24 00:00:49 +02:00
rboullard eb22baacf9 Time equality comparisons 2026-08-24 00:00:32 +02:00
rboullard 0bee2c22ca Has for DataAccessor 2026-08-24 00:00:02 +02:00
rboullard 1307273150 clang format 2026-08-23 23:18:27 +02:00
rboullard 8b2ad9de35 DataAccessor interface 2026-08-23 23:18:18 +02:00
rboullard 1c2f9344b0 Update flatbuffers + reduce copies in Pack
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 14m28s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m14s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 13m56s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 14m47s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m55s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 14m27s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 15m3s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m24s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 17m0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 16m26s
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m5s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 14m35s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m35s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 15m5s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 17m16s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m1s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 17m3s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m52s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m7s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 14m52s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 16m19s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 15m53s
Bigfoot / Clang Format Checks (push) Failing after 9s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 16m5s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 15m51s
2026-08-23 15:46:14 +02:00
rboullard 09014277a1 Asset tests
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
2026-08-23 13:05:26 +02:00
rboullard 8e28f50e1d Asset concepts
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m5s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 14m24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 13m53s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 14m22s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 14m43s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m49s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 14m28s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m21s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 12m47s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 12m42s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 12m41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Canceled after 48s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Canceled after 2m4s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Canceled after 2m24s
2026-08-23 12:28:46 +02:00
rboullard 407401bea2 Documentation
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m18s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 14m10s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 15m5s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 14m41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 15m14s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 13m58s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 14m29s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m10s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 14m42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 15m19s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m30s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 17m21s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 16m51s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 17m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 16m44s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m3s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 14m48s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 16m24s
Bigfoot / Clang Format Checks (push) Failing after 9s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m3s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m50s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 16m5s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 16m28s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 16m22s
2026-08-22 19:17:25 +02:00
rboullard cbf4de6003 fix CI
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 14m8s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 13m51s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 14m11s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 14m2s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 14m31s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 14m51s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m3s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 14m33s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m27s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 15m21s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m35s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 15m11s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 16m51s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 17m19s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 15m11s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 15m16s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 14m53s
Bigfoot / Clang Format Checks (push) Successful in 11s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 17m31s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 14m57s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 16m48s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 16m14s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 16m13s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 16m22s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 16m7s
2026-08-22 19:06:05 +02:00
rboullard 0ba9e062d4 Game and toolmode
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Toolmode: False) (push) Failing after 13m34s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Toolmode: False) (push) Failing after 13m24s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Toolmode: True) (push) Failing after 13m23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Toolmode: True) (push) Failing after 13m29s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Toolmode: True) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Toolmode: False) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Toolmode: True) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Toolmode: False) (push) Canceled after 13m30s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Toolmode: False) (push) Canceled after 13m9s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Toolmode: True) (push) Canceled after 29s
2026-08-22 18:12:30 +02:00
rboullard 33331ea529 flush logs on all asserts 2026-08-21 23:01:25 +02:00
rboullard 8a36af6bcb Update profiles
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF) (push) Successful in 6m16s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF) (push) Successful in 5m47s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON) (push) Successful in 5m35s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON) (push) Successful in 6m22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF) (push) Successful in 7m25s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON) (push) Successful in 6m7s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF) (push) Successful in 6m17s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF) (push) Successful in 6m10s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF) (push) Successful in 7m17s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON) (push) Successful in 7m21s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON) (push) Successful in 6m7s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON) (push) Successful in 6m55s
Bigfoot / Clang Format Checks (push) Successful in 9s
2026-08-19 10:09:58 +02:00
rboullard c6ccdf8214 Cleanup
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m24s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m8s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m2s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m18s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m24s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m32s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m6s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m59s
Bigfoot / Clang Format Checks (push) Successful in 8s
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m6s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m40s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m33s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m15s
2026-08-18 18:25:34 +02:00
rboullard d9f4a0e896 Do not allow creating ReferenceBase
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Sonarqube (push) Skipped
2026-08-18 18:12:05 +02:00
rboullard 1d572b9d09 Simplify asserts
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Sonarqube (push) Skipped
2026-08-18 17:41:24 +02:00
rboullard 870bfe57e6 Cleanup
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m15s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m48s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m39s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m29s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m20s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m18s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 1m10s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m28s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m16s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 3m55s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 2m13s
Bigfoot / Sonarqube (push) Skipped
2026-08-18 17:30:39 +02:00
rboullard 9978ff358b Format + API cleanup
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 8m15s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m28s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m22s
Bigfoot / Clang Format Checks (push) Successful in 8s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m25s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m1s
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m44s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m30s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m52s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m24s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m17s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m35s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m49s
2026-08-18 17:11:57 +02:00
rboullard 8be97bacb5 Full test for reference Copy/Move
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m39s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m25s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m6s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m28s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m32s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m31s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m12s
Bigfoot / Clang Format Checks (push) Failing after 8s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m44s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m18s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m27s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m8s
2026-08-18 17:01:26 +02:00
rboullard cea3b8a904 SoftRef/HardRef count testing
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m17s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m46s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m35s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m14s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m18s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m30s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m27s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m19s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m21s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m6s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m6s
Bigfoot / Clang Format Checks (push) Failing after 8s
2026-08-18 16:53:56 +02:00
rboullard 1d2dafff48 msvc flags update
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m43s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m12s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m23s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m41s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m8s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m22s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m34s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m21s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m16s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m12s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m58s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m7s
Bigfoot / Clang Format Checks (push) Failing after 8s
2026-08-18 15:49:50 +02:00
rboullard 17ab916b11 Remove unused method
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m45s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m50s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m14s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m11s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m28s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m17s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m21s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m13s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m8s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m59s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m57s
Bigfoot / Clang Format Checks (push) Failing after 8s
2026-08-18 15:23:49 +02:00
rboullard 3c306dd2c7 basic testing for reference
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m52s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m46s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m18s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m14s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 7m17s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m25s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 8m7s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m31s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m24s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m18s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m30s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m6s
Bigfoot / Clang Format Checks (push) Failing after 8s
2026-08-18 14:59:42 +02:00
rboullard a1e4119311 Fix compilation
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m49s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m50s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m11s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m5s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m17s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m19s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m38s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m26s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m11s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m6s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m59s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m59s
Bigfoot / Clang Format Checks (push) Successful in 8s
2026-08-18 10:23:23 +02:00
rboullard 1bae20b79c Fix clang-format
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m39s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m16s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 5m57s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m45s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m7s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 6m1s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m19s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m13s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m25s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 5m59s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 6m43s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 6m44s
Bigfoot / Clang Format Checks (push) Successful in 9s
2026-08-18 00:52:22 +02:00
rboullard 39d2ddbe49 ContainerHandle test
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 6m13s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 5m34s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m33s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 5m55s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 5m54s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 6m2s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 7m9s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Successful in 7m13s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 5m49s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 5m52s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 6m34s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 6m34s
Bigfoot / Clang Format Checks (push) Failing after 0s
2026-08-17 18:32:02 +02:00
rboullard 6bc25a776e format
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 10m27s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Successful in 6m3s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 2m34s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 5m30s
2026-08-17 18:08:27 +02:00
rboullard 96c4353a8a StableSlotMap
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 2m4s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 2m34s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 8m3s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 6m46s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Canceled after 0s
Bigfoot / Clang Format Checks (push) Canceled after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Canceled after 1m18s
2026-08-17 17:25:49 +02:00
rboullard 9733860ecd Fix compilation
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 1s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 0s
Bigfoot / Clang Format Checks (push) Failing after 0s
2026-08-17 02:32:42 +02:00
rboullard 2062b8169f BigFile
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: ON) (push) Failing after 0s
Bigfoot / Clang Format Checks (push) Failing after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test Debug with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Failing after 0s
Bigfoot / Build & Test Release with ./ConanProfiles/clang_asan (Unity Build: OFF) (push) Failing after 0s
2026-08-17 01:16:13 +02:00
134 changed files with 1672 additions and 7148 deletions
+10 -25
View File
@@ -127,37 +127,22 @@ IncludeCategories:
Priority: 2 Priority: 2
- Regex: '^<Utils/' - Regex: '^<Utils/'
Priority: 3 Priority: 3
- Regex: '^<SasquatchBaker/'
Priority: 4
- Regex: '^<EngineTests/' - Regex: '^<EngineTests/'
Priority: 5 Priority: 4
- Regex: '^<SystemTests/' - Regex: '^<SystemTests/'
Priority: 6 Priority: 5
- Regex: '^<UtilsTests/' - Regex: '^<UtilsTests/'
Priority: 7 Priority: 6
- Regex: '^<AssetsForTesting/' - Regex: '^<AssetsForTesting/'
Priority: 8 Priority: 7
- Regex: '^<SasquatchBakerTests/'
Priority: 9
- Regex: '^<EngineBenchmarks/' - Regex: '^<EngineBenchmarks/'
Priority: 10 Priority: 8
- Regex: '^<AssetsForBenchmarking/' - Regex: '^<AssetsForBenchmarking/'
Priority: 11 Priority: 9
- Regex: '^<SasquatchBakerBenchmarks/'
Priority: 12
- Regex: '^<[a-zA-Z0-9_/]+\.h>' - Regex: '^<[a-zA-Z0-9_/]+\.h>'
Priority: 13 Priority: 10
- Regex: '^<[a-zA-Z0-9_/]+\.hpp>' - Regex: '^<[a-zA-Z0-9_/]+\.hpp>'
Priority: 13 Priority: 10
- Regex: '^<[a-zA-Z0-9_/]+>' - Regex: '^<[a-zA-Z0-9_/]+>'
Priority: 14 Priority: 11
MainIncludeChar: AngleBracket MainIncludeChar: AngleBracket
Macros:
- 'BIGFOOT_OPTIMIZED_ONLY(x)=x'
- 'BIGFOOT_OPTIMIZED_ONLY(x,y)=x,y'
- 'BIGFOOT_NOT_OPTIMIZED_ONLY(x)=x'
- 'BIGFOOT_NOT_OPTIMIZED_ONLY(x,y)=x,y'
- 'BIGFOOT_TOOLMODE_ONLY(x)=x'
- 'BIGFOOT_TOOLMODE_ONLY(x,y)=x,y'
- 'BIGFOOT_GAME_ONLY(x)=x'
- 'BIGFOOT_GAME_ONLY(x,y)=x,y'
+1 -5
View File
@@ -11,13 +11,9 @@ Checks: >
portability-*, portability-*,
-modernize-use-trailing-return-type, -modernize-use-trailing-return-type,
-modernize-use-auto,
-readability-avoid-const-params-in-decls, -readability-avoid-const-params-in-decls,
-cppcoreguidelines-macro-usage, -cppcoreguidelines-macro-usage,
-cppcoreguidelines-avoid-do-while, -cppcoreguidelines-avoid-do-while
-cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-reinterpret-cast
ExcludeHeaderFilterRegex: '_generated.*' ExcludeHeaderFilterRegex: '_generated.*'
+12 -12
View File
@@ -18,10 +18,10 @@ jobs:
build_type: ["Debug", "RelWithDebInfo", "Release"] build_type: ["Debug", "RelWithDebInfo", "Release"]
unity_build: ["ON", "OFF"] unity_build: ["ON", "OFF"]
conan_profile: ["./ConanProfiles/host/clang", "./ConanProfiles/host/clang_asan"] conan_profile: ["./ConanProfiles/host/clang", "./ConanProfiles/host/clang_asan"]
variant: toolmode:
- { value: "True", name: "toolmode" } - { value: "True", name: "toolmode" }
- { value: "False", name: "game" } - { value: "False", name: "game" }
name: "Build & Test ${{ matrix.build_type }} with ${{ matrix.conan_profile }} (Unity Build: ${{ matrix.unity_build }}, Variant: ${{ matrix.variant.name }})" name: "Build & Test ${{ matrix.build_type }} with ${{ matrix.conan_profile }} (Unity Build: ${{ matrix.unity_build }}, Variant: ${{ matrix.toolmode.name }})"
steps: steps:
- name: Install Node.js - name: Install Node.js
run: apt-get update && apt-get install -y nodejs run: apt-get update && apt-get install -y nodejs
@@ -33,18 +33,18 @@ jobs:
- name: Build - name: Build
run: | run: |
conan install . --remote=bigfootpackages -pr:h=${{ matrix.conan_profile }} -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=${{ matrix.build_type }} -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:vulkan=True -o bigfoot/*:toolmode=${{ matrix.variant.value }} -of build-${{ matrix.variant.name }} conan install . --remote=bigfootpackages -pr:h=${{ matrix.conan_profile }} -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=${{ matrix.build_type }} -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:vulkan=True -o bigfoot/*:toolmode=${{ matrix.toolmode.value }} -of build-${{ matrix.toolmode.name }}
. ./build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh . ./build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh
cmake -S . -B ./build-${{ matrix.variant.name }}/${{ matrix.build_type }} --toolchain ./build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -G "Ninja" cmake -S . -B ./build-${{ matrix.toolmode.name }}/${{ matrix.build_type }} --toolchain ./build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -G "Ninja"
cmake --build build-${{ matrix.variant.name }}/${{ matrix.build_type }} --parallel $(nproc) cmake --build build-${{ matrix.toolmode.name }}/${{ matrix.build_type }} --parallel $(nproc)
. ./build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh . ./build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh
- name: Unit Tests - name: Unit Tests
run: | run: |
cd ./build-${{ matrix.variant.name }}/${{ matrix.build_type }} cd ./build-${{ matrix.toolmode.name }}/${{ matrix.build_type }}
. ../../build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh . ../../build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh
xvfb-run ctest . --output-on-failure xvfb-run ctest . --output-on-failure
. ../../build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh . ../../build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh
clang-format: clang-format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -60,6 +60,6 @@ jobs:
uses: actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
- name: Clang Format Checks - name: Clang Format Checks
run: chmod +x format.sh && ./format.sh --check Bigfoot run: chmod +x format.sh && ./format.sh --check Bigfoot
+12 -59
View File
@@ -5,10 +5,6 @@ on:
branches: branches:
- main - main
- Development - Development
pull_request:
branches:
- main
- Development
jobs: jobs:
build-and-test: build-and-test:
@@ -17,14 +13,7 @@ jobs:
container: container:
image: git.romainboullard.com/bigfootdev/linuxcppbuilder:development image: git.romainboullard.com/bigfootdev/linuxcppbuilder:development
strategy: name: "Sonarqube"
fail-fast: false
matrix:
variant:
- { value: "True", name: "toolmode", projectKey: "Bigfoot-Tool", projectName: "Bigfoot Tool" }
- { value: "False", name: "game", projectKey: "Bigfoot-Game", projectName: "Bigfoot Game" }
name: "Sonarqube (${{ matrix.variant.name }})"
steps: steps:
- name: Install Node.js - name: Install Node.js
run: apt-get update && apt-get install -y nodejs run: apt-get update && apt-get install -y nodejs
@@ -34,64 +23,28 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive submodules: recursive
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Read version
id: version
run: echo "version=$(cat VERSION)" >> "$GITHUB_OUTPUT"
- name: Build - name: Build
run: | run: |
conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/host/clang_coverage -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=Debug -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:toolmode=${{ matrix.variant.value }} -o bigfoot/*:vulkan=True -of build-${{ matrix.variant.name }} conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/host/clang_coverage -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=Debug -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True
. ./build-${{ matrix.variant.name }}/build/Debug/generators/conanbuild.sh . ./build/Debug/generators/conanbuild.sh
cmake -S . -B ./build-${{ matrix.variant.name }}/Debug --toolchain ./build-${{ matrix.variant.name }}/build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja" cmake -S . -B ./build/Debug --toolchain ./build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja"
cmake --build build-${{ matrix.variant.name }}/Debug --parallel $(nproc) cmake --build build/Debug --parallel $(nproc)
. ./build-${{ matrix.variant.name }}/build/Debug/generators/deactivate_conanbuild.sh . ./build/Debug/generators/deactivate_conanbuild.sh
- name: Run tests
run: |
cd ./build-${{ matrix.variant.name }}/Debug
. ../../build-${{ matrix.variant.name }}/build/Debug/generators/conanbuild.sh
LLVM_PROFILE_FILE="%p.profraw%c" xvfb-run ctest --output-on-failure
. ../../build-${{ matrix.variant.name }}/build/Debug/generators/deactivate_conanbuild.sh
- name: Clang-Tidy - name: Clang-Tidy
run: run-clang-tidy -p ./build-${{ matrix.variant.name }}/Debug/ > tidy_result.txt run: run-clang-tidy -p ./build/Debug/ >> tidy_result.txt
- name: Infer - name: Infer
run: infer run --compilation-database build-${{ matrix.variant.name }}/Debug/compile_commands.json run: infer run --compilation-database build/Debug/compile_commands.json
- name: Generate coverage report
shell: bash
run: |
# gcovr's own LLVM-JSON reader only understands coverage-mapping format
# 2.x; this image's clang 22 llvm-cov emits format 3.x, which gcovr
# rejects outright ("Wrong major version"). Bypassing gcovr's JSON
# path entirely: llvm-cov's lcov exporter is a separate, unaffected
# code path, so merge -> export lcov -> convert lcov to Cobertura.
llvm-profdata merge -sparse $(find build-${{ matrix.variant.name }}/Debug -name "*.profraw") -o merged.profdata
BINARIES=($(find build-${{ matrix.variant.name }}/Debug -maxdepth 8 -type f -executable -iname "*Tests"))
OBJECT_ARGS=$(printf -- '-object %s ' "${BINARIES[@]:1}")
llvm-cov export -format=lcov -instr-profile=merged.profdata "${BINARIES[0]}" $OBJECT_ARGS > coverage.lcov
# lcov_cobertura isn't preinstalled on the image; inject it into
# gcovr's existing pipx venv and expose its CLI on PATH.
pipx inject gcovr lcov_cobertura --include-apps
lcov_cobertura coverage.lcov -b . -o coverage.xml
- name: SonarQube Scan - name: SonarQube Scan
if: github.head_ref == 'main' || github.ref_name == 'main'
uses: SonarSource/sonarqube-scan-action@v7.0.0 uses: SonarSource/sonarqube-scan-action@v7.0.0
with: with:
args: > args: >
-Dsonar.projectKey=${{ matrix.variant.projectKey }} -Dsonar.cxx.jsonCompilationDatabase=./build/Debug/compile_commands.json
"-Dsonar.projectName=${{ matrix.variant.projectName }}" -Dsonar.verbose=true
-Dsonar.projectVersion=${{ steps.version.outputs.version }}
-Dsonar.cxx.jsonCompilationDatabase=./build-${{ matrix.variant.name }}/Debug/compile_commands.json
-Dsonar.cxx.xunit.reportPaths=build-${{ matrix.variant.name }}/Debug/TestResults/*.xml
-Dsonar.qualitygate.wait=true
${{ github.event_name == 'pull_request' &&
format('-Dsonar.pullrequest.key={0} -Dsonar.pullrequest.branch={1} -Dsonar.pullrequest.base={2} -Dsonar.analysis.sqbot={3}',
github.event.pull_request.number, github.head_ref, github.base_ref, github.event.pull_request.head.sha)
|| format('-Dsonar.branch.name={0}', github.ref_name) }}
env: env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST }}
-5
View File
@@ -1,5 +0,0 @@
InheritParentConfig: true
Checks: >
-cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-avoid-magic-numbers,
-readability-magic-numbers
@@ -1,11 +0,0 @@
/*********************************************************************
* \file BenchmarkAssetReferred.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <AssetsForBenchmarking/Asset/BenchmarkAssetReferred.hpp>
#include <Engine/Asset/AssetHelper.hpp>
BIGFOOT_ASSET(BenchmarkAssetReferred, ::Bigfoot::BenchmarkAssetReferred)
@@ -1,11 +1,8 @@
include "Engine/Asset/Reference.fbs";
namespace Flat.Bigfoot; namespace Flat.Bigfoot;
table BenchmarkAsset table BenchmarkAsset
{ {
payload: [ubyte]; payload: [ubyte];
refs: [HardReference] (native_inline, bigfoot_ref: "::Bigfoot::BenchmarkAssetReferred");
} }
root_type BenchmarkAsset; root_type BenchmarkAsset;
@@ -1,7 +0,0 @@
namespace Flat.Bigfoot;
table BenchmarkAssetReferred
{
}
root_type BenchmarkAssetReferred;
@@ -1,25 +0,0 @@
/*********************************************************************
* \file BenchmarkAssetReferred.hpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#ifndef BIGFOOT_ASSETSFORBENCHMARKING_ASSET_BENCHMARKASSETREFERRED_HPP
#define BIGFOOT_ASSETSFORBENCHMARKING_ASSET_BENCHMARKASSETREFERRED_HPP
#include <Engine/Asset/Asset.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAssetReferred_generated.hpp>
namespace Bigfoot
{
struct BenchmarkAssetReferredTraits
{
using FLAT = ::Flat::Bigfoot::BenchmarkAssetReferred;
};
class BenchmarkAssetReferred: public Asset<BenchmarkAssetReferredTraits>
{
};
} // namespace Bigfoot
#endif
@@ -1,172 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_BENCHMARKASSETREFERRED_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_BENCHMARKASSETREFERRED_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
// Ensure the included flatbuffers.h is Bigfoot's fork - stock
// flatbuffers (or a differently versioned Bigfoot fork) is not compatible.
#ifndef FLATBUFFERS_BIGFOOT_VERSION
#error "This file requires Bigfoot's flatbuffers fork - stock flatbuffers is not compatible"
#endif
static_assert(FLATBUFFERS_BIGFOOT_VERSION == 1,
"Non-compatible Bigfoot flatbuffers fork version included");
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct BenchmarkAssetReferred;
struct BenchmarkAssetReferredBuilder;
struct BenchmarkAssetReferredT;
inline const ::flatbuffers::TypeTable *BenchmarkAssetReferredTypeTable();
struct BenchmarkAssetReferredT : public ::flatbuffers::NativeTable {
typedef BenchmarkAssetReferred TableType;
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.BenchmarkAssetReferredT";
}
};
struct BenchmarkAssetReferred FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef BenchmarkAssetReferredT NativeTableType;
typedef BenchmarkAssetReferredBuilder Builder;
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return BenchmarkAssetReferredTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.BenchmarkAssetReferred";
}
template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) &&
verifier.EndTable();
}
BenchmarkAssetReferredT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(BenchmarkAssetReferredT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<BenchmarkAssetReferred> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const BenchmarkAssetReferredT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct BenchmarkAssetReferredBuilder {
typedef BenchmarkAssetReferred Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
explicit BenchmarkAssetReferredBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<BenchmarkAssetReferred> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<BenchmarkAssetReferred>(end);
return o;
}
};
inline ::flatbuffers::Offset<BenchmarkAssetReferred> CreateBenchmarkAssetReferred(
::flatbuffers::FlatBufferBuilder &_fbb) {
BenchmarkAssetReferredBuilder builder_(_fbb);
return builder_.Finish();
}
struct BenchmarkAssetReferred::Traits {
using type = BenchmarkAssetReferred;
static auto constexpr Create = CreateBenchmarkAssetReferred;
};
::flatbuffers::Offset<BenchmarkAssetReferred> CreateBenchmarkAssetReferred(::flatbuffers::FlatBufferBuilder &_fbb, const BenchmarkAssetReferredT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline BenchmarkAssetReferredT *BenchmarkAssetReferred::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<BenchmarkAssetReferredT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void BenchmarkAssetReferred::UnPackTo(BenchmarkAssetReferredT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
}
inline ::flatbuffers::Offset<BenchmarkAssetReferred> CreateBenchmarkAssetReferred(::flatbuffers::FlatBufferBuilder &_fbb, const BenchmarkAssetReferredT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return BenchmarkAssetReferred::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<BenchmarkAssetReferred> BenchmarkAssetReferred::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const BenchmarkAssetReferredT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const BenchmarkAssetReferredT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
return Flat::Bigfoot::CreateBenchmarkAssetReferred(
_fbb);
}
inline const ::flatbuffers::TypeTable *BenchmarkAssetReferredTypeTable() {
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr, nullptr
};
return &tt;
}
inline const Flat::Bigfoot::BenchmarkAssetReferred *GetBenchmarkAssetReferred(const void *buf) {
return ::flatbuffers::GetRoot<Flat::Bigfoot::BenchmarkAssetReferred>(buf);
}
inline const Flat::Bigfoot::BenchmarkAssetReferred *GetSizePrefixedBenchmarkAssetReferred(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Flat::Bigfoot::BenchmarkAssetReferred>(buf);
}
template <bool B = false>
inline bool VerifyBenchmarkAssetReferredBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifyBuffer<Flat::Bigfoot::BenchmarkAssetReferred>(nullptr);
}
template <bool B = false>
inline bool VerifySizePrefixedBenchmarkAssetReferredBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifySizePrefixedBuffer<Flat::Bigfoot::BenchmarkAssetReferred>(nullptr);
}
inline const char *BenchmarkAssetReferredExtension() {
return "bfbs";
}
inline void FinishBenchmarkAssetReferredBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::BenchmarkAssetReferred> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedBenchmarkAssetReferredBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::BenchmarkAssetReferred> root) {
fbb.FinishSizePrefixed(root);
}
inline eastl::unique_ptr<Flat::Bigfoot::BenchmarkAssetReferredT> UnPackBenchmarkAssetReferred(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::BenchmarkAssetReferredT>(GetBenchmarkAssetReferred(buf)->UnPack(res));
}
inline eastl::unique_ptr<Flat::Bigfoot::BenchmarkAssetReferredT> UnPackSizePrefixedBenchmarkAssetReferred(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::BenchmarkAssetReferredT>(GetSizePrefixedBenchmarkAssetReferred(buf)->UnPack(res));
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_BENCHMARKASSETREFERRED_FLAT_BIGFOOT_H_
@@ -20,10 +20,6 @@ static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
static_assert(FLATBUFFERS_BIGFOOT_VERSION == 1, static_assert(FLATBUFFERS_BIGFOOT_VERSION == 1,
"Non-compatible Bigfoot flatbuffers fork version included"); "Non-compatible Bigfoot flatbuffers fork version included");
#include "System/UUID/UUID.hpp"
#include "Engine/Asset/Reference.hpp"
#include "Engine/Asset/Reference_generated.hpp"
#include "EASTL/unique_ptr.h" #include "EASTL/unique_ptr.h"
#include "EASTL/string.h" #include "EASTL/string.h"
#include "EASTL/vector.h" #include "EASTL/vector.h"
@@ -35,21 +31,6 @@ struct BenchmarkAsset;
struct BenchmarkAssetBuilder; struct BenchmarkAssetBuilder;
struct BenchmarkAssetT; struct BenchmarkAssetT;
} // namespace Bigfoot
} // namespace Flat
namespace Bigfoot {
class BenchmarkAssetReferred;
} // namespace Bigfoot
namespace flatbuffers {
Flat::Bigfoot::HardReference PackHardReferenceBenchmarkAssetReferred(const ::Bigfoot::HardReference<::Bigfoot::BenchmarkAssetReferred>& p_asset);
::Bigfoot::HardReference<::Bigfoot::BenchmarkAssetReferred> UnPackHardReferenceBenchmarkAssetReferred(const Flat::Bigfoot::HardReference& p_asset);
} // namespace flatbuffers
namespace Flat {
namespace Bigfoot {
inline const ::flatbuffers::TypeTable *BenchmarkAssetTypeTable(); inline const ::flatbuffers::TypeTable *BenchmarkAssetTypeTable();
struct BenchmarkAssetT : public ::flatbuffers::NativeTable { struct BenchmarkAssetT : public ::flatbuffers::NativeTable {
@@ -58,7 +39,6 @@ struct BenchmarkAssetT : public ::flatbuffers::NativeTable {
return "Flat.Bigfoot.BenchmarkAssetT"; return "Flat.Bigfoot.BenchmarkAssetT";
} }
eastl::vector<uint8_t> payload{}; eastl::vector<uint8_t> payload{};
eastl::vector<::Bigfoot::HardReference<::Bigfoot::BenchmarkAssetReferred>> refs{};
}; };
struct BenchmarkAsset FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct BenchmarkAsset FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
@@ -72,22 +52,16 @@ struct BenchmarkAsset FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
return "Flat.Bigfoot.BenchmarkAsset"; return "Flat.Bigfoot.BenchmarkAsset";
} }
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_PAYLOAD = 4, VT_PAYLOAD = 4
VT_REFS = 6
}; };
const ::flatbuffers::Vector<uint8_t> *payload() const { const ::flatbuffers::Vector<uint8_t> *payload() const {
return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_PAYLOAD); return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_PAYLOAD);
} }
const ::flatbuffers::Vector<const Flat::Bigfoot::HardReference *> *refs() const {
return GetPointer<const ::flatbuffers::Vector<const Flat::Bigfoot::HardReference *> *>(VT_REFS);
}
template <bool B = false> template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const { bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_PAYLOAD) && VerifyOffset(verifier, VT_PAYLOAD) &&
verifier.VerifyVector(payload()) && verifier.VerifyVector(payload()) &&
VerifyOffset(verifier, VT_REFS) &&
verifier.VerifyVector(refs()) &&
verifier.EndTable(); verifier.EndTable();
} }
BenchmarkAssetT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const; BenchmarkAssetT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
@@ -102,9 +76,6 @@ struct BenchmarkAssetBuilder {
void add_payload(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> payload) { void add_payload(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> payload) {
fbb_.AddOffset(BenchmarkAsset::VT_PAYLOAD, payload); fbb_.AddOffset(BenchmarkAsset::VT_PAYLOAD, payload);
} }
void add_refs(::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::HardReference *>> refs) {
fbb_.AddOffset(BenchmarkAsset::VT_REFS, refs);
}
explicit BenchmarkAssetBuilder(::flatbuffers::FlatBufferBuilder &_fbb) explicit BenchmarkAssetBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) { : fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
@@ -118,10 +89,8 @@ struct BenchmarkAssetBuilder {
inline ::flatbuffers::Offset<BenchmarkAsset> CreateBenchmarkAsset( inline ::flatbuffers::Offset<BenchmarkAsset> CreateBenchmarkAsset(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> payload = 0, ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> payload = 0) {
::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::HardReference *>> refs = 0) {
BenchmarkAssetBuilder builder_(_fbb); BenchmarkAssetBuilder builder_(_fbb);
builder_.add_refs(refs);
builder_.add_payload(payload); builder_.add_payload(payload);
return builder_.Finish(); return builder_.Finish();
} }
@@ -143,7 +112,6 @@ inline void BenchmarkAsset::UnPackTo(BenchmarkAssetT *_o, const ::flatbuffers::r
(void)_o; (void)_o;
(void)_resolver; (void)_resolver;
{ auto _e = payload(); if (_e) { _o->payload.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->payload.begin()); } } { auto _e = payload(); if (_e) { _o->payload.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->payload.begin()); } }
{ auto _e = refs(); if (_e) { _o->refs.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->refs[_i] = ::flatbuffers::UnPackHardReferenceBenchmarkAssetReferred(*_e->Get(_i)); } } else { _o->refs.resize(0); } }
} }
inline ::flatbuffers::Offset<BenchmarkAsset> CreateBenchmarkAsset(::flatbuffers::FlatBufferBuilder &_fbb, const BenchmarkAssetT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) { inline ::flatbuffers::Offset<BenchmarkAsset> CreateBenchmarkAsset(::flatbuffers::FlatBufferBuilder &_fbb, const BenchmarkAssetT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
@@ -155,23 +123,17 @@ inline ::flatbuffers::Offset<BenchmarkAsset> BenchmarkAsset::Pack(::flatbuffers:
(void)_o; (void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const BenchmarkAssetT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const BenchmarkAssetT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _payload = _fbb.CreateVector(_o->payload.data(), _o->payload.size()); auto _payload = _fbb.CreateVector(_o->payload.data(), _o->payload.size());
auto _refs = _fbb.CreateVectorOfNativeStructs<Flat::Bigfoot::HardReference, ::Bigfoot::HardReference<::Bigfoot::BenchmarkAssetReferred>>(_o->refs.data(), _o->refs.size(), ::flatbuffers::PackHardReferenceBenchmarkAssetReferred);
return Flat::Bigfoot::CreateBenchmarkAsset( return Flat::Bigfoot::CreateBenchmarkAsset(
_fbb, _fbb,
_payload, _payload);
_refs);
} }
inline const ::flatbuffers::TypeTable *BenchmarkAssetTypeTable() { inline const ::flatbuffers::TypeTable *BenchmarkAssetTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = { static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_UCHAR, 1, -1 }, { ::flatbuffers::ET_UCHAR, 1, -1 }
{ ::flatbuffers::ET_SEQUENCE, 1, 0 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::HardReferenceTypeTable
}; };
static const ::flatbuffers::TypeTable tt = { static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, nullptr, nullptr ::flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, nullptr, nullptr
}; };
return &tt; return &tt;
} }
@@ -227,12 +189,4 @@ inline eastl::unique_ptr<Flat::Bigfoot::BenchmarkAssetT> UnPackSizePrefixedBench
} // namespace Bigfoot } // namespace Bigfoot
} // namespace Flat } // namespace Flat
namespace flatbuffers {
#ifndef FLATBUFFERS_BIGFOOT_REF_HARDREFERENCEBENCHMARKASSETREFERRED
#define FLATBUFFERS_BIGFOOT_REF_HARDREFERENCEBENCHMARKASSETREFERRED
inline Flat::Bigfoot::HardReference PackHardReferenceBenchmarkAssetReferred(const ::Bigfoot::HardReference<::Bigfoot::BenchmarkAssetReferred>& p_asset) { return {Pack(p_asset.GetUUID())}; }
inline ::Bigfoot::HardReference<::Bigfoot::BenchmarkAssetReferred> UnPackHardReferenceBenchmarkAssetReferred(const Flat::Bigfoot::HardReference& p_asset) { return {UnPack(p_asset.uuid())}; }
#endif // FLATBUFFERS_BIGFOOT_REF_HARDREFERENCEBENCHMARKASSETREFERRED
} // namespace flatbuffers
#endif // FLATBUFFERS_GENERATED_BENCHMARKASSET_FLAT_BIGFOOT_H_ #endif // FLATBUFFERS_GENERATED_BENCHMARKASSET_FLAT_BIGFOOT_H_
-3
View File
@@ -2,6 +2,3 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/AssetsForBenchmarking)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils)
if(${TOOLMODE})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Tools)
endif()
@@ -20,30 +20,9 @@ namespace
using Random = effolkronium::random_static; using Random = effolkronium::random_static;
} // namespace } // namespace
class AssetContainerFixture: public benchmark::Fixture
{
protected:
[[nodiscard]]
static eastl::vector<UUID> InsertRandomAssets(AssetContainer<BenchmarkAsset>& p_container,
const std::uint32_t p_count)
{
eastl::vector<UUID> uuids;
uuids.reserve(p_count);
for (std::uint32_t i = 0; i < p_count; ++i)
{
uuids.push_back(p_container.Insert()->GetAsset()->GetHeader().uuid);
}
Random::shuffle(uuids);
return uuids;
}
AssetContainer<BenchmarkAsset> m_container;
};
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(AssetContainerFixture, Insert)(benchmark::State& state) void Insert(benchmark::State& state)
{ {
const auto count = static_cast<std::uint32_t>(state.range(0)); const auto count = static_cast<std::uint32_t>(state.range(0));
@@ -62,29 +41,29 @@ BENCHMARK_DEFINE_F(AssetContainerFixture, Insert)(benchmark::State& state)
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations() * count * sizeof(BenchmarkAsset))); state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations() * count * sizeof(BenchmarkAsset)));
} }
BENCHMARK_REGISTER_F(AssetContainerFixture, Insert)->Name("AssetContainer/Insert")->Arg(512)->Arg(8192)->Arg(131'072); BENCHMARK(Insert)->Name("AssetContainer/Insert")->Arg(512)->Arg(8192)->Arg(131'072);
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(AssetContainerFixture, Get)(benchmark::State& state) void Get(benchmark::State& state)
{ {
const auto count = static_cast<std::uint32_t>(state.range(0)); const auto count = static_cast<std::uint32_t>(state.range(0));
const eastl::vector<UUID> uuids = InsertRandomAssets(m_container, count); AssetContainer<BenchmarkAsset> container;
eastl::vector<SlotMapKey<>> keys;
eastl::vector<ContainerHandle*> handles; keys.reserve(count);
handles.reserve(count); for (std::uint32_t i = 0; i < count; ++i)
for (const UUID& uuid: uuids)
{ {
handles.push_back(m_container.AcquireContainerHandle(uuid)); keys.push_back(container.Insert());
} }
Random::shuffle(keys);
for (auto _: state) for (auto _: state)
{ {
std::uint64_t sum = 0; std::uint64_t sum = 0;
for (ContainerHandle* const handle: handles) for (const SlotMapKey<> key: keys)
{ {
if (const auto* const asset = static_cast<const BenchmarkAsset*>(handle->GetAsset())) if (const BenchmarkAsset* const asset = container.Get(key))
{ {
sum += asset->GetHeader().type_id; sum += asset->GetHeader().type_id;
} }
@@ -95,22 +74,30 @@ BENCHMARK_DEFINE_F(AssetContainerFixture, Get)(benchmark::State& state)
state.SetItemsProcessed(state.iterations() * count); state.SetItemsProcessed(state.iterations() * count);
} }
BENCHMARK_REGISTER_F(AssetContainerFixture, Get)->Name("AssetContainer/Get")->Arg(512)->Arg(8192)->Arg(131'072); BENCHMARK(Get)->Name("AssetContainer/Get")->Arg(512)->Arg(8192)->Arg(131'072);
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(AssetContainerFixture, Has)(benchmark::State& state) void Has(benchmark::State& state)
{ {
const auto count = static_cast<std::uint32_t>(state.range(0)); const auto count = static_cast<std::uint32_t>(state.range(0));
const eastl::vector<UUID> uuids = InsertRandomAssets(m_container, count); AssetContainer<BenchmarkAsset> container;
eastl::vector<UUID> uuids;
uuids.reserve(count);
for (std::uint32_t i = 0; i < count; ++i)
{
const SlotMapKey<> key = container.Insert();
uuids.push_back(container.Get(key)->GetHeader().uuid);
}
Random::shuffle(uuids);
for (auto _: state) for (auto _: state)
{ {
bool result = true; bool result = true;
for (const UUID& uuid: uuids) for (const UUID& uuid: uuids)
{ {
result = result && m_container.Has(uuid); result = result && container.Has(uuid);
} }
benchmark::DoNotOptimize(result); benchmark::DoNotOptimize(result);
} }
@@ -118,22 +105,30 @@ BENCHMARK_DEFINE_F(AssetContainerFixture, Has)(benchmark::State& state)
state.SetItemsProcessed(state.iterations() * count); state.SetItemsProcessed(state.iterations() * count);
} }
BENCHMARK_REGISTER_F(AssetContainerFixture, Has)->Name("AssetContainer/Has")->Arg(512)->Arg(8192)->Arg(131'072); BENCHMARK(Has)->Name("AssetContainer/Has")->Arg(512)->Arg(8192)->Arg(131'072);
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(AssetContainerFixture, AcquireContainerHandle)(benchmark::State& state) void AcquireContainerHandle(benchmark::State& state)
{ {
const auto count = static_cast<std::uint32_t>(state.range(0)); const auto count = static_cast<std::uint32_t>(state.range(0));
const eastl::vector<UUID> uuids = InsertRandomAssets(m_container, count); AssetContainer<BenchmarkAsset> container;
eastl::vector<UUID> uuids;
uuids.reserve(count);
for (std::uint32_t i = 0; i < count; ++i)
{
const SlotMapKey<> key = container.Insert();
uuids.push_back(container.Get(key)->GetHeader().uuid);
}
Random::shuffle(uuids);
for (auto _: state) for (auto _: state)
{ {
std::uint64_t sum = 0; std::uint64_t sum = 0;
for (const UUID& uuid: uuids) for (const UUID& uuid: uuids)
{ {
sum += m_container.AcquireContainerHandle(uuid)->GetHardRefCount(); sum += container.AcquireContainerHandle(uuid)->GetHardRefCount();
} }
benchmark::DoNotOptimize(sum); benchmark::DoNotOptimize(sum);
} }
@@ -141,29 +136,33 @@ BENCHMARK_DEFINE_F(AssetContainerFixture, AcquireContainerHandle)(benchmark::Sta
state.SetItemsProcessed(state.iterations() * count); state.SetItemsProcessed(state.iterations() * count);
} }
BENCHMARK_REGISTER_F(AssetContainerFixture, AcquireContainerHandle) BENCHMARK(AcquireContainerHandle)->Name("AssetContainer/AcquireContainerHandle")->Arg(512)->Arg(8192)->Arg(131'072);
->Name("AssetContainer/AcquireContainerHandle")
->Arg(512)
->Arg(8192)
->Arg(131'072);
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(AssetContainerFixture, Remove)(benchmark::State& state) void Remove(benchmark::State& state)
{ {
const auto count = static_cast<std::uint32_t>(state.range(0)); const auto count = static_cast<std::uint32_t>(state.range(0));
AssetContainer<BenchmarkAsset> container;
eastl::vector<UUID> uuids; eastl::vector<UUID> uuids;
uuids.reserve(count);
for (auto _: state) for (auto _: state)
{ {
state.PauseTiming(); state.PauseTiming();
uuids = InsertRandomAssets(m_container, count); uuids.clear();
for (std::uint32_t i = 0; i < count; ++i)
{
const SlotMapKey<> key = container.Insert();
uuids.push_back(container.Get(key)->GetHeader().uuid);
}
Random::shuffle(uuids);
state.ResumeTiming(); state.ResumeTiming();
for (const UUID& uuid: uuids) for (const UUID& uuid: uuids)
{ {
m_container.Remove(uuid); container.Remove(uuid);
} }
} }
@@ -171,5 +170,5 @@ BENCHMARK_DEFINE_F(AssetContainerFixture, Remove)(benchmark::State& state)
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations() * count * sizeof(BenchmarkAsset))); state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations() * count * sizeof(BenchmarkAsset)));
} }
BENCHMARK_REGISTER_F(AssetContainerFixture, Remove)->Name("AssetContainer/Remove")->Arg(512)->Arg(8192)->Arg(131'072); BENCHMARK(Remove)->Name("AssetContainer/Remove")->Arg(512)->Arg(8192)->Arg(131'072);
} // namespace Bigfoot } // namespace Bigfoot
+56 -107
View File
@@ -10,7 +10,6 @@
#include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp> #include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp>
#include <EASTL/optional.h>
#include <EASTL/vector.h> #include <EASTL/vector.h>
#include <benchmark/benchmark.h> #include <benchmark/benchmark.h>
@@ -20,119 +19,96 @@
namespace Bigfoot namespace Bigfoot
{ {
template<template<class> class REFERENCE> template<template<class> class REFERENCE>
class ReferenceFixture: public benchmark::Fixture void Construct(benchmark::State& state)
{ {
protected: AssetLibrary library;
using ReferenceType = REFERENCE<BenchmarkAsset>; AssetContainer<BenchmarkAsset> container;
std::ignore = library.Insert(&container);
ScopedActiveAssetLibrary scopedLibrary {&library};
void SetUp(benchmark::State&) override const SlotMapKey<> key = container.Insert();
{ const UUID uuid = container.Get(key)->GetHeader().uuid;
SetActiveAssetLibrary(&m_library);
std::ignore = m_library.Insert(&m_container);
m_uuid = CreateAsset<BenchmarkAsset>()->GetHeader().uuid;
m_reference.emplace(m_uuid);
}
void TearDown(benchmark::State&) override
{
SetActiveAssetLibrary(&g_assetLibrary);
}
AssetLibrary m_library;
AssetContainer<BenchmarkAsset> m_container;
UUID m_uuid;
eastl::optional<ReferenceType> m_reference;
};
/****************************************************************************************/
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceConstruct, HardReference)(benchmark::State& state)
{
for (auto _: state) for (auto _: state)
{ {
ReferenceType reference {m_uuid}; REFERENCE<BenchmarkAsset> reference {uuid};
benchmark::DoNotOptimize(reference); benchmark::DoNotOptimize(reference);
} }
state.SetItemsProcessed(state.iterations()); state.SetItemsProcessed(state.iterations());
} }
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceConstruct)->Name("Reference/HardReference/Construct"); BENCHMARK_TEMPLATE(Construct, HardReference)->Name("Reference/HardReference/Construct");
BENCHMARK_TEMPLATE(Construct, SoftReference)->Name("Reference/SoftReference/Construct");
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceConstruct, SoftReference)(benchmark::State& state)
{
for (auto _: state)
{
ReferenceType reference {m_uuid};
benchmark::DoNotOptimize(reference);
}
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceConstruct)->Name("Reference/SoftReference/Construct");
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceGet, HardReference)(benchmark::State& state) template<template<class> class REFERENCE>
void Get(benchmark::State& state)
{ {
AssetLibrary library;
AssetContainer<BenchmarkAsset> container;
std::ignore = library.Insert(&container);
ScopedActiveAssetLibrary scopedLibrary {&library};
const SlotMapKey<> key = container.Insert();
const UUID uuid = container.Get(key)->GetHeader().uuid;
REFERENCE<BenchmarkAsset> reference {uuid};
for (auto _: state) for (auto _: state)
{ {
benchmark::DoNotOptimize(m_reference->Get()); benchmark::DoNotOptimize(reference.Get());
} }
state.SetItemsProcessed(state.iterations()); state.SetItemsProcessed(state.iterations());
} }
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceGet)->Name("Reference/HardReference/Get"); BENCHMARK_TEMPLATE(Get, HardReference)->Name("Reference/HardReference/Get");
BENCHMARK_TEMPLATE(Get, SoftReference)->Name("Reference/SoftReference/Get");
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceGet, SoftReference)(benchmark::State& state)
{
for (auto _: state)
{
benchmark::DoNotOptimize(m_reference->Get());
}
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceGet)->Name("Reference/SoftReference/Get");
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceCopy, HardReference)(benchmark::State& state) template<template<class> class REFERENCE>
void Copy(benchmark::State& state)
{ {
AssetLibrary library;
AssetContainer<BenchmarkAsset> container;
std::ignore = library.Insert(&container);
ScopedActiveAssetLibrary scopedLibrary {&library};
const SlotMapKey<> key = container.Insert();
const UUID uuid = container.Get(key)->GetHeader().uuid;
REFERENCE<BenchmarkAsset> reference {uuid};
for (auto _: state) for (auto _: state)
{ {
ReferenceType copy {*m_reference}; REFERENCE<BenchmarkAsset> copy {reference};
benchmark::DoNotOptimize(copy); benchmark::DoNotOptimize(copy);
} }
state.SetItemsProcessed(state.iterations()); state.SetItemsProcessed(state.iterations());
} }
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceCopy)->Name("Reference/HardReference/Copy"); BENCHMARK_TEMPLATE(Copy, HardReference)->Name("Reference/HardReference/Copy");
BENCHMARK_TEMPLATE(Copy, SoftReference)->Name("Reference/SoftReference/Copy");
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceCopy, SoftReference)(benchmark::State& state)
{
for (auto _: state)
{
ReferenceType copy {*m_reference};
benchmark::DoNotOptimize(copy);
}
state.SetItemsProcessed(state.iterations());
}
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceCopy)->Name("Reference/SoftReference/Copy");
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceMove, HardReference)(benchmark::State& state) template<template<class> class REFERENCE>
void Move(benchmark::State& state)
{ {
AssetLibrary library;
AssetContainer<BenchmarkAsset> container;
std::ignore = library.Insert(&container);
ScopedActiveAssetLibrary scopedLibrary {&library};
const SlotMapKey<> key = container.Insert();
const UUID uuid = container.Get(key)->GetHeader().uuid;
constexpr std::size_t BATCH_SIZE = 128; constexpr std::size_t BATCH_SIZE = 128;
eastl::vector<ReferenceType> batch; eastl::vector<REFERENCE<BenchmarkAsset>> batch;
batch.reserve(BATCH_SIZE); batch.reserve(BATCH_SIZE);
for (auto _: state) for (auto _: state)
@@ -141,13 +117,13 @@ BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceMove, HardReference)(
batch.clear(); batch.clear();
for (std::size_t i = 0; i < BATCH_SIZE; ++i) for (std::size_t i = 0; i < BATCH_SIZE; ++i)
{ {
batch.emplace_back(m_uuid); batch.emplace_back(uuid);
} }
state.ResumeTiming(); state.ResumeTiming();
for (ReferenceType& reference: batch) for (REFERENCE<BenchmarkAsset>& reference: batch)
{ {
ReferenceType moved {std::move(reference)}; REFERENCE<BenchmarkAsset> moved {std::move(reference)};
benchmark::DoNotOptimize(moved); benchmark::DoNotOptimize(moved);
} }
} }
@@ -155,33 +131,6 @@ BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceMove, HardReference)(
state.SetItemsProcessed(state.iterations() * BATCH_SIZE); state.SetItemsProcessed(state.iterations() * BATCH_SIZE);
} }
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceMove)->Name("Reference/HardReference/Move"); BENCHMARK_TEMPLATE(Move, HardReference)->Name("Reference/HardReference/Move");
BENCHMARK_TEMPLATE(Move, SoftReference)->Name("Reference/SoftReference/Move");
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceMove, SoftReference)(benchmark::State& state)
{
constexpr std::size_t BATCH_SIZE = 128;
eastl::vector<ReferenceType> batch;
batch.reserve(BATCH_SIZE);
for (auto _: state)
{
state.PauseTiming();
batch.clear();
for (std::size_t i = 0; i < BATCH_SIZE; ++i)
{
batch.emplace_back(m_uuid);
}
state.ResumeTiming();
for (ReferenceType& reference: batch)
{
ReferenceType moved {std::move(reference)};
benchmark::DoNotOptimize(moved);
}
}
state.SetItemsProcessed(state.iterations() * BATCH_SIZE);
}
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceMove)->Name("Reference/SoftReference/Move");
} // namespace Bigfoot } // namespace Bigfoot
+80 -116
View File
@@ -12,10 +12,7 @@
#include <EngineBenchmarks/BigFileInfo_generated.hpp> #include <EngineBenchmarks/BigFileInfo_generated.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp> #include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAssetReferred.hpp>
#include <EASTL/optional.h>
#include <EASTL/span.h>
#include <EASTL/vector.h> #include <EASTL/vector.h>
#include <benchmark/benchmark.h> #include <benchmark/benchmark.h>
#include <effolkronium/random.hpp> #include <effolkronium/random.hpp>
@@ -26,30 +23,47 @@
namespace Bigfoot namespace Bigfoot
{ {
#ifdef BIGFOOT_TOOLMODE #ifdef BIGFOOT_TOOLMODE
namespace
{
using Random = effolkronium::random_static; using Random = effolkronium::random_static;
class BigFileFixture: public benchmark::Fixture constexpr std::uint32_t ASSET_COUNT = 20'000;
constexpr std::size_t ASSET_PAYLOAD_SIZE = 256;
class Fixture: public benchmark::Fixture
{ {
public:
void SetUp(benchmark::State&) override
{
BigFile::Request {m_bigFile, "DELETE FROM Asset;"}.Execute();
BigFile::Request {m_bigFile, "DELETE FROM AssetMetadata;"}.Execute();
m_uuids.clear();
m_uuids.reserve(ASSET_COUNT);
eastl::vector<AssetMetadata> metadatas;
eastl::vector<eastl::vector<std::byte>> flatbuffers;
metadatas.reserve(ASSET_COUNT);
flatbuffers.reserve(ASSET_COUNT);
for (std::uint32_t i = 0; i < ASSET_COUNT; ++i)
{
BenchmarkAsset asset;
asset.SetName(asset.GetHeader().uuid.ToString().c_str());
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
metadatas.push_back(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
.m_name = asset.GetHeader().name,
.m_typeID = asset.GetHeader().type_id,
.m_typeName = asset.GetHeader().type_name});
flatbuffers.push_back(asset.Pack());
m_uuids.push_back(asset.GetHeader().uuid);
}
m_bigFile.SaveAssetFlatbuffers(metadatas, flatbuffers);
}
protected: protected:
static constexpr std::uint32_t ASSET_COUNT = 20'000;
static constexpr std::uint32_t REFS_PER_ASSET = 4;
static constexpr std::size_t ASSET_PAYLOAD_SIZE = 256;
void SetUp([[maybe_unused]] benchmark::State& p_state) override
{
// The DB is populated exactly once for the entire benchmark process.
// SetUp is called before every calibration round (Google Benchmark doubles
// iteration counts until it reaches a stable measurement), so rebuilding
// the DB each time would dominate the total benchmark time.
m_uuids = BuildData();
m_bigFile.emplace(File {BIGFILE_ENGINEBENCHMARKS_LOCATION});
}
void TearDown([[maybe_unused]] benchmark::State& p_state) override
{
m_bigFile.reset();
}
[[nodiscard]] [[nodiscard]]
eastl::vector<UUID> RandomBatch(const std::size_t p_batchSize) const eastl::vector<UUID> RandomBatch(const std::size_t p_batchSize) const
{ {
@@ -77,75 +91,38 @@ class BigFileFixture: public benchmark::Fixture
return pool; return pool;
} }
eastl::optional<BigFile> m_bigFile; BigFile m_bigFile {File {BIGFILE_ENGINEBENCHMARKS_LOCATION}};
eastl::span<const UUID> m_uuids; eastl::vector<UUID> m_uuids;
private:
static const eastl::vector<UUID>& BuildData()
{
static const eastl::vector<UUID> s_uuids = []()
{
eastl::vector<UUID> uuids;
eastl::vector<eastl::vector<std::byte>> flatbuffers;
eastl::vector<eastl::vector<UUID>> hardReferences;
uuids.reserve(ASSET_COUNT);
flatbuffers.reserve(ASSET_COUNT);
hardReferences.reserve(ASSET_COUNT);
for (std::uint32_t i = 0; i < ASSET_COUNT; ++i)
{
BenchmarkAsset asset;
asset.SetName(asset.GetHeader().uuid.ToString());
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
for (std::uint32_t j = 0; j < REFS_PER_ASSET; ++j)
{
BenchmarkAssetReferred assetReferred;
assetReferred.SetName(assetReferred.GetHeader().uuid.ToString());
asset.GetAsset().refs.emplace_back(assetReferred.GetHeader().uuid);
}
eastl::vector<std::byte> flatbuffer = asset.Pack();
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
flatbuffers.push_back(std::move(flatbuffer));
uuids.push_back(asset.GetHeader().uuid);
}
BigFile bigFile {File {BIGFILE_ENGINEBENCHMARKS_LOCATION}};
bigFile.Clear();
bigFile.SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences);
return uuids;
}();
return s_uuids;
}
}; };
} // namespace
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(BigFileFixture, GetAssetFlatbuffer)(benchmark::State& state) BENCHMARK_DEFINE_F(Fixture, GetAssetFlatbuffer)(benchmark::State& state)
{ {
std::int64_t bytesProcessed = 0; std::int64_t bytesProcessed = 0;
for (auto _: state) for (auto _: state)
{ {
eastl::vector<std::byte> flatbuffer = m_bigFile->GetAssetFlatbuffer( eastl::optional<eastl::vector<std::byte>> flatbuffer = m_bigFile.GetAssetFlatbuffer(
m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]); m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]);
benchmark::DoNotOptimize(flatbuffer); benchmark::DoNotOptimize(flatbuffer);
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size()); if (flatbuffer.has_value())
{
bytesProcessed += static_cast<std::int64_t>(flatbuffer->size());
}
} }
state.SetItemsProcessed(state.iterations()); state.SetItemsProcessed(state.iterations());
state.SetBytesProcessed(bytesProcessed); state.SetBytesProcessed(bytesProcessed);
} }
BENCHMARK_REGISTER_F(BigFileFixture, GetAssetFlatbuffer)->Name("BigFile/GetAssetFlatbuffer")->UseRealTime(); BENCHMARK_REGISTER_F(Fixture, GetAssetFlatbuffer)->Name("BigFile/GetAssetFlatbuffer");
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(BigFileFixture, GetAssetFlatbuffers)(benchmark::State& state) BENCHMARK_DEFINE_F(Fixture, GetAssetFlatbuffers)(benchmark::State& state)
{ {
const auto batchSize = static_cast<std::size_t>(state.range(0)); const auto batchSize = static_cast<std::size_t>(state.range(0));
@@ -157,7 +134,7 @@ BENCHMARK_DEFINE_F(BigFileFixture, GetAssetFlatbuffers)(benchmark::State& state)
for (auto _: state) for (auto _: state)
{ {
eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile->GetAssetFlatbuffers(batchPool[batchIndex]); eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(batchPool[batchIndex]);
benchmark::DoNotOptimize(flatbuffers); benchmark::DoNotOptimize(flatbuffers);
for (const eastl::vector<std::byte>& flatbuffer: flatbuffers) for (const eastl::vector<std::byte>& flatbuffer: flatbuffers)
@@ -172,34 +149,31 @@ BENCHMARK_DEFINE_F(BigFileFixture, GetAssetFlatbuffers)(benchmark::State& state)
state.SetBytesProcessed(bytesProcessed); state.SetBytesProcessed(bytesProcessed);
} }
BENCHMARK_REGISTER_F(BigFileFixture, GetAssetFlatbuffers) BENCHMARK_REGISTER_F(Fixture, GetAssetFlatbuffers)
->Name("BigFile/GetAssetFlatbuffers") ->Name("BigFile/GetAssetFlatbuffers")
->Arg(1) ->Arg(1)
->Arg(8) ->Arg(8)
->Arg(64) ->Arg(64)
->Arg(512) ->Arg(512)
->Arg(4096) ->Arg(4096);
->UseRealTime();
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(BigFileFixture, GetAssetHardReferences)(benchmark::State& state) BENCHMARK_DEFINE_F(Fixture, GetAssetMetadata)(benchmark::State& state)
{ {
for (auto _: state) for (auto _: state)
{ {
benchmark::DoNotOptimize( benchmark::DoNotOptimize(m_bigFile.GetAssetMetadata(m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]));
m_bigFile->GetAssetHardReferences(m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]));
} }
state.SetItemsProcessed(state.iterations()); state.SetItemsProcessed(state.iterations());
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations()) * REFS_PER_ASSET * UUID::UUID_BYTE_SIZE);
} }
BENCHMARK_REGISTER_F(BigFileFixture, GetAssetHardReferences)->Name("BigFile/GetAssetHardReferences")->UseRealTime(); BENCHMARK_REGISTER_F(Fixture, GetAssetMetadata)->Name("BigFile/GetAssetMetadata");
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(BigFileFixture, GetAssetsHardReferences)(benchmark::State& state) BENCHMARK_DEFINE_F(Fixture, GetAssetMetadatas)(benchmark::State& state)
{ {
const auto batchSize = static_cast<std::size_t>(state.range(0)); const auto batchSize = static_cast<std::size_t>(state.range(0));
@@ -209,27 +183,24 @@ BENCHMARK_DEFINE_F(BigFileFixture, GetAssetsHardReferences)(benchmark::State& st
std::size_t batchIndex = 0; std::size_t batchIndex = 0;
for (auto _: state) for (auto _: state)
{ {
benchmark::DoNotOptimize(m_bigFile->GetAssetsHardReferences(batchPool[batchIndex])); benchmark::DoNotOptimize(m_bigFile.GetAssetMetadatas(batchPool[batchIndex]));
batchIndex = (batchIndex + 1) % BATCH_POOL_SIZE; batchIndex = (batchIndex + 1) % BATCH_POOL_SIZE;
} }
state.SetItemsProcessed(state.iterations() * batchSize); state.SetItemsProcessed(state.iterations() * batchSize);
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations()) * batchSize * REFS_PER_ASSET *
UUID::UUID_BYTE_SIZE);
} }
BENCHMARK_REGISTER_F(BigFileFixture, GetAssetsHardReferences) BENCHMARK_REGISTER_F(Fixture, GetAssetMetadatas)
->Name("BigFile/GetAssetsHardReferences") ->Name("BigFile/GetAssetMetadatas")
->Arg(1) ->Arg(1)
->Arg(8) ->Arg(8)
->Arg(64) ->Arg(64)
->Arg(512) ->Arg(512)
->Arg(4096) ->Arg(4096);
->UseRealTime();
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(BigFileFixture, SaveAssetFlatbuffer)(benchmark::State& state) BENCHMARK_DEFINE_F(Fixture, SaveAssetFlatbuffer)(benchmark::State& state)
{ {
std::int64_t bytesProcessed = 0; std::int64_t bytesProcessed = 0;
@@ -237,30 +208,29 @@ BENCHMARK_DEFINE_F(BigFileFixture, SaveAssetFlatbuffer)(benchmark::State& state)
{ {
state.PauseTiming(); state.PauseTiming();
BenchmarkAsset asset; BenchmarkAsset asset;
asset.SetName(asset.GetHeader().uuid.ToString()); asset.SetName(asset.GetHeader().uuid.ToString().c_str());
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB}); asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
for (std::uint32_t j = 0; j < REFS_PER_ASSET; ++j)
{
asset.GetAsset().refs.emplace_back(m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]);
}
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
.m_name = asset.GetHeader().name,
.m_typeID = asset.GetHeader().type_id,
.m_typeName = asset.GetHeader().type_name};
const eastl::vector<std::byte> flatbuffer = asset.Pack(); const eastl::vector<std::byte> flatbuffer = asset.Pack();
const eastl::vector<UUID> hardReferences = asset.GetHardReferences(flatbuffer);
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size()); bytesProcessed += static_cast<std::int64_t>(flatbuffer.size());
state.ResumeTiming(); state.ResumeTiming();
m_bigFile->SaveAssetFlatbuffer(asset.GetHeader().uuid, flatbuffer, hardReferences); m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer);
} }
state.SetItemsProcessed(state.iterations()); state.SetItemsProcessed(state.iterations());
state.SetBytesProcessed(bytesProcessed); state.SetBytesProcessed(bytesProcessed);
} }
BENCHMARK_REGISTER_F(BigFileFixture, SaveAssetFlatbuffer)->Name("BigFile/SaveAssetFlatbuffer")->UseRealTime(); BENCHMARK_REGISTER_F(Fixture, SaveAssetFlatbuffer)->Name("BigFile/SaveAssetFlatbuffer");
/****************************************************************************************/ /****************************************************************************************/
BENCHMARK_DEFINE_F(BigFileFixture, SaveAssetFlatbuffers)(benchmark::State& state) BENCHMARK_DEFINE_F(Fixture, SaveAssetFlatbuffers)(benchmark::State& state)
{ {
const auto batchSize = static_cast<std::size_t>(state.range(0)); const auto batchSize = static_cast<std::size_t>(state.range(0));
std::int64_t bytesProcessed = 0; std::int64_t bytesProcessed = 0;
@@ -268,45 +238,39 @@ BENCHMARK_DEFINE_F(BigFileFixture, SaveAssetFlatbuffers)(benchmark::State& state
for (auto _: state) for (auto _: state)
{ {
state.PauseTiming(); state.PauseTiming();
eastl::vector<UUID> uuids; eastl::vector<AssetMetadata> metadatas;
eastl::vector<eastl::vector<std::byte>> flatbuffers; eastl::vector<eastl::vector<std::byte>> flatbuffers;
eastl::vector<eastl::vector<UUID>> hardReferences; metadatas.reserve(batchSize);
uuids.reserve(batchSize);
flatbuffers.reserve(batchSize); flatbuffers.reserve(batchSize);
hardReferences.reserve(batchSize);
for (std::size_t i = 0; i < batchSize; ++i) for (std::size_t i = 0; i < batchSize; ++i)
{ {
BenchmarkAsset asset; BenchmarkAsset asset;
asset.SetName(asset.GetHeader().uuid.ToString()); asset.SetName(asset.GetHeader().uuid.ToString().c_str());
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB}); asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
for (std::uint32_t j = 0; j < REFS_PER_ASSET; ++j)
{
asset.GetAsset().refs.emplace_back(m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]);
}
eastl::vector<std::byte> flatbuffer = asset.Pack(); metadatas.push_back(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
uuids.push_back(asset.GetHeader().uuid); .m_name = asset.GetHeader().name,
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size()); .m_typeID = asset.GetHeader().type_id,
hardReferences.push_back(asset.GetHardReferences(flatbuffer)); .m_typeName = asset.GetHeader().type_name});
flatbuffers.push_back(std::move(flatbuffer)); flatbuffers.push_back(asset.Pack());
bytesProcessed += static_cast<std::int64_t>(flatbuffers.back().size());
} }
state.ResumeTiming(); state.ResumeTiming();
m_bigFile->SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences); m_bigFile.SaveAssetFlatbuffers(metadatas, flatbuffers);
} }
state.SetItemsProcessed(state.iterations() * batchSize); state.SetItemsProcessed(state.iterations() * batchSize);
state.SetBytesProcessed(bytesProcessed); state.SetBytesProcessed(bytesProcessed);
} }
BENCHMARK_REGISTER_F(BigFileFixture, SaveAssetFlatbuffers) BENCHMARK_REGISTER_F(Fixture, SaveAssetFlatbuffers)
->Name("BigFile/SaveAssetFlatbuffers") ->Name("BigFile/SaveAssetFlatbuffers")
->Arg(1) ->Arg(1)
->Arg(8) ->Arg(8)
->Arg(64) ->Arg(64)
->Arg(512) ->Arg(512)
->Arg(4096) ->Arg(4096);
->UseRealTime();
#endif #endif
} // namespace Bigfoot } // namespace Bigfoot
-2
View File
@@ -10,5 +10,3 @@ target_link_libraries(${PROJECT_NAME}
$<LINK_LIBRARY:WHOLE_ARCHIVE,AssetsForBenchmarking>) $<LINK_LIBRARY:WHOLE_ARCHIVE,AssetsForBenchmarking>)
bigfoot_create_bigfile("Benchmarks/Bigfoot") bigfoot_create_bigfile("Benchmarks/Bigfoot")
bigfoot_create_sasquatch_info()
@@ -16,7 +16,7 @@ namespace Bigfoot
/* /*
* BigFile location * BigFile location
*/ */
constexpr eastl::string_view BIGFILE_ENGINEBENCHMARKS_LOCATION {"./EngineBenchmarks.db"}; constexpr eastl::string_view BIGFILE_ENGINEBENCHMARKS_LOCATION {"./EngineBenchmarks-bigfile.db"};
} // namespace Bigfoot } // namespace Bigfoot
#endif #endif
#endif #endif
@@ -1,22 +0,0 @@
// AUTO-GENERATED DO NOT TOUCH
/*********************************************************************
* \file SasquatchInfo.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_ENGINEBENCHMARKS_SASQUATCHINFO_GENERATED_HPP
#define BIGFOOT_ENGINEBENCHMARKS_SASQUATCHINFO_GENERATED_HPP
#include <EASTL/string_view.h>
#if defined BIGFOOT_GAME
namespace Bigfoot
{
/*
* Sasquatch location
*/
constexpr eastl::string_view SASQUATCH_ENGINEBENCHMARKS_LOCATION {"./EngineBenchmarks.sasquatch"};
} // namespace Bigfoot
#endif
#endif
@@ -1,245 +0,0 @@
/*********************************************************************
* \file Sasquatch.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <Engine/Sasquatch/Sasquatch.hpp>
#include <System/File/File.hpp>
#include <System/UUID/UUID.hpp>
#include <EngineBenchmarks/SasquatchInfo_generated.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAssetReferred.hpp>
#include <EASTL/optional.h>
#include <EASTL/span.h>
#include <EASTL/vector.h>
#include <benchmark/benchmark.h>
#include <effolkronium/random.hpp>
#include <cstddef>
#include <cstdint>
namespace Bigfoot
{
#ifdef BIGFOOT_GAME
using Random = effolkronium::random_static;
class SasquatchFixture: public benchmark::Fixture
{
protected:
static constexpr std::uint32_t ASSET_COUNT = 20'000;
static constexpr std::uint32_t REFS_PER_ASSET = 4;
static constexpr std::size_t ASSET_PAYLOAD_SIZE = 256;
void SetUp([[maybe_unused]] benchmark::State& p_state) override
{
// The Sasquatch file is built exactly once for the entire benchmark process.
// SetUp is called before every calibration round (Google Benchmark doubles
// iteration counts until it reaches a stable measurement), so rebuilding
// the file each time would dominate the total benchmark time.
m_uuids = BuildData();
m_sasquatch.emplace(File {SASQUATCH_ENGINEBENCHMARKS_LOCATION});
}
void TearDown([[maybe_unused]] benchmark::State& p_state) override
{
m_sasquatch.reset();
}
[[nodiscard]]
eastl::vector<UUID> RandomBatch(const std::size_t p_batchSize) const
{
eastl::vector<UUID> batch;
batch.reserve(p_batchSize);
for (std::size_t i = 0; i < p_batchSize; ++i)
{
batch.push_back(m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]);
}
return batch;
}
[[nodiscard]]
eastl::vector<eastl::vector<UUID>> RandomBatchPool(const std::size_t p_batchSize,
const std::size_t p_poolSize) const
{
eastl::vector<eastl::vector<UUID>> pool;
pool.reserve(p_poolSize);
for (std::size_t i = 0; i < p_poolSize; ++i)
{
pool.push_back(RandomBatch(p_batchSize));
}
return pool;
}
eastl::optional<Sasquatch> m_sasquatch;
eastl::span<const UUID> m_uuids;
private:
static const eastl::vector<UUID>& BuildData()
{
static const eastl::vector<UUID> s_uuids = []()
{
File {SASQUATCH_ENGINEBENCHMARKS_LOCATION}.Delete();
eastl::vector<UUID> uuids;
eastl::vector<eastl::vector<std::byte>> flatbuffers;
eastl::vector<eastl::vector<UUID>> hardReferences;
uuids.reserve(ASSET_COUNT);
flatbuffers.reserve(ASSET_COUNT);
hardReferences.reserve(ASSET_COUNT);
for (std::uint32_t i = 0; i < ASSET_COUNT; ++i)
{
BenchmarkAsset asset;
asset.SetName(asset.GetHeader().uuid.ToString());
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
for (std::uint32_t j = 0; j < REFS_PER_ASSET; ++j)
{
BenchmarkAssetReferred assetReferred;
assetReferred.SetName(assetReferred.GetHeader().uuid.ToString());
asset.GetAsset().refs.emplace_back(assetReferred.GetHeader().uuid);
}
eastl::vector<std::byte> flatbuffer = asset.Pack();
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
flatbuffers.push_back(std::move(flatbuffer));
uuids.push_back(asset.GetHeader().uuid);
}
std::size_t totalFlatbufferBytes = 0;
std::size_t totalHardReferencesBytes = 0;
for (std::size_t i = 0; i < uuids.size(); ++i)
{
totalFlatbufferBytes += flatbuffers[i].size();
totalHardReferencesBytes += hardReferences[i].size() * UUID::UUID_BYTE_SIZE;
}
SasquatchWriter writer {File {SASQUATCH_ENGINEBENCHMARKS_LOCATION},
uuids.size(),
totalFlatbufferBytes,
totalHardReferencesBytes};
for (std::size_t i = 0; i < uuids.size(); ++i)
{
writer.WriteAsset(uuids[i], flatbuffers[i], hardReferences[i]);
}
return uuids;
}();
return s_uuids;
}
};
/****************************************************************************************/
BENCHMARK_DEFINE_F(SasquatchFixture, GetAssetHardReferences)(benchmark::State& state)
{
for (auto _: state)
{
benchmark::DoNotOptimize(
m_sasquatch->GetAssetHardReferences(m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]));
}
state.SetItemsProcessed(state.iterations());
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations()) * REFS_PER_ASSET * UUID::UUID_BYTE_SIZE);
}
BENCHMARK_REGISTER_F(SasquatchFixture, GetAssetHardReferences)->Name("Sasquatch/GetAssetHardReferences")->UseRealTime();
/****************************************************************************************/
BENCHMARK_DEFINE_F(SasquatchFixture, GetAssetsHardReferences)(benchmark::State& state)
{
const auto batchSize = static_cast<std::size_t>(state.range(0));
constexpr std::size_t BATCH_POOL_SIZE = 64;
const eastl::vector<eastl::vector<UUID>> batchPool = RandomBatchPool(batchSize, BATCH_POOL_SIZE);
std::size_t batchIndex = 0;
for (auto _: state)
{
benchmark::DoNotOptimize(m_sasquatch->GetAssetsHardReferences(batchPool[batchIndex]));
batchIndex = (batchIndex + 1) % BATCH_POOL_SIZE;
}
state.SetItemsProcessed(state.iterations() * batchSize);
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations()) * batchSize * REFS_PER_ASSET *
UUID::UUID_BYTE_SIZE);
}
BENCHMARK_REGISTER_F(SasquatchFixture, GetAssetsHardReferences)
->Name("Sasquatch/GetAssetsHardReferences")
->Arg(1)
->Arg(8)
->Arg(64)
->Arg(512)
->Arg(4096)
->UseRealTime();
/****************************************************************************************/
BENCHMARK_DEFINE_F(SasquatchFixture, GetAssetFlatbuffer)(benchmark::State& state)
{
std::int64_t bytesProcessed = 0;
for (auto _: state)
{
eastl::vector<std::byte> flatbuffer = m_sasquatch->GetAssetFlatbuffer(
m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]);
benchmark::DoNotOptimize(flatbuffer);
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size());
}
state.SetItemsProcessed(state.iterations());
state.SetBytesProcessed(bytesProcessed);
}
BENCHMARK_REGISTER_F(SasquatchFixture, GetAssetFlatbuffer)->Name("Sasquatch/GetAssetFlatbuffer")->UseRealTime();
/****************************************************************************************/
BENCHMARK_DEFINE_F(SasquatchFixture, GetAssetFlatbuffers)(benchmark::State& state)
{
const auto batchSize = static_cast<std::size_t>(state.range(0));
constexpr std::size_t BATCH_POOL_SIZE = 64;
const eastl::vector<eastl::vector<UUID>> batchPool = RandomBatchPool(batchSize, BATCH_POOL_SIZE);
std::int64_t bytesProcessed = 0;
std::size_t batchIndex = 0;
for (auto _: state)
{
eastl::vector<eastl::vector<std::byte>> flatbuffers = m_sasquatch->GetAssetFlatbuffers(batchPool[batchIndex]);
benchmark::DoNotOptimize(flatbuffers);
for (const eastl::vector<std::byte>& flatbuffer: flatbuffers)
{
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size());
}
batchIndex = (batchIndex + 1) % BATCH_POOL_SIZE;
}
state.SetItemsProcessed(state.iterations() * batchSize);
state.SetBytesProcessed(bytesProcessed);
}
BENCHMARK_REGISTER_F(SasquatchFixture, GetAssetFlatbuffers)
->Name("Sasquatch/GetAssetFlatbuffers")
->Arg(1)
->Arg(8)
->Arg(64)
->Arg(512)
->Arg(4096)
->UseRealTime();
#endif
} // namespace Bigfoot
@@ -1,391 +0,0 @@
/*********************************************************************
* \file SerializationManager.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <Engine/SerializationManager/SerializationManager.hpp>
#include <Engine/Asset/AssetLibrary.hpp>
#include <Engine/DataAccessor/DataAccessor.hpp>
#if defined BIGFOOT_TOOLMODE
#include <Engine/BigFile/BigFile.hpp>
#include <EngineBenchmarks/BigFileInfo_generated.hpp>
#elif defined BIGFOOT_GAME
#include <Engine/Sasquatch/Sasquatch.hpp>
#include <EngineBenchmarks/SasquatchInfo_generated.hpp>
#endif
#include <System/File/File.hpp>
#include <System/UUID/UUID.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAssetReferred.hpp>
#include <EASTL/optional.h>
#include <EASTL/span.h>
#include <EASTL/vector.h>
#include <ankerl/unordered_dense.h>
#include <benchmark/benchmark.h>
#include <effolkronium/random.hpp>
#include <cstddef>
#include <cstdint>
#include <tuple>
namespace Bigfoot
{
using Random = effolkronium::random_static;
class SerializationManagerFixture: public benchmark::Fixture
{
protected:
static constexpr std::uint32_t ROOT_ASSET_COUNT = 20'000;
static constexpr std::uint32_t REFS_PER_ROOT = 4;
static constexpr std::size_t ASSET_PAYLOAD_SIZE = 256;
void SetUp([[maybe_unused]] benchmark::State& p_state) override
{
m_previousDataAccessor = g_dataAccessor;
m_previousAssetLibrary = g_activeAssetLibrary;
// The data store is populated exactly once for the entire benchmark process.
// SetUp is called before every calibration round (Google Benchmark doubles
// iteration counts until it reaches a stable measurement), so rebuilding
// the data store each time would dominate the total benchmark time.
static const SharedData& s_data = BuildData();
m_rootUuids = s_data.rootUuids;
m_leafUuids = s_data.leafUuids;
m_rootTotalBytes = &s_data.rootTotalBytes;
#if defined BIGFOOT_TOOLMODE
m_bigFile.emplace(File {BIGFILE_ENGINEBENCHMARKS_LOCATION});
SetDataAccessor(&*m_bigFile);
#elif defined BIGFOOT_GAME
m_sasquatch.emplace(File {SASQUATCH_ENGINEBENCHMARKS_LOCATION});
SetDataAccessor(&*m_sasquatch);
#endif
}
void TearDown([[maybe_unused]] benchmark::State& p_state) override
{
#if defined BIGFOOT_TOOLMODE
m_bigFile.reset();
#elif defined BIGFOOT_GAME
m_sasquatch.reset();
#endif
SetDataAccessor(m_previousDataAccessor);
SetActiveAssetLibrary(m_previousAssetLibrary);
}
/*
* Registers a fresh, empty AssetLibrary as the active one, so that every root and leaf asset appears unloaded
*
* \param p_library The library to register
* \param p_leafContainer The container to register leaves into
* \param p_rootContainer The container to register roots into
*/
static void ResetActiveLibrary(AssetLibrary& p_library,
AssetContainer<BenchmarkAssetReferred>& p_leafContainer,
AssetContainer<BenchmarkAsset>& p_rootContainer)
{
std::ignore = p_library.Insert(&p_leafContainer);
std::ignore = p_library.Insert(&p_rootContainer);
SetActiveAssetLibrary(&p_library);
}
[[nodiscard]]
eastl::vector<UUID> RandomRootBatch(const std::size_t p_batchSize) const
{
eastl::vector<UUID> batch;
batch.reserve(p_batchSize);
for (std::size_t i = 0; i < p_batchSize; ++i)
{
batch.push_back(m_rootUuids[Random::get<std::size_t>(0, m_rootUuids.size() - 1)]);
}
return batch;
}
/*
* Total flatbuffer bytes (root + its leaves) that loading p_roots will actually read, deduplicated the same way
* SerializationManager::LoadAssets deduplicates its own transitive discovery
*
* \param p_roots The root assets that would be loaded
* \return The total flatbuffer bytes across the unique roots
*/
[[nodiscard]]
std::int64_t TotalBytes(const eastl::vector<UUID>& p_roots) const
{
ankerl::unordered_dense::set<UUID> unique;
unique.reserve(p_roots.size());
for (const UUID& uuid: p_roots)
{
unique.insert(uuid);
}
std::int64_t bytes = 0;
for (const UUID& uuid: unique)
{
bytes += static_cast<std::int64_t>(m_rootTotalBytes->at(uuid));
}
return bytes;
}
DataAccessor* m_previousDataAccessor = nullptr;
AssetLibrary* m_previousAssetLibrary = nullptr;
eastl::span<const UUID> m_rootUuids;
eastl::span<const UUID> m_leafUuids;
const ankerl::unordered_dense::map<UUID, std::size_t>* m_rootTotalBytes = nullptr;
#if defined BIGFOOT_TOOLMODE
eastl::optional<BigFile> m_bigFile;
#elif defined BIGFOOT_GAME
eastl::optional<Sasquatch> m_sasquatch;
#endif
private:
struct SharedData
{
eastl::vector<UUID> rootUuids;
eastl::vector<UUID> leafUuids;
ankerl::unordered_dense::map<UUID, std::size_t> rootTotalBytes;
};
static const SharedData& BuildData()
{
static const SharedData s_data = []()
{
SharedData data;
data.rootUuids.reserve(ROOT_ASSET_COUNT);
data.leafUuids.reserve(ROOT_ASSET_COUNT * REFS_PER_ROOT);
data.rootTotalBytes.reserve(ROOT_ASSET_COUNT);
eastl::vector<UUID> uuids;
eastl::vector<eastl::vector<std::byte>> flatbuffers;
eastl::vector<eastl::vector<UUID>> hardReferences;
uuids.reserve(ROOT_ASSET_COUNT * (1 + REFS_PER_ROOT));
flatbuffers.reserve(uuids.capacity());
hardReferences.reserve(uuids.capacity());
for (std::uint32_t i = 0; i < ROOT_ASSET_COUNT; ++i)
{
BenchmarkAsset root;
root.SetName(root.GetHeader().uuid.ToString());
root.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
std::size_t totalBytes = 0;
for (std::uint32_t j = 0; j < REFS_PER_ROOT; ++j)
{
BenchmarkAssetReferred leaf;
leaf.SetName(leaf.GetHeader().uuid.ToString());
root.GetAsset().refs.emplace_back(leaf.GetHeader().uuid);
eastl::vector<std::byte> leafFlatbuffer = leaf.Pack();
totalBytes += leafFlatbuffer.size();
data.leafUuids.push_back(leaf.GetHeader().uuid);
uuids.push_back(leaf.GetHeader().uuid);
hardReferences.push_back(leaf.GetHardReferences(leafFlatbuffer));
flatbuffers.push_back(std::move(leafFlatbuffer));
}
eastl::vector<std::byte> rootFlatbuffer = root.Pack();
totalBytes += rootFlatbuffer.size();
data.rootTotalBytes.emplace(root.GetHeader().uuid, totalBytes);
data.rootUuids.push_back(root.GetHeader().uuid);
uuids.push_back(root.GetHeader().uuid);
hardReferences.push_back(root.GetHardReferences(rootFlatbuffer));
flatbuffers.push_back(std::move(rootFlatbuffer));
}
#if defined BIGFOOT_TOOLMODE
BigFile bigFile {File { BIGFILE_ENGINEBENCHMARKS_LOCATION }};
bigFile.Clear();
bigFile.SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences);
#elif defined BIGFOOT_GAME
std::size_t totalFlatbufferBytes = 0;
std::size_t totalHardReferencesBytes = 0;
for (std::size_t i = 0; i < uuids.size(); ++i)
{
totalFlatbufferBytes += flatbuffers[i].size();
totalHardReferencesBytes += hardReferences[i].size() * UUID::UUID_BYTE_SIZE;
}
File {SASQUATCH_ENGINEBENCHMARKS_LOCATION}.Delete();
SasquatchWriter writer {File {SASQUATCH_ENGINEBENCHMARKS_LOCATION},
uuids.size(),
totalFlatbufferBytes,
totalHardReferencesBytes};
for (std::size_t i = 0; i < uuids.size(); ++i)
{
writer.WriteAsset(uuids[i], flatbuffers[i], hardReferences[i]);
}
#endif
return data;
}();
return s_data;
}
};
/****************************************************************************************/
BENCHMARK_DEFINE_F(SerializationManagerFixture, LoadAsset)(benchmark::State& state)
{
std::int64_t bytesProcessed = 0;
for (auto _: state)
{
state.PauseTiming();
AssetLibrary library;
// leafContainer must outlive rootContainer: the loaded root's HardReferences release into leafContainer's
// handles on destruction, so declaring it second would tear it down first and use-after-free those handles.
AssetContainer<BenchmarkAssetReferred> leafContainer;
AssetContainer<BenchmarkAsset> rootContainer;
ResetActiveLibrary(library, leafContainer, rootContainer);
const UUID uuid = m_rootUuids[Random::get<std::size_t>(0, m_rootUuids.size() - 1)];
const std::size_t uuidBytes = m_rootTotalBytes->at(uuid);
state.ResumeTiming();
SerializationManager::LoadAsset(uuid);
bytesProcessed += static_cast<std::int64_t>(uuidBytes);
}
state.SetItemsProcessed(state.iterations() * (1 + REFS_PER_ROOT));
state.SetBytesProcessed(bytesProcessed);
}
BENCHMARK_REGISTER_F(SerializationManagerFixture, LoadAsset)->Name("SerializationManager/LoadAsset")->UseRealTime();
/****************************************************************************************/
BENCHMARK_DEFINE_F(SerializationManagerFixture, LoadAssets)(benchmark::State& state)
{
const auto batchSize = static_cast<std::size_t>(state.range(0));
std::int64_t bytesProcessed = 0;
for (auto _: state)
{
state.PauseTiming();
AssetLibrary library;
// leafContainer must outlive rootContainer, see the same comment in the LoadAsset benchmark above.
AssetContainer<BenchmarkAssetReferred> leafContainer;
AssetContainer<BenchmarkAsset> rootContainer;
ResetActiveLibrary(library, leafContainer, rootContainer);
const eastl::vector<UUID> batch = RandomRootBatch(batchSize);
const std::int64_t batchBytes = TotalBytes(batch);
state.ResumeTiming();
SerializationManager::LoadAssets(batch);
bytesProcessed += batchBytes;
}
state.SetItemsProcessed(state.iterations() * batchSize * (1 + REFS_PER_ROOT));
state.SetBytesProcessed(bytesProcessed);
}
BENCHMARK_REGISTER_F(SerializationManagerFixture, LoadAssets)
->Name("SerializationManager/LoadAssets")
->Arg(1)
->Arg(8)
->Arg(64)
->Arg(512)
->Arg(4096)
->UseRealTime();
/****************************************************************************************/
#if defined BIGFOOT_TOOLMODE
BENCHMARK_DEFINE_F(SerializationManagerFixture, SaveAsset)(benchmark::State& state)
{
AssetLibrary library;
AssetContainer<BenchmarkAsset> container;
std::ignore = library.Insert(&container);
SetActiveAssetLibrary(&library);
std::int64_t bytesProcessed = 0;
for (auto _: state)
{
state.PauseTiming();
auto* asset = CreateAsset<BenchmarkAsset>();
asset->SetName(asset->GetHeader().uuid.ToString());
asset->GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
for (std::uint32_t j = 0; j < REFS_PER_ROOT; ++j)
{
asset->GetAsset().refs.emplace_back(m_leafUuids[Random::get<std::size_t>(0, m_leafUuids.size() - 1)]);
}
const UUID uuid = asset->GetHeader().uuid;
const std::size_t assetBytes = asset->Pack().size();
bytesProcessed += static_cast<std::int64_t>(assetBytes);
state.ResumeTiming();
benchmark::DoNotOptimize(SerializationManager::SaveAsset(uuid));
}
state.SetItemsProcessed(state.iterations());
state.SetBytesProcessed(bytesProcessed);
}
BENCHMARK_REGISTER_F(SerializationManagerFixture, SaveAsset)->Name("SerializationManager/SaveAsset")->UseRealTime();
/****************************************************************************************/
BENCHMARK_DEFINE_F(SerializationManagerFixture, SaveAssets)(benchmark::State& state)
{
const auto batchSize = static_cast<std::size_t>(state.range(0));
AssetLibrary library;
AssetContainer<BenchmarkAsset> container;
std::ignore = library.Insert(&container);
SetActiveAssetLibrary(&library);
std::int64_t bytesProcessed = 0;
for (auto _: state)
{
state.PauseTiming();
eastl::vector<UUID> uuids;
uuids.reserve(batchSize);
std::size_t batchBytes = 0;
for (std::size_t i = 0; i < batchSize; ++i)
{
auto* asset = CreateAsset<BenchmarkAsset>();
asset->SetName(asset->GetHeader().uuid.ToString());
asset->GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
for (std::uint32_t j = 0; j < REFS_PER_ROOT; ++j)
{
asset->GetAsset().refs.emplace_back(m_leafUuids[Random::get<std::size_t>(0, m_leafUuids.size() - 1)]);
}
batchBytes += asset->Pack().size();
uuids.push_back(asset->GetHeader().uuid);
}
state.ResumeTiming();
benchmark::DoNotOptimize(SerializationManager::SaveAssets(uuids));
bytesProcessed += static_cast<std::int64_t>(batchBytes);
}
state.SetItemsProcessed(state.iterations() * batchSize);
state.SetBytesProcessed(bytesProcessed);
}
BENCHMARK_REGISTER_F(SerializationManagerFixture, SaveAssets)
->Name("SerializationManager/SaveAssets")
->Arg(1)
->Arg(8)
->Arg(64)
->Arg(512)
->UseRealTime();
#endif
} // namespace Bigfoot
-1
View File
@@ -1 +0,0 @@
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/SasquatchBaker)
@@ -1,11 +0,0 @@
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName}Benchmarks)
bigfoot_create_package_benchmarks(
"Tools")
target_link_libraries(${PROJECT_NAME}
PRIVATE
$<LINK_LIBRARY:WHOLE_ARCHIVE,AssetsForBenchmarking>)
bigfoot_create_bigfile("Benchmarks/Tools")
@@ -1,22 +0,0 @@
// AUTO-GENERATED DO NOT TOUCH
/*********************************************************************
* \file BigFileInfo.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_SASQUATCHBAKERBENCHMARKS_BIGFILEINFO_GENERATED_HPP
#define BIGFOOT_SASQUATCHBAKERBENCHMARKS_BIGFILEINFO_GENERATED_HPP
#include <EASTL/string_view.h>
#if defined BIGFOOT_TOOLMODE
namespace Bigfoot
{
/*
* BigFile location
*/
constexpr eastl::string_view BIGFILE_SASQUATCHBAKERBENCHMARKS_LOCATION {"./SasquatchBakerBenchmarks.db"};
} // namespace Bigfoot
#endif
#endif
@@ -1,87 +0,0 @@
/*********************************************************************
* \file SasquatchBaker.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <SasquatchBaker/SasquatchBaker.hpp>
#include <Engine/BigFile/BigFile.hpp>
#include <Engine/Sasquatch/Sasquatch.hpp>
#include <System/File/File.hpp>
#include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp>
#include <SasquatchBakerBenchmarks/BigFileInfo_generated.hpp>
#include <EASTL/vector.h>
#include <benchmark/benchmark.h>
#include <cstddef>
#include <cstdint>
namespace Bigfoot
{
class SasquatchBakerFixture: public benchmark::Fixture
{
protected:
static constexpr std::uint32_t ASSET_COUNT = 20'000;
static constexpr std::size_t ASSET_PAYLOAD_SIZE = 256;
void SetUp(benchmark::State&) override
{
m_bigFile.Clear();
m_outputFile.Delete();
eastl::vector<UUID> uuids;
eastl::vector<eastl::vector<std::byte>> flatbuffers;
eastl::vector<eastl::vector<UUID>> hardReferences;
uuids.reserve(ASSET_COUNT);
flatbuffers.reserve(ASSET_COUNT);
hardReferences.reserve(ASSET_COUNT);
for (std::uint32_t i = 0; i < ASSET_COUNT; ++i)
{
BenchmarkAsset asset;
asset.SetName(asset.GetHeader().uuid.ToString());
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
const eastl::vector<std::byte> flatbuffer = asset.Pack();
flatbuffers.push_back(flatbuffer);
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
uuids.push_back(asset.GetHeader().uuid);
}
m_bigFile.SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences);
}
void TearDown(benchmark::State&) override
{
m_outputFile.Delete();
}
static constexpr eastl::string_view SASQUATCH_SASQUATCHBAKERBENCHMARKS_LOCATION {
"./SasquatchBakerBenchmarks.sasquatch"};
BigFile m_bigFile {File {BIGFILE_SASQUATCHBAKERBENCHMARKS_LOCATION}};
File m_outputFile {SASQUATCH_SASQUATCHBAKERBENCHMARKS_LOCATION};
};
/****************************************************************************************/
BENCHMARK_DEFINE_F(SasquatchBakerFixture, Bake)(benchmark::State& state)
{
std::int64_t bytesProcessed = 0;
for (auto _: state)
{
Bake(m_bigFile, m_outputFile);
bytesProcessed += static_cast<std::int64_t>(m_outputFile.GetSize());
}
state.SetItemsProcessed(state.iterations() * ASSET_COUNT);
state.SetBytesProcessed(bytesProcessed);
}
BENCHMARK_REGISTER_F(SasquatchBakerFixture, Bake)->Name("SasquatchBaker/Bake")->Unit(benchmark::kMillisecond);
} // namespace Bigfoot
@@ -1,92 +0,0 @@
/*********************************************************************
* \file Graph.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <Utils/Algorithm/Graph.hpp>
#include <ankerl/unordered_dense.h>
#include <benchmark/benchmark.h>
#include <effolkronium/random.hpp>
#include <cstdint>
namespace Bigfoot
{
using Random = effolkronium::random_static;
class LayeredTopologicalSortFixture: public benchmark::Fixture
{
protected:
/*
* Nodes are grouped into layers, and every node in a layer depends on up to DEPENDENCY_MAX_COUNT
* distinct nodes randomly picked from the previous layer.
*/
void SetUp(benchmark::State& state) override
{
Random::seed(0x5EEDU);
const auto nodeCount = static_cast<std::uint32_t>(state.range(0));
m_graph.clear();
m_nodes.clear();
m_graph.reserve(nodeCount);
m_nodes.reserve(nodeCount);
for (std::uint32_t node = 0; node < nodeCount; ++node)
{
m_nodes.insert(node);
eastl::vector<std::uint32_t>& edges = m_graph[node];
const std::uint32_t layerStart = (node / NODE_COUNT_PER_LAYER) * NODE_COUNT_PER_LAYER;
if (layerStart == 0)
{
continue;
}
const std::uint32_t previousLayerStart = layerStart - NODE_COUNT_PER_LAYER;
ankerl::unordered_dense::set<std::uint32_t> picked;
for (std::uint32_t i = 0; i < DEPENDENCY_MAX_COUNT; ++i)
{
const std::uint32_t dependency = Random::get<std::uint32_t>(previousLayerStart, layerStart - 1);
if (picked.insert(dependency).second)
{
edges.push_back(dependency);
}
}
}
}
static constexpr std::uint32_t NODE_COUNT_PER_LAYER = 64;
static constexpr std::uint32_t DEPENDENCY_MAX_COUNT = 4;
ankerl::unordered_dense::map<std::uint32_t, eastl::vector<std::uint32_t>> m_graph;
ankerl::unordered_dense::set<std::uint32_t> m_nodes;
};
/****************************************************************************************/
BENCHMARK_DEFINE_F(LayeredTopologicalSortFixture, LayeredTopologicalSortBench)(benchmark::State& state)
{
const auto nodeCount = static_cast<std::uint32_t>(state.range(0));
for (auto _: state)
{
eastl::vector<eastl::vector<std::uint32_t>> waves;
eastl::vector<std::uint32_t> cyclicNodes;
benchmark::DoNotOptimize(LayeredTopologicalSort(m_graph, m_nodes, waves, cyclicNodes));
benchmark::DoNotOptimize(waves);
benchmark::ClobberMemory();
}
state.SetItemsProcessed(state.iterations() * nodeCount);
}
BENCHMARK_REGISTER_F(LayeredTopologicalSortFixture, LayeredTopologicalSortBench)
->Name("Bigfoot::LayeredTopologicalSort")
->Arg(512)
->Arg(8192)
->Arg(262'144)
->Arg(4'194'304);
} // namespace Bigfoot
@@ -11,7 +11,10 @@
namespace Bigfoot namespace Bigfoot
{ {
namespace
{
using Random = effolkronium::random_static; using Random = effolkronium::random_static;
} // namespace
struct MyComplexStruct struct MyComplexStruct
{ {
+1 -4
View File
@@ -1,6 +1,3 @@
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/System) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/System)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine)
if(${TOOLMODE})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Tools)
endif()
@@ -1,63 +0,0 @@
/*********************************************************************
* \file AssetBase.cpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#include <Engine/Asset/AssetBase.hpp>
#include <Engine/Asset/Reference_generated.hpp>
namespace Bigfoot
{
void AssetBase::HardReferenceVisitor::Field([[maybe_unused]] size_t p_fieldIndex,
[[maybe_unused]] size_t p_setIndex,
const flatbuffers::ElementaryType p_type,
const bool p_isVector,
const flatbuffers::TypeTable* p_typeTable,
[[maybe_unused]] const char* p_name,
const std::uint8_t* p_val)
{
if (!p_isVector)
{
Visit(p_type, p_typeTable, p_val);
}
}
/****************************************************************************************/
void AssetBase::HardReferenceVisitor::Element([[maybe_unused]] size_t p_index,
const flatbuffers::ElementaryType p_type,
const flatbuffers::TypeTable* p_typeTable,
const std::uint8_t* p_val)
{
Visit(p_type, p_typeTable, p_val);
}
/****************************************************************************************/
eastl::vector<UUID> AssetBase::HardReferenceVisitor::GetUUIDs() const
{
eastl::vector<UUID> uuids;
uuids.reserve(m_uuids.size());
std::copy(m_uuids.begin(), m_uuids.end(), eastl::back_inserter(uuids));
return uuids;
}
/****************************************************************************************/
void AssetBase::HardReferenceVisitor::Visit(const flatbuffers::ElementaryType p_type,
const flatbuffers::TypeTable* p_typeTable,
const std::uint8_t* p_val)
{
if (p_val == nullptr || p_type != flatbuffers::ET_SEQUENCE ||
p_typeTable != ::Flat::Bigfoot::HardReference::MiniReflectTypeTable())
{
return;
}
const ::Flat::Bigfoot::HardReference* hardReference = reinterpret_cast<const ::Flat::Bigfoot::HardReference*>(
p_val);
m_uuids.emplace(flatbuffers::UnPack(hardReference->uuid()));
}
} // namespace Bigfoot
@@ -1,188 +0,0 @@
/*********************************************************************
* \file AssetContainer.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <Engine/Asset/AssetContainer.hpp>
namespace Bigfoot
{
ContainerHandle::ContainerHandle(AssetContainerBase* p_assetContainer, const UUID p_uuid):
m_assetContainer(p_assetContainer),
m_uuid(p_uuid)
{
}
/****************************************************************************************/
std::uint32_t ContainerHandle::GetHardRefCount() const
{
return m_hardRefCount;
}
/****************************************************************************************/
void ContainerHandle::IncrementHardRefCount()
{
if (m_hardRefCount == 0)
{
m_assetContainer->CancelRemoval(m_uuid);
}
++m_hardRefCount;
}
/****************************************************************************************/
void ContainerHandle::DecrementHardRefCount()
{
--m_hardRefCount;
if (m_hardRefCount == 0)
{
m_assetContainer->QueueForRemoval(m_uuid);
}
}
/****************************************************************************************/
std::uint32_t ContainerHandle::GetSoftRefCount() const
{
return m_softRefCount;
}
/****************************************************************************************/
void ContainerHandle::IncrementSoftRefCount()
{
++m_softRefCount;
}
/****************************************************************************************/
void ContainerHandle::DecrementSoftRefCount()
{
--m_softRefCount;
}
/****************************************************************************************/
AssetBase* ContainerHandle::GetAsset()
{
return m_asset;
}
/****************************************************************************************/
const AssetBase* ContainerHandle::GetAsset() const
{
return m_asset;
}
/****************************************************************************************/
void ContainerHandle::SetAsset(AssetBase* p_asset)
{
m_asset = p_asset;
}
/****************************************************************************************/
bool AssetContainerBase::Has(const UUID& p_uuid) const
{
const Entry* entry = FindEntry(p_uuid);
return entry != nullptr && entry->m_assetSlotKey.Valid();
}
/****************************************************************************************/
ContainerHandle* AssetContainerBase::AcquireContainerHandle(const UUID& p_uuid)
{
return GetOrCreateEntry(p_uuid).m_handle;
}
/****************************************************************************************/
void AssetContainerBase::Remove(const UUID& p_uuid)
{
if (Entry* entry = FindEntry(p_uuid); entry != nullptr)
{
if (entry->m_assetSlotKey.Valid())
{
entry->m_handle->SetAsset(nullptr);
RemoveAsset(entry->m_assetSlotKey);
entry->m_assetSlotKey = SlotMapKey {};
}
m_handles.Remove(entry->m_handleSlotKey);
m_uuidToEntry.erase(p_uuid);
}
}
/****************************************************************************************/
void AssetContainerBase::QueueForRemoval(const UUID& p_uuid)
{
m_pendingRemovalUuids.push_back(p_uuid);
}
/****************************************************************************************/
void AssetContainerBase::CancelRemoval(const UUID& p_uuid)
{
auto* const pendingIt = eastl::find(m_pendingRemovalUuids.begin(), m_pendingRemovalUuids.end(), p_uuid);
if (pendingIt != m_pendingRemovalUuids.end())
{
m_pendingRemovalUuids.erase_unsorted(pendingIt);
}
}
/****************************************************************************************/
void AssetContainerBase::ProcessPendingRemovals()
{
eastl::vector<UUID> toRemove;
toRemove.swap(m_pendingRemovalUuids);
for (const UUID& uuid: toRemove)
{
Remove(uuid);
}
}
/****************************************************************************************/
bool AssetContainerBase::IsMarkedForRemove(const UUID& p_uuid)
{
return eastl::find(m_pendingRemovalUuids.begin(), m_pendingRemovalUuids.end(), p_uuid) !=
m_pendingRemovalUuids.end();
}
/****************************************************************************************/
AssetContainerBase::Entry* AssetContainerBase::FindEntry(const UUID& p_uuid)
{
const auto entryIt = m_uuidToEntry.find(p_uuid);
return entryIt != m_uuidToEntry.end() ? &entryIt->second : nullptr;
}
/****************************************************************************************/
const AssetContainerBase::Entry* AssetContainerBase::FindEntry(const UUID& p_uuid) const
{
const auto entryIt = m_uuidToEntry.find(p_uuid);
return entryIt != m_uuidToEntry.end() ? &entryIt->second : nullptr;
}
/****************************************************************************************/
AssetContainerBase::Entry& AssetContainerBase::GetOrCreateEntry(const UUID& p_uuid)
{
auto [entryIt, inserted] = m_uuidToEntry.try_emplace(p_uuid);
if (inserted)
{
entryIt->second.m_handleSlotKey = m_handles.Insert(this, p_uuid);
entryIt->second.m_handle = m_handles.Get(entryIt->second.m_handleSlotKey);
}
return entryIt->second;
}
} // namespace Bigfoot
@@ -8,77 +8,6 @@
namespace Bigfoot namespace Bigfoot
{ {
AssetContainerBase* AssetLibrary::GetAssetContainer(const AssetTypeID p_typeID)
{
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
{
return container->second;
}
return nullptr;
}
/****************************************************************************************/
const AssetContainerBase* AssetLibrary::GetAssetContainer(const AssetTypeID p_typeID) const
{
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
{
return container->second;
}
return nullptr;
}
/****************************************************************************************/
const AssetContainerBase* AssetLibrary::GetAssetContainer(const UUID& p_uuid) const
{
for (const auto [typeId, container]: m_assetContainers)
{
if (container->Has(p_uuid))
{
return container;
}
}
return nullptr;
}
/****************************************************************************************/
AssetContainerBase* AssetLibrary::GetAssetContainer(const UUID& p_uuid)
{
for (const auto [typeId, container]: m_assetContainers)
{
if (container->Has(p_uuid))
{
return container;
}
}
return nullptr;
}
/****************************************************************************************/
bool AssetLibrary::IsLoaded(const UUID& p_uuid) const
{
return GetAssetContainer(p_uuid) != nullptr;
}
/****************************************************************************************/
void AssetLibrary::ProcessPendingRemovals()
{
for (const auto [typeId, container]: m_assetContainers)
{
container->ProcessPendingRemovals();
}
}
/****************************************************************************************/
void SetActiveAssetLibrary(AssetLibrary* p_assetLibrary) void SetActiveAssetLibrary(AssetLibrary* p_assetLibrary)
{ {
g_activeAssetLibrary = p_assetLibrary; g_activeAssetLibrary = p_assetLibrary;
+169 -413
View File
@@ -8,9 +8,9 @@
#include <Engine/EngineAssertHandler.hpp> #include <Engine/EngineAssertHandler.hpp>
#include <Utils/Format.hpp>
#include <EASTL/algorithm.h> #include <EASTL/algorithm.h>
#include <EASTL/sort.h>
#include <fmt/format.h>
namespace Bigfoot namespace Bigfoot
{ {
@@ -69,19 +69,6 @@ void BigFile::RollbackTransaction()
/****************************************************************************************/ /****************************************************************************************/
void BigFile::Clear()
{
BeginTransaction();
BigFile::Request {*this, "DELETE FROM AssetHardReference;"}.Execute();
BigFile::Request {*this, "DELETE FROM Asset;"}.Execute();
BigFile::Request {*this, "DELETE FROM AssetMetadata;"}.Execute();
CommitTransaction();
}
/****************************************************************************************/
BigFile::~BigFile() BigFile::~BigFile()
{ {
[[maybe_unused]] [[maybe_unused]]
@@ -91,14 +78,14 @@ BigFile::~BigFile()
/****************************************************************************************/ /****************************************************************************************/
eastl::vector<std::byte> BigFile::GetAssetFlatbuffer(const UUID& p_uuid) const eastl::optional<eastl::vector<std::byte>> BigFile::GetAssetFlatbuffer(const UUID& p_uuid) const
{ {
BigFile::Request assetRequest {*this, "SELECT Asset FROM Asset WHERE UUID = ?1;"}; BigFile::Request assetRequest {*this, "SELECT Asset FROM Asset WHERE UUID = ?1;"};
assetRequest.Bind(1, p_uuid.ToBytes()); assetRequest.Bind(1, p_uuid.ToBytes());
if (!assetRequest.Step()) if (!assetRequest.Step())
{ {
return {}; return eastl::nullopt;
} }
const eastl::span<const std::byte> flatbuffer = assetRequest.Get(0); const eastl::span<const std::byte> flatbuffer = assetRequest.Get(0);
@@ -109,74 +96,58 @@ eastl::vector<std::byte> BigFile::GetAssetFlatbuffer(const UUID& p_uuid) const
eastl::vector<eastl::vector<std::byte>> BigFile::GetAssetFlatbuffers(const eastl::span<const UUID> p_uuids) const eastl::vector<eastl::vector<std::byte>> BigFile::GetAssetFlatbuffers(const eastl::span<const UUID> p_uuids) const
{ {
eastl::vector<eastl::vector<std::byte>> flatbuffers(p_uuids.size()); eastl::vector<eastl::vector<std::byte>> flatbuffers;
if (p_uuids.empty()) if (p_uuids.empty())
{ {
return flatbuffers; return flatbuffers;
} }
ankerl::unordered_dense::map<UUID, eastl::vector<std::size_t>> uuidToIndices; flatbuffers.reserve(p_uuids.size());
uuidToIndices.reserve(p_uuids.size());
for (std::size_t i = 0; i < p_uuids.size(); ++i) if (p_uuids.size() == 1)
{ {
uuidToIndices[p_uuids[i]].push_back(i); if (eastl::optional<eastl::vector<std::byte>> flatbuffer = GetAssetFlatbuffer(p_uuids[0]);
flatbuffer.has_value())
{
flatbuffers.push_back(std::move(*flatbuffer));
}
return flatbuffers;
} }
eastl::vector<UUID> distinctUUIDs; eastl::vector<UUID> uniqueUUIDs {p_uuids.begin(), p_uuids.end()};
distinctUUIDs.reserve(uuidToIndices.size()); eastl::sort(uniqueUUIDs.begin(), uniqueUUIDs.end());
for (const auto& [uuid, indices]: uuidToIndices) uniqueUUIDs.erase(eastl::unique(uniqueUUIDs.begin(), uniqueUUIDs.end()), uniqueUUIDs.end());
eastl::string placeholders;
placeholders.reserve(uniqueUUIDs.size() * 3);
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
{ {
distinctUUIDs.push_back(uuid); if (i > 0)
{
placeholders += ", ";
}
placeholders += "?";
} }
constexpr std::size_t PARAMS_PER_ROW = 1; const std::string sqlRequest = fmt::format("SELECT Asset FROM Asset WHERE UUID IN ({});", placeholders);
const std::size_t maxRowsPerStatement = static_cast<std::size_t>(
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
PARAMS_PER_ROW;
for (std::size_t chunkStart = 0; chunkStart < distinctUUIDs.size(); chunkStart += maxRowsPerStatement) BigFile::Request assetRequest {*this, sqlRequest.c_str()};
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
{ {
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, distinctUUIDs.size() - chunkStart); assetRequest.Bind(static_cast<std::uint32_t>(i + 1), uniqueUUIDs[i].ToBytes());
}
eastl::string placeholders; flatbuffers.reserve(uniqueUUIDs.size());
placeholders.reserve(chunkSize * 2); for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
for (std::size_t i = 0; i < chunkSize; ++i) {
if (!assetRequest.Step())
{ {
if (i > 0) break;
{
placeholders += ", ";
}
placeholders += "?";
} }
const eastl::string sql = Format("SELECT UUID, Asset FROM Asset WHERE UUID IN ({});", placeholders); const eastl::span<const std::byte> flatbuffer = assetRequest.Get(0);
flatbuffers.emplace_back(flatbuffer.begin(), flatbuffer.end());
BigFile::Request assetRequest {*this, sql};
for (std::size_t i = 0; i < chunkSize; ++i)
{
assetRequest.Bind(static_cast<std::uint32_t>(i + 1), distinctUUIDs[chunkStart + i].ToBytes());
}
while (assetRequest.Step())
{
const std::span<const std::byte, UUID::UUID_BYTE_SIZE> rawUUID {
static_cast<std::span<const std::byte>>(assetRequest.Get(0))};
const UUID uuid {rawUUID};
const auto indicesIt = uuidToIndices.find(uuid);
ASSERT(EngineAssertHandler,
indicesIt != uuidToIndices.end(),
"Returned UUID {} not found in requested UUIDs",
uuid);
const eastl::span<const std::byte> flatbuffer = assetRequest.Get(1);
for (const std::size_t index: indicesIt->second)
{
flatbuffers[index].assign(flatbuffer.begin(), flatbuffer.end());
}
}
} }
return flatbuffers; return flatbuffers;
@@ -184,271 +155,133 @@ eastl::vector<eastl::vector<std::byte>> BigFile::GetAssetFlatbuffers(const eastl
/****************************************************************************************/ /****************************************************************************************/
eastl::vector<UUID> BigFile::GetAssetHardReferences(const UUID& p_uuid) const eastl::optional<AssetMetadata> BigFile::GetAssetMetadata(const UUID& p_uuid) const
{ {
BigFile::Request hardReferencesRequest {*this, "SELECT HardReference FROM AssetHardReference WHERE UUID = ?1;"}; BigFile::Request assetRequest {
hardReferencesRequest.Bind(1, p_uuid.ToBytes()); *this,
"SELECT UUID, Name, TypeID, TypeName, CreateTime, ModificationTime FROM AssetMetadata WHERE UUID = ?1;"};
assetRequest.Bind(1, p_uuid.ToBytes());
eastl::vector<UUID> hardReferences; if (!assetRequest.Step())
while (hardReferencesRequest.Step())
{
const std::span<const std::byte, UUID::UUID_BYTE_SIZE> rawUUID {
static_cast<std::span<const std::byte>>(hardReferencesRequest.Get(0))};
hardReferences.emplace_back(rawUUID);
}
return hardReferences;
}
/****************************************************************************************/
eastl::vector<eastl::vector<UUID>> BigFile::GetAssetsHardReferences(eastl::span<const UUID> p_uuids) const
{
eastl::vector<eastl::vector<UUID>> hardReferences(p_uuids.size());
if (p_uuids.empty())
{
return hardReferences;
}
ankerl::unordered_dense::map<UUID, eastl::vector<std::size_t>> uuidToIndices;
uuidToIndices.reserve(p_uuids.size());
for (std::size_t i = 0; i < p_uuids.size(); ++i)
{
uuidToIndices[p_uuids[i]].push_back(i);
}
eastl::vector<UUID> distinctUUIDs;
distinctUUIDs.reserve(uuidToIndices.size());
for (const auto& [uuid, indices]: uuidToIndices)
{
distinctUUIDs.push_back(uuid);
}
constexpr std::size_t PARAMS_PER_ROW = 1;
const std::size_t maxRowsPerStatement = static_cast<std::size_t>(
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
PARAMS_PER_ROW;
for (std::size_t chunkStart = 0; chunkStart < distinctUUIDs.size(); chunkStart += maxRowsPerStatement)
{
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, distinctUUIDs.size() - chunkStart);
eastl::string placeholders;
placeholders.reserve(chunkSize * 2);
for (std::size_t i = 0; i < chunkSize; ++i)
{
if (i > 0)
{
placeholders += ", ";
}
placeholders += "?";
}
const eastl::string sql = Format("SELECT UUID, HardReference FROM AssetHardReference WHERE UUID IN ({});",
placeholders);
BigFile::Request hardReferencesRequest {*this, sql};
for (std::size_t i = 0; i < chunkSize; ++i)
{
hardReferencesRequest.Bind(static_cast<std::uint32_t>(i + 1), distinctUUIDs[chunkStart + i].ToBytes());
}
while (hardReferencesRequest.Step())
{
const std::span<const std::byte, UUID::UUID_BYTE_SIZE> rawOwnerUUID {
static_cast<std::span<const std::byte>>(hardReferencesRequest.Get(0))};
const UUID ownerUUID {rawOwnerUUID};
const auto indicesIt = uuidToIndices.find(ownerUUID);
ASSERT(EngineAssertHandler,
indicesIt != uuidToIndices.end(),
"Returned UUID {} not found in requested UUIDs",
ownerUUID);
const std::span<const std::byte, UUID::UUID_BYTE_SIZE> rawHardReference {
static_cast<std::span<const std::byte>>(hardReferencesRequest.Get(1))};
for (const std::size_t index: indicesIt->second)
{
hardReferences[index].emplace_back(rawHardReference);
}
}
}
return hardReferences;
}
/****************************************************************************************/
eastl::optional<BigFile::AssetTime> BigFile::GetAssetTime(const UUID& p_uuid) const
{
BigFile::Request timeRequest {*this, "SELECT CreateTime, ModificationTime FROM AssetMetadata WHERE UUID = ?1;"};
timeRequest.Bind(1, p_uuid.ToBytes());
if (!timeRequest.Step())
{ {
return eastl::nullopt; return eastl::nullopt;
} }
return AssetTime {.m_creationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(0))}, return AssetMetadata {.m_uuid = UUID {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {
.m_modificationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(1))}}; static_cast<eastl::span<const std::byte>>(assetRequest.Get(0)).data(),
UUID::UUID_BYTE_SIZE}},
.m_name = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(1))},
.m_typeID = assetRequest.Get(2),
.m_typeName = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(3))},
.m_creationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(4))},
.m_modificationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(5))}};
} }
/****************************************************************************************/ /****************************************************************************************/
eastl::vector<eastl::optional<BigFile::AssetTime>> BigFile::GetAssetsTime(const eastl::span<const UUID> p_uuids) const eastl::vector<AssetMetadata> BigFile::GetAssetMetadatas(const eastl::span<const UUID> p_uuids) const
{ {
eastl::vector<eastl::optional<AssetTime>> times(p_uuids.size()); eastl::vector<AssetMetadata> metadatas;
if (p_uuids.empty()) if (p_uuids.empty())
{ {
return times; return metadatas;
} }
ankerl::unordered_dense::map<UUID, eastl::vector<std::size_t>> uuidToIndices; metadatas.reserve(p_uuids.size());
uuidToIndices.reserve(p_uuids.size());
for (std::size_t i = 0; i < p_uuids.size(); ++i) if (p_uuids.size() == 1)
{ {
uuidToIndices[p_uuids[i]].push_back(i); if (eastl::optional<AssetMetadata> metadata = GetAssetMetadata(p_uuids[0]); metadata.has_value())
}
eastl::vector<UUID> distinctUUIDs;
distinctUUIDs.reserve(uuidToIndices.size());
for (const auto& [uuid, indices]: uuidToIndices)
{
distinctUUIDs.push_back(uuid);
}
constexpr std::size_t PARAMS_PER_ROW = 1;
const std::size_t maxRowsPerStatement = static_cast<std::size_t>(
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
PARAMS_PER_ROW;
for (std::size_t chunkStart = 0; chunkStart < distinctUUIDs.size(); chunkStart += maxRowsPerStatement)
{
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, distinctUUIDs.size() - chunkStart);
eastl::string placeholders;
placeholders.reserve(chunkSize * 2);
for (std::size_t i = 0; i < chunkSize; ++i)
{ {
if (i > 0) metadatas.push_back(std::move(*metadata));
{
placeholders += ", ";
}
placeholders += "?";
} }
const eastl::string sql = Format( return metadatas;
"SELECT UUID, CreateTime, ModificationTime FROM AssetMetadata WHERE UUID IN ({});",
placeholders);
BigFile::Request timeRequest {*this, sql};
for (std::size_t i = 0; i < chunkSize; ++i)
{
timeRequest.Bind(static_cast<std::uint32_t>(i + 1), distinctUUIDs[chunkStart + i].ToBytes());
}
while (timeRequest.Step())
{
const std::span<const std::byte, UUID::UUID_BYTE_SIZE> rawUUID {
static_cast<std::span<const std::byte>>(timeRequest.Get(0))};
const UUID uuid {rawUUID};
const auto indicesIt = uuidToIndices.find(uuid);
ASSERT(EngineAssertHandler,
indicesIt != uuidToIndices.end(),
"Returned UUID {} not found in requested UUIDs",
uuid);
const AssetTime assetTime {.m_creationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(1))},
.m_modificationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(2))}};
for (const std::size_t index: indicesIt->second)
{
times[index] = assetTime;
}
}
} }
return times; eastl::vector<UUID> uniqueUUIDs {p_uuids.begin(), p_uuids.end()};
eastl::sort(uniqueUUIDs.begin(), uniqueUUIDs.end());
uniqueUUIDs.erase(eastl::unique(uniqueUUIDs.begin(), uniqueUUIDs.end()), uniqueUUIDs.end());
eastl::string placeholders;
placeholders.reserve(uniqueUUIDs.size() * 3);
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
{
if (i > 0)
{
placeholders += ", ";
}
placeholders += "?";
}
const std::string sqlRequest = fmt::format("SELECT UUID, Name, TypeID, TypeName, CreateTime, ModificationTime "
"FROM AssetMetadata WHERE UUID IN ({});",
placeholders);
BigFile::Request assetRequest {*this, sqlRequest.c_str()};
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
{
assetRequest.Bind(static_cast<std::uint32_t>(i + 1), uniqueUUIDs[i].ToBytes());
}
metadatas.reserve(uniqueUUIDs.size());
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
{
if (!assetRequest.Step())
{
break;
}
metadatas.push_back(
AssetMetadata {.m_uuid = UUID {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {
static_cast<eastl::span<const std::byte>>(assetRequest.Get(0)).data(),
UUID::UUID_BYTE_SIZE}},
.m_name = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(1))},
.m_typeID = assetRequest.Get(2),
.m_typeName = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(3))},
.m_creationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(4))},
.m_modificationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(5))}});
}
return metadatas;
} }
/****************************************************************************************/ /****************************************************************************************/
void BigFile::SaveAssetFlatbuffer(const UUID& p_uuid, void BigFile::SaveAssetFlatbuffer(const AssetMetadata& p_metadata, const eastl::span<const std::byte> p_flatbuffer)
const eastl::span<const std::byte> p_flatbuffer,
const eastl::span<const UUID> p_hardReferences)
{ {
BeginTransaction(); BeginTransaction();
BigFile::Request metadataRequest {*this, BigFile::Request metadataRequest {
"INSERT INTO AssetMetadata (UUID) VALUES (?1) " *this,
"ON CONFLICT(UUID) DO NOTHING;"}; "INSERT INTO AssetMetadata (UUID, Name, TypeID, TypeName) VALUES (?1, ?2, ?3, ?4) "
metadataRequest.Bind(1, p_uuid.ToBytes()); "ON CONFLICT(UUID) DO UPDATE SET Name = excluded.Name, TypeID = excluded.TypeID, TypeName = excluded.TypeName;"};
metadataRequest.Bind(1, p_metadata.m_uuid.ToBytes());
metadataRequest.Bind(2, p_metadata.m_name);
metadataRequest.Bind(3, p_metadata.m_typeID);
metadataRequest.Bind(4, p_metadata.m_typeName);
metadataRequest.Execute(); metadataRequest.Execute();
BigFile::Request assetRequest {*this, BigFile::Request assetRequest {*this,
"INSERT INTO Asset (UUID, Asset) VALUES (?1, ?2) " "INSERT INTO Asset (UUID, Asset) VALUES (?1, ?2) "
"ON CONFLICT(UUID) DO UPDATE SET Asset = excluded.Asset;"}; "ON CONFLICT(UUID) DO UPDATE SET Asset = excluded.Asset;"};
assetRequest.Bind(1, p_uuid.ToBytes()); assetRequest.Bind(1, p_metadata.m_uuid.ToBytes());
assetRequest.Bind(2, p_flatbuffer); assetRequest.Bind(2, p_flatbuffer);
assetRequest.Execute(); assetRequest.Execute();
BigFile::Request deleteHardReferencesRequest {*this, "DELETE FROM AssetHardReference WHERE UUID = ?1;"};
deleteHardReferencesRequest.Bind(1, p_uuid.ToBytes());
deleteHardReferencesRequest.Execute();
constexpr std::size_t HARDREF_PARAMS_PER_ROW = 2;
constexpr std::size_t HARDREF_PLACEHOLDER_RESERVE_CHARS_PER_ROW = 8;
const std::size_t maxHardRefRowsPerStatement = static_cast<std::size_t>(
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
HARDREF_PARAMS_PER_ROW;
for (std::size_t chunkStart = 0; chunkStart < p_hardReferences.size(); chunkStart += maxHardRefRowsPerStatement)
{
const std::size_t chunkSize = eastl::min(maxHardRefRowsPerStatement, p_hardReferences.size() - chunkStart);
eastl::string hardReferencePlaceholders;
hardReferencePlaceholders.reserve(chunkSize * HARDREF_PLACEHOLDER_RESERVE_CHARS_PER_ROW);
for (std::size_t i = 0; i < chunkSize; ++i)
{
if (i > 0)
{
hardReferencePlaceholders += ", ";
}
hardReferencePlaceholders += "(?, ?)";
}
const eastl::string hardReferenceSQL = Format("INSERT INTO AssetHardReference (UUID, HardReference) VALUES {} "
"ON CONFLICT(UUID, HardReference) DO NOTHING;",
hardReferencePlaceholders);
BigFile::Request hardReferenceRequest {*this, hardReferenceSQL};
std::uint32_t bindIndex = 1;
for (std::size_t i = 0; i < chunkSize; ++i)
{
hardReferenceRequest.Bind(bindIndex++, p_uuid.ToBytes());
hardReferenceRequest.Bind(bindIndex++, p_hardReferences[chunkStart + i].ToBytes());
}
hardReferenceRequest.Execute();
}
CommitTransaction(); CommitTransaction();
} }
/****************************************************************************************/ /****************************************************************************************/
void BigFile::SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids, void BigFile::SaveAssetFlatbuffers(const eastl::span<const AssetMetadata> p_metadatas,
const eastl::span<const eastl::vector<std::byte>> p_flatbuffers, const eastl::span<const eastl::vector<std::byte>> p_flatbuffers)
const eastl::span<const eastl::vector<UUID>> p_hardReferences)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
p_uuids.size() == p_flatbuffers.size() && p_uuids.size() == p_hardReferences.size(), p_metadatas.size() == p_flatbuffers.size(),
"p_metadatas and p_flatbuffers and p_hardReferences must have the same size"); "p_metadatas and p_flatbuffers must have the same size");
if (p_uuids.empty()) if (p_metadatas.empty())
{ {
return; return;
} }
@@ -456,41 +289,45 @@ void BigFile::SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids,
BeginTransaction(); BeginTransaction();
constexpr std::size_t METADATA_PARAMS_PER_ROW = 4; constexpr std::size_t METADATA_PARAMS_PER_ROW = 4;
constexpr std::size_t METADATA_PLACEHOLDER_RESERVE_CHARS_PER_ROW = 14;
constexpr std::size_t ASSET_PLACEHOLDER_RESERVE_CHARS_PER_ROW = 8;
const std::size_t maxRowsPerStatement = static_cast<std::size_t>( const std::size_t maxRowsPerStatement = static_cast<std::size_t>(
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) / sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
METADATA_PARAMS_PER_ROW; METADATA_PARAMS_PER_ROW;
for (std::size_t chunkStart = 0; chunkStart < p_uuids.size(); chunkStart += maxRowsPerStatement) for (std::size_t chunkStart = 0; chunkStart < p_metadatas.size(); chunkStart += maxRowsPerStatement)
{ {
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, p_uuids.size() - chunkStart); const std::size_t chunkSize = eastl::min(maxRowsPerStatement, p_metadatas.size() - chunkStart);
eastl::string metadataPlaceholders; eastl::string metadataPlaceholders;
metadataPlaceholders.reserve(chunkSize * METADATA_PLACEHOLDER_RESERVE_CHARS_PER_ROW); metadataPlaceholders.reserve(chunkSize * 14);
for (std::size_t i = 0; i < chunkSize; ++i) for (std::size_t i = 0; i < chunkSize; ++i)
{ {
if (i > 0) if (i > 0)
{ {
metadataPlaceholders += ", "; metadataPlaceholders += ", ";
} }
metadataPlaceholders += "(?)"; metadataPlaceholders += "(?, ?, ?, ?)";
} }
const eastl::string metadataSQL = Format( const std::string metadataSQL = fmt::format(
"INSERT INTO AssetMetadata (UUID) VALUES {} ON CONFLICT(UUID) DO NOTHING;", "INSERT INTO AssetMetadata (UUID, Name, TypeID, TypeName) VALUES {} "
"ON CONFLICT(UUID) DO UPDATE SET Name = excluded.Name, TypeID = excluded.TypeID, TypeName = "
"excluded.TypeName;",
metadataPlaceholders); metadataPlaceholders);
BigFile::Request metadataRequest {*this, metadataSQL}; BigFile::Request metadataRequest {*this, metadataSQL.c_str()};
std::uint32_t metadataBindIndex = 1; std::uint32_t metadataBindIndex = 1;
for (std::size_t i = 0; i < chunkSize; ++i) for (std::size_t i = 0; i < chunkSize; ++i)
{ {
metadataRequest.Bind(metadataBindIndex++, p_uuids[chunkStart + i].ToBytes()); const AssetMetadata& metadata = p_metadatas[chunkStart + i];
metadataRequest.Bind(metadataBindIndex++, metadata.m_uuid.ToBytes());
metadataRequest.Bind(metadataBindIndex++, metadata.m_name);
metadataRequest.Bind(metadataBindIndex++, metadata.m_typeID);
metadataRequest.Bind(metadataBindIndex++, metadata.m_typeName);
} }
metadataRequest.Execute(); metadataRequest.Execute();
eastl::string assetPlaceholders; eastl::string assetPlaceholders;
assetPlaceholders.reserve(chunkSize * ASSET_PLACEHOLDER_RESERVE_CHARS_PER_ROW); assetPlaceholders.reserve(chunkSize * 8);
for (std::size_t i = 0; i < chunkSize; ++i) for (std::size_t i = 0; i < chunkSize; ++i)
{ {
if (i > 0) if (i > 0)
@@ -500,88 +337,18 @@ void BigFile::SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids,
assetPlaceholders += "(?, ?)"; assetPlaceholders += "(?, ?)";
} }
const eastl::string assetSQL = Format( const std::string assetSQL = fmt::format(
"INSERT INTO Asset (UUID, Asset) VALUES {} ON CONFLICT(UUID) DO UPDATE SET Asset = excluded.Asset;", "INSERT INTO Asset (UUID, Asset) VALUES {} ON CONFLICT(UUID) DO UPDATE SET Asset = excluded.Asset;",
assetPlaceholders); assetPlaceholders);
BigFile::Request assetRequest {*this, assetSQL}; BigFile::Request assetRequest {*this, assetSQL.c_str()};
std::uint32_t assetBindIndex = 1; std::uint32_t assetBindIndex = 1;
for (std::size_t i = 0; i < chunkSize; ++i) for (std::size_t i = 0; i < chunkSize; ++i)
{ {
assetRequest.Bind(assetBindIndex++, p_uuids[chunkStart + i].ToBytes()); assetRequest.Bind(assetBindIndex++, p_metadatas[chunkStart + i].m_uuid.ToBytes());
assetRequest.Bind(assetBindIndex++, p_flatbuffers[chunkStart + i]); assetRequest.Bind(assetBindIndex++, p_flatbuffers[chunkStart + i]);
} }
assetRequest.Execute(); assetRequest.Execute();
// Replace hard references for every asset in this chunk with its current set.
eastl::string deleteInPlaceholders;
deleteInPlaceholders.reserve(chunkSize * 3);
for (std::size_t i = 0; i < chunkSize; ++i)
{
if (i > 0)
{
deleteInPlaceholders += ", ";
}
deleteInPlaceholders += "?";
}
const eastl::string deleteHardReferencesSQL = Format("DELETE FROM AssetHardReference WHERE UUID IN ({});",
deleteInPlaceholders);
BigFile::Request deleteHardReferencesRequest {*this, deleteHardReferencesSQL};
for (std::size_t i = 0; i < chunkSize; ++i)
{
deleteHardReferencesRequest.Bind(static_cast<std::uint32_t>(i + 1), p_uuids[chunkStart + i].ToBytes());
}
deleteHardReferencesRequest.Execute();
eastl::vector<eastl::pair<UUID, UUID>> hardReferencePairs;
for (std::size_t i = 0; i < chunkSize; ++i)
{
for (const UUID& hardReference: p_hardReferences[chunkStart + i])
{
hardReferencePairs.emplace_back(p_uuids[chunkStart + i], hardReference);
}
}
constexpr std::size_t HARDREF_PARAMS_PER_ROW = 2;
constexpr std::size_t HARDREF_PLACEHOLDER_RESERVE_CHARS_PER_ROW = 8;
const std::size_t maxHardRefRowsPerStatement = static_cast<std::size_t>(
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
HARDREF_PARAMS_PER_ROW;
for (std::size_t hardRefChunkStart = 0; hardRefChunkStart < hardReferencePairs.size();
hardRefChunkStart += maxHardRefRowsPerStatement)
{
const std::size_t hardRefChunkSize = eastl::min(maxHardRefRowsPerStatement,
hardReferencePairs.size() - hardRefChunkStart);
eastl::string hardReferencePlaceholders;
hardReferencePlaceholders.reserve(hardRefChunkSize * HARDREF_PLACEHOLDER_RESERVE_CHARS_PER_ROW);
for (std::size_t i = 0; i < hardRefChunkSize; ++i)
{
if (i > 0)
{
hardReferencePlaceholders += ", ";
}
hardReferencePlaceholders += "(?, ?)";
}
const eastl::string hardReferenceSQL = Format(
"INSERT INTO AssetHardReference (UUID, HardReference) VALUES {} "
"ON CONFLICT(UUID, HardReference) DO NOTHING;",
hardReferencePlaceholders);
BigFile::Request hardReferenceRequest {*this, hardReferenceSQL};
std::uint32_t bindIndex = 1;
for (std::size_t i = 0; i < hardRefChunkSize; ++i)
{
const auto& [assetUUID, hardReference] = hardReferencePairs[hardRefChunkStart + i];
hardReferenceRequest.Bind(bindIndex++, assetUUID.ToBytes());
hardReferenceRequest.Bind(bindIndex++, hardReference.ToBytes());
}
hardReferenceRequest.Execute();
}
} }
CommitTransaction(); CommitTransaction();
@@ -605,7 +372,7 @@ BigFile::Request::Request(const BigFile& p_bigFile, const eastl::string_view p_r
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_prepare_v2(m_db, const int result = sqlite3_prepare_v2(m_db,
p_request.data(), p_request.data(),
static_cast<int>(p_request.size()), static_cast<std::uint32_t>(p_request.size()),
&m_statement, &m_statement,
nullptr); nullptr);
CRITICAL_ASSERT(EngineAssertHandler, CRITICAL_ASSERT(EngineAssertHandler,
@@ -619,11 +386,11 @@ BigFile::Request::Request(const BigFile& p_bigFile, const eastl::string_view p_r
void BigFile::Request::Bind(const std::uint32_t p_index, const std::int32_t p_value) void BigFile::Request::Bind(const std::uint32_t p_index, const std::int32_t p_value)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_int(m_statement, static_cast<int>(p_index), p_value); const int result = sqlite3_bind_int(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -632,11 +399,11 @@ void BigFile::Request::Bind(const std::uint32_t p_index, const std::int32_t p_va
void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint32_t p_value) void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint32_t p_value)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_int(m_statement, static_cast<int>(p_index), static_cast<int>(p_value)); const int result = sqlite3_bind_int(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -645,11 +412,11 @@ void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint32_t p_v
void BigFile::Request::Bind(const std::uint32_t p_index, const std::int64_t p_value) void BigFile::Request::Bind(const std::uint32_t p_index, const std::int64_t p_value)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_int64(m_statement, static_cast<int>(p_index), p_value); const int result = sqlite3_bind_int64(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -658,11 +425,11 @@ void BigFile::Request::Bind(const std::uint32_t p_index, const std::int64_t p_va
void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint64_t p_value) void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint64_t p_value)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_int64(m_statement, static_cast<int>(p_index), std::bit_cast<std::int64_t>(p_value)); const int result = sqlite3_bind_int64(m_statement, p_index, std::bit_cast<std::int64_t>(p_value));
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -671,11 +438,11 @@ void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint64_t p_v
void BigFile::Request::Bind(const std::uint32_t p_index, const float p_value) void BigFile::Request::Bind(const std::uint32_t p_index, const float p_value)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_double(m_statement, static_cast<int>(p_index), p_value); const int result = sqlite3_bind_double(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -684,11 +451,11 @@ void BigFile::Request::Bind(const std::uint32_t p_index, const float p_value)
void BigFile::Request::Bind(const std::uint32_t p_index, const double p_value) void BigFile::Request::Bind(const std::uint32_t p_index, const double p_value)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_double(m_statement, static_cast<int>(p_index), p_value); const int result = sqlite3_bind_double(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -697,14 +464,14 @@ void BigFile::Request::Bind(const std::uint32_t p_index, const double p_value)
void BigFile::Request::Bind(const std::uint32_t p_index, const eastl::string_view p_value, const CopyValue p_copy) void BigFile::Request::Bind(const std::uint32_t p_index, const eastl::string_view p_value, const CopyValue p_copy)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_text(m_statement, const int result = sqlite3_bind_text(m_statement,
static_cast<int>(p_index), p_index,
p_value.data(), p_value.data(),
static_cast<int>(p_value.size()), static_cast<std::uint32_t>(p_value.size()),
p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC); p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -716,14 +483,14 @@ void BigFile::Request::Bind(const std::uint32_t p_index,
const CopyValue p_copy) const CopyValue p_copy)
{ {
ASSERT(EngineAssertHandler, ASSERT(EngineAssertHandler,
(p_index >= 1U) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))), (p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement"); "Invalid index for statement");
[[maybe_unused]] [[maybe_unused]]
const int result = sqlite3_bind_blob(m_statement, const int result = sqlite3_bind_blob(m_statement,
static_cast<int>(p_index), p_index,
p_value.data(), p_value.data(),
static_cast<int>(p_value.size()), static_cast<std::uint32_t>(p_value.size()),
p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC); p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db)); ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
} }
@@ -764,69 +531,58 @@ BigFile::Request::Column::Column(const Request& p_request, const std::uint32_t p
BigFile::Request::Column::operator std::int32_t() const BigFile::Request::Column::operator std::int32_t() const
{ {
return sqlite3_column_int(m_statement, static_cast<int>(m_index)); return sqlite3_column_int(m_statement, m_index);
} }
/****************************************************************************************/ /****************************************************************************************/
BigFile::Request::Column::operator std::uint32_t() const BigFile::Request::Column::operator std::uint32_t() const
{ {
return sqlite3_column_int(m_statement, static_cast<int>(m_index)); return sqlite3_column_int(m_statement, m_index);
} }
/****************************************************************************************/ /****************************************************************************************/
BigFile::Request::Column::operator std::int64_t() const BigFile::Request::Column::operator std::int64_t() const
{ {
return sqlite3_column_int64(m_statement, static_cast<int>(m_index)); return sqlite3_column_int64(m_statement, m_index);
} }
/****************************************************************************************/ /****************************************************************************************/
BigFile::Request::Column::operator std::uint64_t() const BigFile::Request::Column::operator std::uint64_t() const
{ {
return std::bit_cast<std::uint64_t>(sqlite3_column_int64(m_statement, static_cast<int>(m_index))); return std::bit_cast<std::uint64_t>(sqlite3_column_int64(m_statement, m_index));
} }
/****************************************************************************************/ /****************************************************************************************/
BigFile::Request::Column::operator float() const BigFile::Request::Column::operator float() const
{ {
return static_cast<float>(sqlite3_column_double(m_statement, static_cast<int>(m_index))); return static_cast<float>(sqlite3_column_double(m_statement, m_index));
} }
/****************************************************************************************/ /****************************************************************************************/
BigFile::Request::Column::operator double() const BigFile::Request::Column::operator double() const
{ {
return sqlite3_column_double(m_statement, static_cast<int>(m_index)); return sqlite3_column_double(m_statement, m_index);
} }
/****************************************************************************************/ /****************************************************************************************/
BigFile::Request::Column::operator eastl::string_view() const BigFile::Request::Column::operator eastl::string_view() const
{ {
return eastl::string_view { return eastl::string_view {reinterpret_cast<const char*>(sqlite3_column_text(m_statement, m_index)),
reinterpret_cast<const char*>(sqlite3_column_text(m_statement, static_cast<int>(m_index))), static_cast<std::size_t>(sqlite3_column_bytes(m_statement, m_index))};
static_cast<std::size_t>(sqlite3_column_bytes(m_statement, static_cast<int>(m_index)))};
} }
/****************************************************************************************/ /****************************************************************************************/
BigFile::Request::Column::operator eastl::span<const std::byte>() const BigFile::Request::Column::operator eastl::span<const std::byte>() const
{ {
return eastl::span<const std::byte> { return eastl::span<const std::byte> {static_cast<const std::byte*>(sqlite3_column_blob(m_statement, m_index)),
static_cast<const std::byte*>(sqlite3_column_blob(m_statement, static_cast<int>(m_index))), static_cast<std::size_t>(sqlite3_column_bytes(m_statement, m_index))};
static_cast<std::size_t>(sqlite3_column_bytes(m_statement, static_cast<int>(m_index)))};
}
/****************************************************************************************/
BigFile::Request::Column::operator std::span<const std::byte>() const
{
return std::span<const std::byte> {
static_cast<const std::byte*>(sqlite3_column_blob(m_statement, static_cast<int>(m_index))),
static_cast<std::size_t>(sqlite3_column_bytes(m_statement, static_cast<int>(m_index)))};
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -1,16 +1,27 @@
PRAGMA journal_mode=WAL; PRAGMA journal_mode=WAL;
CREATE TABLE IF NOT EXISTS AssetMetadata ( CREATE TABLE IF NOT EXISTS AssetMetadata (
UUID BLOB NOT NULL, UUID BLOB NOT NULL,
Name TEXT NOT NULL UNIQUE,
TypeID INTEGER NOT NULL,
TypeName TEXT NOT NULL,
CreateTime INTEGER NOT NULL DEFAULT(CAST(unixepoch('subsec') * 1000000 AS INTEGER)), CreateTime INTEGER NOT NULL DEFAULT(CAST(unixepoch('subsec') * 1000000 AS INTEGER)),
ModificationTime INTEGER NOT NULL DEFAULT(CAST(unixepoch('subsec') * 1000000 AS INTEGER)), ModificationTime INTEGER NOT NULL DEFAULT(CAST(unixepoch('subsec') * 1000000 AS INTEGER)),
PRIMARY KEY(UUID) PRIMARY KEY(UUID)
) WITHOUT ROWID; ) WITHOUT ROWID;
CREATE TRIGGER IF NOT EXISTS AssetMetadata_UpdateTime
AFTER UPDATE OF Name, TypeID, TypeName ON AssetMetadata FOR EACH ROW
BEGIN
UPDATE AssetMetadata
SET ModificationTime = CAST(unixepoch('subsec') * 1000000 AS INTEGER)
WHERE UUID = NEW.UUID;
END;
CREATE TABLE IF NOT EXISTS Asset ( CREATE TABLE IF NOT EXISTS Asset (
UUID BLOB NOT NULL, UUID BLOB NOT NULL,
Asset BLOB NOT NULL, Asset BLOB NOT NULL,
@@ -24,15 +35,4 @@ BEGIN
UPDATE AssetMetadata UPDATE AssetMetadata
SET ModificationTime = CAST(unixepoch('subsec') * 1000000 AS INTEGER) SET ModificationTime = CAST(unixepoch('subsec') * 1000000 AS INTEGER)
WHERE UUID = NEW.UUID; WHERE UUID = NEW.UUID;
END; END;
CREATE TABLE IF NOT EXISTS AssetHardReference (
UUID BLOB NOT NULL,
HardReference BLOB NOT NULL,
PRIMARY KEY(UUID, HardReference),
FOREIGN KEY(UUID) REFERENCES AssetMetadata(UUID)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS AssetHardReference_ReferencedUUID ON AssetHardReference(HardReference);
@@ -10,6 +10,7 @@ table AssetHeader
name: string (required, id: 1); name: string (required, id: 1);
type_id: AssetTypeID (required, native_inline, id: 2); type_id: AssetTypeID (required, native_inline, id: 2);
type_name: string (required, id: 3); type_name: string (required, id: 3);
version: uint = 0 (id: 4);
} }
table Asset table Asset
@@ -6,27 +6,39 @@
*********************************************************************/ *********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_ASSET_HPP #ifndef BIGFOOT_ENGINE_ASSET_ASSET_HPP
#define BIGFOOT_ENGINE_ASSET_ASSET_HPP #define BIGFOOT_ENGINE_ASSET_ASSET_HPP
#include <Engine/Asset/AssetBase.hpp>
#include <Engine/Asset/AssetConcepts.hpp> #include <Engine/Asset/AssetConcepts.hpp>
#include <Engine/Asset/AssetContainer.hpp>
#include <Engine/Asset/AssetLibrary.hpp>
#include <Engine/Asset/Asset_generated.hpp> #include <Engine/Asset/Asset_generated.hpp>
#include <Engine/EngineAssertHandler.hpp> #include <Engine/EngineAssertHandler.hpp>
#include <EASTL/span.h> #include <EASTL/span.h>
#include <EASTL/vector.h> #include <EASTL/vector.h>
#include <ankerl/unordered_dense.h> #include <ankerl/unordered_dense.h>
#include <flatbuffers/minireflect.h> #include <flatbuffers/reflection.h>
#include <rapidhash.h> #include <rapidhash.h>
namespace Bigfoot namespace Bigfoot
{ {
class AssetBase
{
public:
virtual ~AssetBase() = default;
protected:
AssetBase() = default;
AssetBase(const AssetBase& p_asset) = delete;
AssetBase(AssetBase&& p_asset) = default;
AssetBase& operator=(const AssetBase& p_asset) = delete;
AssetBase& operator=(AssetBase&& p_asset) = default;
};
template<class ASSET> template<class ASSET>
requires AssetTraits<ASSET> requires AssetTraits<ASSET>
class Asset: public AssetBase class Asset: public AssetBase
{ {
public: public:
using FLAT_ASSET = ASSET::FLAT; using FLAT_ASSET = typename ASSET::FLAT;
/** /**
* Constructor * Constructor
@@ -46,7 +58,7 @@ class Asset: public AssetBase
* \return The header of the asset * \return The header of the asset
*/ */
[[nodiscard]] [[nodiscard]]
const ::Flat::Bigfoot::AssetHeaderT& GetHeader() const override const ::Flat::Bigfoot::AssetHeaderT& GetHeader() const
{ {
return m_header; return m_header;
} }
@@ -61,13 +73,23 @@ class Asset: public AssetBase
m_header.name = p_name; m_header.name = p_name;
} }
/**
* Set the version of the asset
*
* \param p_name The version of the asset
*/
void SetVersion(const std::uint32_t p_version)
{
m_header.version = p_version;
}
/** /**
* Get the asset * Get the asset
* *
* \return The asset * \return The asset
*/ */
[[nodiscard]] [[nodiscard]]
const FLAT_ASSET::NativeTableType& GetAsset() const const typename FLAT_ASSET::NativeTableType& GetAsset() const
{ {
return m_asset; return m_asset;
} }
@@ -78,7 +100,7 @@ class Asset: public AssetBase
* \return The asset * \return The asset
*/ */
[[nodiscard]] [[nodiscard]]
FLAT_ASSET::NativeTableType& GetAsset() typename FLAT_ASSET::NativeTableType& GetAsset()
{ {
return m_asset; return m_asset;
} }
@@ -88,21 +110,20 @@ class Asset: public AssetBase
* *
* \param p_flatbuffer The flatbuffer to unpack * \param p_flatbuffer The flatbuffer to unpack
*/ */
void Unpack(const eastl::span<const std::byte> p_flatbuffer) override void Unpack(const eastl::span<const std::byte> p_flatbuffer)
{ {
#ifdef BIGFOOT_NOT_OPTIMIZED #ifdef BIGFOOT_NOT_OPTIMIZED
flatbuffers::Verifier verifier {reinterpret_cast<const std::uint8_t*>(p_flatbuffer.data()), flatbuffers::Verifier verifier {std::bit_cast<std::uint8_t*>(p_flatbuffer.data()), p_flatbuffer.size()};
p_flatbuffer.size()};
const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier); const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier);
CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!"); CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!");
#endif
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data()); const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data());
#ifdef BIGFOOT_NOT_OPTIMIZED
flatbuffers::Verifier innerAssetVerifier {asset->inner_asset()->data(), asset->inner_asset()->size()}; flatbuffers::Verifier innerAssetVerifier {asset->inner_asset()->data(), asset->inner_asset()->size()};
const bool innerAssetVerified = innerAssetVerifier.VerifyBuffer<FLAT_ASSET>(); const bool innerAssetVerified = innerAssetVerifier.VerifyBuffer<FLAT_ASSET>();
CRITICAL_ASSERT(EngineAssertHandler, innerAssetVerified, "Given asset could not be verified!"); CRITICAL_ASSERT(EngineAssertHandler, innerAssetVerified, "Given asset could not be verified!");
#else
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data());
#endif #endif
asset->header()->UnPackTo(&m_header); asset->header()->UnPackTo(&m_header);
@@ -115,7 +136,7 @@ class Asset: public AssetBase
* \return The packed asset * \return The packed asset
*/ */
[[nodiscard]] [[nodiscard]]
eastl::vector<std::byte> Pack() const override eastl::vector<std::byte> Pack() const
{ {
flatbuffers::FlatBufferBuilder innerAssetFbb; flatbuffers::FlatBufferBuilder innerAssetFbb;
innerAssetFbb.Finish(FLAT_ASSET::Pack(innerAssetFbb, &m_asset)); innerAssetFbb.Finish(FLAT_ASSET::Pack(innerAssetFbb, &m_asset));
@@ -125,39 +146,8 @@ class Asset: public AssetBase
const auto innerAsset = assetFbb.CreateVector(innerAssetFbb.GetBufferPointer(), innerAssetFbb.GetSize()); const auto innerAsset = assetFbb.CreateVector(innerAssetFbb.GetBufferPointer(), innerAssetFbb.GetSize());
assetFbb.Finish(::Flat::Bigfoot::CreateAsset(assetFbb, header, innerAsset)); assetFbb.Finish(::Flat::Bigfoot::CreateAsset(assetFbb, header, innerAsset));
return eastl::vector<std::byte> { return eastl::vector<std::byte> {std::bit_cast<std::byte*>(assetFbb.GetBufferPointer()),
reinterpret_cast<std::byte*>(assetFbb.GetBufferPointer()), std::bit_cast<std::byte*>(assetFbb.GetBufferPointer() + assetFbb.GetSize())};
reinterpret_cast<std::byte*>(assetFbb.GetBufferPointer() + assetFbb.GetSize())};
}
/**
* Get the HardReferences the flatbuffer has
*
* \param p_flatbuffer The flatbuffer
* \return The UUIDs of the HardReferences
*/
[[nodiscard]]
eastl::vector<UUID> GetHardReferences(const eastl::span<const std::byte> p_flatbuffer) const override
{
#ifdef BIGFOOT_NOT_OPTIMIZED
flatbuffers::Verifier verifier {reinterpret_cast<const std::uint8_t*>(p_flatbuffer.data()),
p_flatbuffer.size()};
const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier);
CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!");
#endif
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data());
#ifdef BIGFOOT_NOT_OPTIMIZED
flatbuffers::Verifier innerAssetVerifier {asset->inner_asset()->data(), asset->inner_asset()->size()};
const bool innerAssetVerified = innerAssetVerifier.VerifyBuffer<FLAT_ASSET>();
CRITICAL_ASSERT(EngineAssertHandler, innerAssetVerified, "Given asset could not be verified!");
#endif
HardReferenceVisitor visitor;
flatbuffers::IterateFlatBuffer(asset->inner_asset()->data(), FLAT_ASSET::MiniReflectTypeTable(), &visitor);
return visitor.GetUUIDs();
} }
/** /**
@@ -188,30 +178,12 @@ class Asset: public AssetBase
/** /**
* The asset * The asset
*/ */
FLAT_ASSET::NativeTableType m_asset; typename FLAT_ASSET::NativeTableType m_asset;
/** /**
* The asset header * The asset header
*/ */
::Flat::Bigfoot::AssetHeaderT m_header; ::Flat::Bigfoot::AssetHeaderT m_header;
}; };
/**
* Create an asset and insert it into its corresponding AssetContainer
*
* \tparam ASSET The Asset type
* \return The created asset, nullptr if no AssetContainer is registered for ASSET
*/
template<class ASSET>
requires AssetType<ASSET>
[[nodiscard]]
ASSET* CreateAsset()
{
AssetContainerBase* container = g_activeAssetLibrary->GetAssetContainer(ASSET::GetTypeID());
CRITICAL_ASSERT(EngineAssertHandler, container != nullptr, "No AssetContainer registered for this asset type!");
ContainerHandle* handle = container->Insert();
return static_cast<ASSET*>(handle->GetAsset());
}
} // namespace Bigfoot } // namespace Bigfoot
#endif #endif
@@ -1,111 +0,0 @@
/*********************************************************************
* \file AssetBase.hpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_ASSETBASE_HPP
#define BIGFOOT_ENGINE_ASSET_ASSETBASE_HPP
#include <Engine/Asset/Asset_generated.hpp>
#include <System/UUID/UUID.hpp>
#include <EASTL/span.h>
#include <EASTL/vector.h>
#include <ankerl/unordered_dense.h>
#include <flatbuffers/minireflect.h>
namespace Bigfoot
{
class AssetBase
{
public:
virtual ~AssetBase() = default;
/**
* Get the header of the asset
*
* \return The header of the asset
*/
[[nodiscard]]
virtual const ::Flat::Bigfoot::AssetHeaderT& GetHeader() const = 0;
/**
* Get the HardReferences the flatbuffer has
*
* \param p_flatbuffer The flatbuffer
* \return The UUIDs of the HardReferences
*/
[[nodiscard]]
virtual eastl::vector<UUID> GetHardReferences(const eastl::span<const std::byte> p_flatbuffer) const = 0;
/**
* Unpack a flatbuffer to the asset
*
* \param p_flatbuffer The flatbuffer to unpack
*/
virtual void Unpack(const eastl::span<const std::byte> p_flatbuffer) = 0;
/**
* Pack the asset to a flatbuffer
*
* \return The packed asset
*/
[[nodiscard]]
virtual eastl::vector<std::byte> Pack() const = 0;
AssetBase(const AssetBase& p_asset) = delete;
AssetBase& operator=(const AssetBase& p_asset) = delete;
protected:
AssetBase() = default;
AssetBase(AssetBase&& p_asset) = default;
AssetBase& operator=(AssetBase&& p_asset) = default;
class HardReferenceVisitor: public flatbuffers::IterationVisitor
{
public:
void Field(size_t p_fieldIndex,
size_t p_setIndex,
const flatbuffers::ElementaryType p_type,
const bool p_isVector,
const flatbuffers::TypeTable* p_typeTable,
const char* p_name,
const std::uint8_t* p_val) override;
void Element(size_t p_index,
const flatbuffers::ElementaryType p_type,
const flatbuffers::TypeTable* p_typeTable,
const std::uint8_t* p_val) override;
/**
* Get the visited HardReference
*
* \return The visited HardReferences
*/
[[nodiscard]]
eastl::vector<UUID> GetUUIDs() const;
private:
/**
* Visit an element in the flatbuffer
*
* \param p_type The element type
* \param p_typeTable The element typetable
* \param p_val The element
*/
void Visit(const flatbuffers::ElementaryType p_type,
const flatbuffers::TypeTable* p_typeTable,
const std::uint8_t* p_val);
/**
* The HardReferences visited so far
*/
ankerl::unordered_dense::set<UUID> m_uuids;
};
};
} // namespace Bigfoot
#endif
@@ -10,8 +10,6 @@
#include <System/UUID/UUID.hpp> #include <System/UUID/UUID.hpp>
#include <flatbuffers/minireflect.h>
#include <concepts> #include <concepts>
namespace Bigfoot namespace Bigfoot
@@ -27,7 +25,6 @@ concept AssetTraits = requires {
typename TRAITS::FLAT; typename TRAITS::FLAT;
typename TRAITS::FLAT::NativeTableType; typename TRAITS::FLAT::NativeTableType;
{ TRAITS::FLAT::GetFullyQualifiedName() } -> std::convertible_to<const char*>; { TRAITS::FLAT::GetFullyQualifiedName() } -> std::convertible_to<const char*>;
{ TRAITS::FLAT::MiniReflectTypeTable() } -> std::convertible_to<const flatbuffers::TypeTable*>;
}; };
/** /**
@@ -6,7 +6,7 @@
*********************************************************************/ *********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_ASSETCONTAINER_HPP #ifndef BIGFOOT_ENGINE_ASSET_ASSETCONTAINER_HPP
#define BIGFOOT_ENGINE_ASSET_ASSETCONTAINER_HPP #define BIGFOOT_ENGINE_ASSET_ASSETCONTAINER_HPP
#include <Engine/Asset/AssetBase.hpp> #include <Engine/Asset/Asset.hpp>
#include <Engine/Asset/AssetConcepts.hpp> #include <Engine/Asset/AssetConcepts.hpp>
#include <Engine/EngineAssertHandler.hpp> #include <Engine/EngineAssertHandler.hpp>
@@ -18,41 +18,40 @@
namespace Bigfoot namespace Bigfoot
{ {
class AssetContainerBase;
/** /**
* An indirection that allows References to immediately get the asset, without fetching the actual container * An indirection that allows References to immediately get the asset, without fetching the actual container
*/ */
class ContainerHandle class ContainerHandle
{ {
public: public:
/**
* Constructor
*
* \param p_assetContainer The originating assetcontainer
* \param p_uuid The UUID of tha asset
*/
ContainerHandle(AssetContainerBase* p_assetContainer, const UUID p_uuid);
/* /*
* Get the HardRef count * Get the HardRef count
* *
* \return The HardRef count. * \return The HardRef count.
*/ */
[[nodiscard]] [[nodiscard]]
std::uint32_t GetHardRefCount() const; std::uint32_t GetHardRefCount() const
{
return m_hardRefCount;
}
/* /*
* Increment the HardRef count * Increment the HardRef count
* *
*/ */
void IncrementHardRefCount(); void IncrementHardRefCount()
{
++m_hardRefCount;
}
/* /*
* Decrement the HardRef count * Decrement the HardRef count
* *
*/ */
void DecrementHardRefCount(); void DecrementHardRefCount()
{
--m_hardRefCount;
}
/* /*
* Get the SoftRef count * Get the SoftRef count
@@ -60,19 +59,28 @@ class ContainerHandle
* \return The SoftRef count. * \return The SoftRef count.
*/ */
[[nodiscard]] [[nodiscard]]
std::uint32_t GetSoftRefCount() const; std::uint32_t GetSoftRefCount() const
{
return m_softRefCount;
}
/* /*
* Increment the SoftRef count * Increment the SoftRef count
* *
*/ */
void IncrementSoftRefCount(); void IncrementSoftRefCount()
{
++m_softRefCount;
}
/* /*
* Decrement the SoftRef count * Decrement the SoftRef count
* *
*/ */
void DecrementSoftRefCount(); void DecrementSoftRefCount()
{
--m_softRefCount;
}
/* /*
* Get the Asset * Get the Asset
@@ -80,7 +88,10 @@ class ContainerHandle
* \return The asset, can be nullptr * \return The asset, can be nullptr
*/ */
[[nodiscard]] [[nodiscard]]
AssetBase* GetAsset(); AssetBase* GetAsset()
{
return m_asset;
}
/* /*
* Get the Asset * Get the Asset
@@ -88,14 +99,20 @@ class ContainerHandle
* \return The asset * \return The asset
*/ */
[[nodiscard]] [[nodiscard]]
const AssetBase* GetAsset() const; const AssetBase* GetAsset() const
{
return m_asset;
}
/* /*
* Set the asset * Set the asset
* *
* \param p_asset The asset * \param p_asset The asset
*/ */
void SetAsset(AssetBase* p_asset); void SetAsset(AssetBase* p_asset)
{
m_asset = p_asset;
}
private: private:
/* /*
@@ -112,16 +129,6 @@ class ContainerHandle
* The asset * The asset
*/ */
AssetBase* m_asset = nullptr; AssetBase* m_asset = nullptr;
/**
* The asset container
*/
AssetContainerBase* m_assetContainer = nullptr;
/**
* The UUID of the asset
*/
UUID m_uuid = UUID::NULL_UUID;
}; };
/****************************************************************************************/ /****************************************************************************************/
@@ -134,23 +141,6 @@ class AssetContainerBase
public: public:
virtual ~AssetContainerBase() = default; virtual ~AssetContainerBase() = default;
/*
* Inserts an Asset to the AssetContainer
*
* \param p_flatbuffer The flatbuffer to unpack to the asset
* \return The handle of the inserted asset
*/
[[nodiscard]]
virtual ContainerHandle* Insert(const eastl::span<const std::byte> p_flatbuffer) = 0;
/*
* Inserts an Asset to the AssetContainer
*
* \return The handle of the inserted asset
*/
[[nodiscard]]
virtual ContainerHandle* Insert() = 0;
/* /*
* Check if an Asset is in the AssetContainer or not * Check if an Asset is in the AssetContainer or not
* *
@@ -158,7 +148,11 @@ class AssetContainerBase
* \return True if in AssetContainer, false otherwise * \return True if in AssetContainer, false otherwise
*/ */
[[nodiscard]] [[nodiscard]]
bool Has(const UUID& p_uuid) const; bool Has(const UUID& p_uuid) const
{
const Entry* entry = FindEntry(p_uuid);
return entry != nullptr && entry->m_assetSlotKey.Valid();
}
/* /*
* Acquires a ContainerHandle for a given UUID * Acquires a ContainerHandle for a given UUID
@@ -168,44 +162,27 @@ class AssetContainerBase
* \return A ContainerHandle for the UUID * \return A ContainerHandle for the UUID
*/ */
[[nodiscard]] [[nodiscard]]
ContainerHandle* AcquireContainerHandle(const UUID& p_uuid); ContainerHandle* AcquireContainerHandle(const UUID& p_uuid)
{
return GetOrCreateEntry(p_uuid).m_handle;
}
/* /*
* Remove an Asset from the AssetContainer * Remove an Asset from the AssetContainer
* *
* \param p_uuid The UUID to remove * \param p_uuid The UUID to remove
*/ */
void Remove(const UUID& p_uuid); virtual void Remove(const UUID& p_uuid)
{
if (Entry* entry = FindEntry(p_uuid); entry != nullptr)
{
m_handles.Remove(entry->m_handleSlotKey);
m_uuidToEntry.erase(p_uuid);
}
}
/**
* Add an asset to be removed
*
* \param p_uuid UUID of the asset to remove
*/
void QueueForRemoval(const UUID& p_uuid);
/**
* Remove an asset from the pending remove queue
*
* \param p_uuid UUID of the asset to cancel removal
*/
void CancelRemoval(const UUID& p_uuid);
/**
* Process the assets that have been marked for remove
*
*/
void ProcessPendingRemovals();
[[nodiscard]]
bool IsMarkedForRemove(const UUID& p_uuid);
AssetContainerBase& operator=(const AssetContainerBase& p_container) = delete;
AssetContainerBase& operator=(AssetContainerBase&& p_container) = delete; AssetContainerBase& operator=(AssetContainerBase&& p_container) = delete;
AssetContainerBase(const AssetContainerBase& p_container) = delete;
AssetContainerBase(AssetContainerBase&& p_container) = delete;
protected: protected:
struct Entry struct Entry
{ {
@@ -227,14 +204,7 @@ class AssetContainerBase
AssetContainerBase() = default; AssetContainerBase() = default;
/* AssetContainerBase(AssetContainerBase&& p_container) = delete;
* Finds an entry matching the Asset
*
* \param p_uuid The UUID to find
* \return Pointer to an Entry, nullptr otherwise
*/
[[nodiscard]]
Entry* FindEntry(const UUID& p_uuid);
/* /*
* Finds an entry matching the Asset * Finds an entry matching the Asset
@@ -243,7 +213,24 @@ class AssetContainerBase
* \return Pointer to an Entry, nullptr otherwise * \return Pointer to an Entry, nullptr otherwise
*/ */
[[nodiscard]] [[nodiscard]]
const Entry* FindEntry(const UUID& p_uuid) const; Entry* FindEntry(const UUID& p_uuid)
{
const auto it = m_uuidToEntry.find(p_uuid);
return it != m_uuidToEntry.end() ? &it->second : nullptr;
}
/*
* Finds an entry matching the Asset
*
* \param p_uuid The UUID to find
* \return Pointer to an Entry, nullptr otherwise
*/
[[nodiscard]]
const Entry* FindEntry(const UUID& p_uuid) const
{
const auto it = m_uuidToEntry.find(p_uuid);
return it != m_uuidToEntry.end() ? &it->second : nullptr;
}
/* /*
* Finds an entry matching the Asset * Finds an entry matching the Asset
@@ -253,14 +240,17 @@ class AssetContainerBase
* \return The entry matching the Asset * \return The entry matching the Asset
*/ */
[[nodiscard]] [[nodiscard]]
Entry& GetOrCreateEntry(const UUID& p_uuid); Entry& GetOrCreateEntry(const UUID& p_uuid)
{
auto [it, inserted] = m_uuidToEntry.try_emplace(p_uuid);
if (inserted)
{
it->second.m_handleSlotKey = m_handles.Insert();
it->second.m_handle = m_handles.Get(it->second.m_handleSlotKey);
}
/* return it->second;
* Remove an asset }
*
* \param p_key The key to the asset
*/
virtual void RemoveAsset(SlotMapKey p_slotKey) = 0;
private: private:
/* /*
@@ -272,11 +262,6 @@ class AssetContainerBase
* Every Asset added to the map * Every Asset added to the map
*/ */
ankerl::unordered_dense::map<UUID, Entry> m_uuidToEntry; ankerl::unordered_dense::map<UUID, Entry> m_uuidToEntry;
/**
* Assets queued for removal
*/
eastl::vector<UUID> m_pendingRemovalUuids;
}; };
/****************************************************************************************/ /****************************************************************************************/
@@ -292,42 +277,16 @@ class AssetContainer: public AssetContainerBase
/* /*
* Inserts an Asset to the AssetContainer * Inserts an Asset to the AssetContainer
* *
* \param p_flatbuffer The flatbuffer to unpack to the asset * \tparam ARGS Arguments to construct the asset
* \return The handle of the inserted asset * \param p_args The arguments
* \return The key to the inserted asset.
*/ */
template<class... ARGS>
[[nodiscard]] [[nodiscard]]
ContainerHandle* Insert(const eastl::span<const std::byte> p_flatbuffer) override SlotMapKey Insert(ARGS&&... p_args)
{ {
return InsertInternal(&p_flatbuffer); SlotMapKey slotKey = m_assets.Insert(std::forward<ARGS>(p_args)...);
}
/*
* Inserts an Asset to the AssetContainer
*
* \return The handle of the inserted asset
*/
[[nodiscard]]
ContainerHandle* Insert() override
{
return InsertInternal(nullptr);
}
private:
/*
* Inserts an Asset to the AssetContainer, unpacking it from a flatbuffer if given one
*
* \param p_flatbuffer The flatbuffer to unpack to the asset, nullptr to default-construct the asset
* \return The handle of the inserted asset
*/
[[nodiscard]]
ContainerHandle* InsertInternal(const eastl::span<const std::byte>* p_flatbuffer)
{
SlotMapKey slotKey = m_assets.Insert();
ASSET* asset = m_assets.Get(slotKey); ASSET* asset = m_assets.Get(slotKey);
if (p_flatbuffer != nullptr)
{
asset->Unpack(*p_flatbuffer);
}
Entry& entry = GetOrCreateEntry(asset->GetHeader().uuid); Entry& entry = GetOrCreateEntry(asset->GetHeader().uuid);
if (entry.m_assetSlotKey.Valid()) if (entry.m_assetSlotKey.Valid())
@@ -341,19 +300,51 @@ class AssetContainer: public AssetContainerBase
entry.m_handle->SetAsset(asset); entry.m_handle->SetAsset(asset);
} }
return entry.m_handle; return slotKey;
} }
/* /*
* Remove an asset * Get the Asset
* *
* \param p_key The key to the asset * \param p_key The key to the asset
* \return Pointer to the Asset
*/ */
void RemoveAsset(SlotMapKey p_key) override [[nodiscard]]
ASSET* Get(const SlotMapKey p_key)
{ {
m_assets.Remove(p_key); return m_assets.Get(p_key);
} }
/*
* Get the Asset
*
* \param p_key The key to the asset
* \return Pointer to the Asset
*/
[[nodiscard]]
const ASSET* Get(const SlotMapKey p_key) const
{
return m_assets.Get(p_key);
}
/*
* Remove an Asset from the AssetContainer
*
* \param p_uuid The UUID to remove
*/
void Remove(const UUID& p_uuid) override
{
if (Entry* entry = FindEntry(p_uuid); entry != nullptr && entry->m_assetSlotKey.Valid())
{
entry->m_handle->SetAsset(nullptr);
m_assets.Remove(entry->m_assetSlotKey);
entry->m_assetSlotKey = SlotMapKey {};
}
AssetContainerBase::Remove(p_uuid);
}
private:
/* /*
* The assets * The assets
*/ */
@@ -19,13 +19,6 @@
return AssetType::GetTypeID(); \ return AssetType::GetTypeID(); \
} \ } \
AssetContainer<AssetType> g_containerFor##AssetName; \ AssetContainer<AssetType> g_containerFor##AssetName; \
const bool g_insertedContainerFor##AssetName = []() \ const bool g_insertedContainerFor##AssetName = g_assetLibrary.Insert(&g_containerFor##AssetName); \
{ \
const bool inserted = g_assetLibrary.Insert(&g_containerFor##AssetName); \
CRITICAL_ASSERT(EngineAssertHandler, \
inserted, \
"AssetTypeID collision or duplicate registration for asset type '" #AssetName "'"); \
return inserted; \
}(); \
} }
#endif #endif
@@ -52,7 +52,15 @@ class AssetLibrary
* \return The AssetContainer for the AssetType. Nullptr if not found * \return The AssetContainer for the AssetType. Nullptr if not found
*/ */
[[nodiscard]] [[nodiscard]]
AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID); AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID)
{
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
{
return container->second;
}
return nullptr;
}
/** /**
* Get the AssetContainer for a given AssetType * Get the AssetContainer for a given AssetType
@@ -61,46 +69,19 @@ class AssetLibrary
* \return The AssetContainer for the AssetType. Nullptr if not found * \return The AssetContainer for the AssetType. Nullptr if not found
*/ */
[[nodiscard]] [[nodiscard]]
const AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID) const; const AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID) const
{
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
{
return container->second;
}
/** return nullptr;
* Get the AssetContainer for a given UUID }
*
* \param p_uuid The asset
* \return The AssetContainer for the UUID. Nullptr if not found
*/
[[nodiscard]]
const AssetContainerBase* GetAssetContainer(const UUID& p_uuid) const;
/**
* Get the AssetContainer for a given UUID
*
* \param p_uuid The asset
* \return The AssetContainer for the UUID. Nullptr if not found
*/
[[nodiscard]]
AssetContainerBase* GetAssetContainer(const UUID& p_uuid);
/**
* Check if an Asset is already loaded in the library
*
* \param p_uuid The asset to check
* \return True if already loaded, false otherwise
*/
[[nodiscard]]
bool IsLoaded(const UUID& p_uuid) const;
/**
* Loop through the AssetContainers to remove the pending assets marked for removal
*
*/
void ProcessPendingRemovals();
AssetLibrary& operator=(const AssetLibrary& p_library) = default; AssetLibrary& operator=(const AssetLibrary& p_library) = default;
AssetLibrary& operator=(AssetLibrary&& p_library) = delete; AssetLibrary& operator=(AssetLibrary&& p_library) = delete;
~AssetLibrary() = default;
private: private:
// All the asset containers // All the asset containers
ankerl::unordered_dense::map<AssetTypeID, AssetContainerBase*> m_assetContainers; ankerl::unordered_dense::map<AssetTypeID, AssetContainerBase*> m_assetContainers;
@@ -15,10 +15,13 @@ using AssetTypeID = std::uint64_t;
/****************************************************************************************/ /****************************************************************************************/
namespace Flat::Bigfoot namespace Flat
{
namespace Bigfoot
{ {
struct AssetTypeID; struct AssetTypeID;
} // namespace Flat::Bigfoot }
} // namespace Flat
/****************************************************************************************/ /****************************************************************************************/
@@ -53,6 +53,7 @@ struct AssetHeaderT : public ::flatbuffers::NativeTable {
eastl::string name{}; eastl::string name{};
::Bigfoot::AssetTypeID type_id{}; ::Bigfoot::AssetTypeID type_id{};
eastl::string type_name{}; eastl::string type_name{};
uint32_t version = 0;
}; };
struct AssetHeader FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { struct AssetHeader FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
@@ -69,7 +70,8 @@ struct AssetHeader FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
VT_UUID = 4, VT_UUID = 4,
VT_NAME = 6, VT_NAME = 6,
VT_TYPE_ID = 8, VT_TYPE_ID = 8,
VT_TYPE_NAME = 10 VT_TYPE_NAME = 10,
VT_VERSION = 12
}; };
const Flat::Bigfoot::UUID *uuid() const { const Flat::Bigfoot::UUID *uuid() const {
return GetStruct<const Flat::Bigfoot::UUID *>(VT_UUID); return GetStruct<const Flat::Bigfoot::UUID *>(VT_UUID);
@@ -83,6 +85,9 @@ struct AssetHeader FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
const ::flatbuffers::String *type_name() const { const ::flatbuffers::String *type_name() const {
return GetPointer<const ::flatbuffers::String *>(VT_TYPE_NAME); return GetPointer<const ::flatbuffers::String *>(VT_TYPE_NAME);
} }
uint32_t version() const {
return GetField<uint32_t>(VT_VERSION, 0);
}
template <bool B = false> template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const { bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
@@ -92,6 +97,7 @@ struct AssetHeader FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
VerifyFieldRequired<Flat::Bigfoot::AssetTypeID>(verifier, VT_TYPE_ID, 8) && VerifyFieldRequired<Flat::Bigfoot::AssetTypeID>(verifier, VT_TYPE_ID, 8) &&
VerifyOffsetRequired(verifier, VT_TYPE_NAME) && VerifyOffsetRequired(verifier, VT_TYPE_NAME) &&
verifier.VerifyString(type_name()) && verifier.VerifyString(type_name()) &&
VerifyField<uint32_t>(verifier, VT_VERSION, 4) &&
verifier.EndTable(); verifier.EndTable();
} }
AssetHeaderT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const; AssetHeaderT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
@@ -115,6 +121,9 @@ struct AssetHeaderBuilder {
void add_type_name(::flatbuffers::Offset<::flatbuffers::String> type_name) { void add_type_name(::flatbuffers::Offset<::flatbuffers::String> type_name) {
fbb_.AddOffset(AssetHeader::VT_TYPE_NAME, type_name); fbb_.AddOffset(AssetHeader::VT_TYPE_NAME, type_name);
} }
void add_version(uint32_t version) {
fbb_.AddElement<uint32_t>(AssetHeader::VT_VERSION, version, 0);
}
explicit AssetHeaderBuilder(::flatbuffers::FlatBufferBuilder &_fbb) explicit AssetHeaderBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) { : fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
@@ -135,8 +144,10 @@ inline ::flatbuffers::Offset<AssetHeader> CreateAssetHeader(
const Flat::Bigfoot::UUID *uuid = nullptr, const Flat::Bigfoot::UUID *uuid = nullptr,
::flatbuffers::Offset<::flatbuffers::String> name = 0, ::flatbuffers::Offset<::flatbuffers::String> name = 0,
const Flat::Bigfoot::AssetTypeID *type_id = nullptr, const Flat::Bigfoot::AssetTypeID *type_id = nullptr,
::flatbuffers::Offset<::flatbuffers::String> type_name = 0) { ::flatbuffers::Offset<::flatbuffers::String> type_name = 0,
uint32_t version = 0) {
AssetHeaderBuilder builder_(_fbb); AssetHeaderBuilder builder_(_fbb);
builder_.add_version(version);
builder_.add_type_name(type_name); builder_.add_type_name(type_name);
builder_.add_type_id(type_id); builder_.add_type_id(type_id);
builder_.add_name(name); builder_.add_name(name);
@@ -251,6 +262,7 @@ inline void AssetHeader::UnPackTo(AssetHeaderT *_o, const ::flatbuffers::resolve
{ auto _e = name(); if (_e) _o->name = eastl::string(_e->c_str(), _e->size()); } { auto _e = name(); if (_e) _o->name = eastl::string(_e->c_str(), _e->size()); }
{ auto _e = type_id(); if (_e) _o->type_id = ::flatbuffers::UnPack(*_e); } { auto _e = type_id(); if (_e) _o->type_id = ::flatbuffers::UnPack(*_e); }
{ auto _e = type_name(); if (_e) _o->type_name = eastl::string(_e->c_str(), _e->size()); } { auto _e = type_name(); if (_e) _o->type_name = eastl::string(_e->c_str(), _e->size()); }
{ auto _e = version(); _o->version = _e; }
} }
inline ::flatbuffers::Offset<AssetHeader> CreateAssetHeader(::flatbuffers::FlatBufferBuilder &_fbb, const AssetHeaderT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) { inline ::flatbuffers::Offset<AssetHeader> CreateAssetHeader(::flatbuffers::FlatBufferBuilder &_fbb, const AssetHeaderT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
@@ -265,12 +277,14 @@ inline ::flatbuffers::Offset<AssetHeader> AssetHeader::Pack(::flatbuffers::FlatB
auto _name = _fbb.CreateString(_o->name); auto _name = _fbb.CreateString(_o->name);
auto _type_id = ::flatbuffers::Pack(_o->type_id); auto _type_id = ::flatbuffers::Pack(_o->type_id);
auto _type_name = _fbb.CreateString(_o->type_name); auto _type_name = _fbb.CreateString(_o->type_name);
auto _version = _o->version;
return Flat::Bigfoot::CreateAssetHeader( return Flat::Bigfoot::CreateAssetHeader(
_fbb, _fbb,
&_uuid, &_uuid,
_name, _name,
&_type_id, &_type_id,
_type_name); _type_name,
_version);
} }
inline AssetT::AssetT(const AssetT &o) inline AssetT::AssetT(const AssetT &o)
@@ -318,14 +332,15 @@ inline const ::flatbuffers::TypeTable *AssetHeaderTypeTable() {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 }, { ::flatbuffers::ET_SEQUENCE, 0, 0 },
{ ::flatbuffers::ET_STRING, 0, -1 }, { ::flatbuffers::ET_STRING, 0, -1 },
{ ::flatbuffers::ET_SEQUENCE, 0, 1 }, { ::flatbuffers::ET_SEQUENCE, 0, 1 },
{ ::flatbuffers::ET_STRING, 0, -1 } { ::flatbuffers::ET_STRING, 0, -1 },
{ ::flatbuffers::ET_UINT, 0, -1 }
}; };
static const ::flatbuffers::TypeFunction type_refs[] = { static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::UUIDTypeTable, Flat::Bigfoot::UUIDTypeTable,
Flat::Bigfoot::AssetTypeIDTypeTable Flat::Bigfoot::AssetTypeIDTypeTable
}; };
static const ::flatbuffers::TypeTable tt = { static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, nullptr, nullptr ::flatbuffers::ST_TABLE, 5, type_codes, type_refs, nullptr, nullptr, nullptr
}; };
return &tt; return &tt;
} }
@@ -94,9 +94,7 @@ class ReferenceBase
return m_uuid == p_reference.m_uuid; return m_uuid == p_reference.m_uuid;
} }
private: protected:
friend DERIVED;
ReferenceBase() = default; ReferenceBase() = default;
ReferenceBase(const UUID& p_uuid): ReferenceBase(const UUID& p_uuid):
@@ -118,6 +116,7 @@ class ReferenceBase
{ {
} }
private:
/** /**
* Get the associated handle container for the asset * Get the associated handle container for the asset
* Register the reference inside the handle * Register the reference inside the handle
@@ -153,6 +152,7 @@ class ReferenceBase
} }
} }
private:
/** /**
* The UUID * The UUID
*/ */
@@ -9,17 +9,12 @@
#include <Engine/DataAccessor/DataAccessor.hpp> #include <Engine/DataAccessor/DataAccessor.hpp>
#include <System/File/File.hpp> #include <System/File/File.hpp>
#include <System/Time/Time.hpp>
#include <Utils/TaggedType.hpp> #include <Utils/TaggedType.hpp>
#include <EASTL/optional.h>
#include <EASTL/span.h> #include <EASTL/span.h>
#include <EASTL/string_view.h>
#include <sqlite3.h> #include <sqlite3.h>
#include <span>
namespace Bigfoot namespace Bigfoot
{ {
#ifdef BIGFOOT_TOOLMODE #ifdef BIGFOOT_TOOLMODE
@@ -54,22 +49,15 @@ class BigFile: public DataAccessor
*/ */
void RollbackTransaction(); void RollbackTransaction();
/** ~BigFile();
* Clear the BigFile
*
*/
void Clear();
~BigFile() override;
/** /**
* Get an Asset flatbuffer * Get an Asset flatbuffer
* *
* \param p_uuid The asset to get the flatbuffer of * \param p_uuid The asset to get the flatbuffer of
* \return The flatbuffer, or an empty vector if the asset was not found * \return The flatbuffer, or nullopt if the asset was not found
*/ */
[[nodiscard]] eastl::optional<eastl::vector<std::byte>> GetAssetFlatbuffer(const UUID& p_uuid) const override;
eastl::vector<std::byte> GetAssetFlatbuffer(const UUID& p_uuid) const override;
/** /**
* Get several Asset flatbuffers * Get several Asset flatbuffers
@@ -77,75 +65,40 @@ class BigFile: public DataAccessor
* \param p_uuids The assets to get the flatbuffers of * \param p_uuids The assets to get the flatbuffers of
* \return The flatbuffers that were found * \return The flatbuffers that were found
*/ */
[[nodiscard]]
eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const override; eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const override;
/** /**
* Get the HardReferences of a given asset * Get an Asset metadata
* *
* \param p_uuid The asset to get the HardReferences of * \param p_uuid The asset to get the metadata of
* \return The HardReferences of the asset * \return The metadata, or nullopt if the asset was not found
*/ */
[[nodiscard]] eastl::optional<AssetMetadata> GetAssetMetadata(const UUID& p_uuid) const override;
eastl::vector<UUID> GetAssetHardReferences(const UUID& p_uuid) const override;
/** /**
* Get the HardReferences of given assets * Get several Asset metadatas
* *
* \param p_uuids The assets to get the HardReferences of * \param p_uuids The assets to get the metadatas of
* \return The HardReferences of the assets * \return The metadatas that were found
*/ */
[[nodiscard]] eastl::vector<AssetMetadata> GetAssetMetadatas(eastl::span<const UUID> p_uuids) const override;
eastl::vector<eastl::vector<UUID>> GetAssetsHardReferences(eastl::span<const UUID> p_uuids) const override;
struct AssetTime
{
Time m_creationTime;
Time m_modificationTime;
[[nodiscard]]
bool operator==(const AssetTime& p_other) const = default;
};
/**
* Get the creation and modification time of an asset
*
* \param p_uuid The asset to get the time of
* \return The time of the asset, nullopt if the asset was not found
*/
[[nodiscard]]
eastl::optional<AssetTime> GetAssetTime(const UUID& p_uuid) const;
/**
* Get the creation and modification time of several assets
*
* \param p_uuids The assets to get the time of
* \return The time of the assets. nullopt for assets not found
*/
[[nodiscard]]
eastl::vector<eastl::optional<AssetTime>> GetAssetsTime(eastl::span<const UUID> p_uuids) const;
/** /**
* Save an asset * Save an asset
* *
* \param p_uuid The UUID * \p_metadata The metadata
* \param p_flatbuffer The flatbuffer of the asset * \p_flatbuffer The flatbuffer of the asset
* \param p_hardReferences The HardReferences the asset points to
*/ */
void SaveAssetFlatbuffer(const UUID& p_uuid, void SaveAssetFlatbuffer(const AssetMetadata& p_metadata, const eastl::span<const std::byte> p_flatbuffer) override;
const eastl::span<const std::byte> p_flatbuffer,
const eastl::span<const UUID> p_hardReferences) override;
/** /**
* Save several assets * Save several assets
* *
* \param p_uuids The UUIDs * \p_metadatas The metadatas
* \param p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index * \p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index
* \param p_hardReferences The HardReferences the asset points to
*/ */
void SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids, void SaveAssetFlatbuffers(eastl::span<const AssetMetadata> p_metadatas,
const eastl::span<const eastl::vector<std::byte>> p_flatbuffers, eastl::span<const eastl::vector<std::byte>> p_flatbuffers) override;
const eastl::span<const eastl::vector<UUID>> p_hardReferences) override;
/** /**
* Check if the Asset exists * Check if the Asset exists
@@ -153,7 +106,6 @@ class BigFile: public DataAccessor
* \param p_uuid The asset to check * \param p_uuid The asset to check
* \param True if it exists, false otherwise * \param True if it exists, false otherwise
*/ */
[[nodiscard]]
bool Has(const UUID& p_uuid) const override; bool Has(const UUID& p_uuid) const override;
BigFile& operator=(const BigFile& p_bigFile) = delete; BigFile& operator=(const BigFile& p_bigFile) = delete;
@@ -328,13 +280,6 @@ class BigFile: public DataAccessor
*/ */
operator eastl::span<const std::byte>() const; operator eastl::span<const std::byte>() const;
/*
* Get value as a blob
*
* \return The value
*/
operator std::span<const std::byte>() const;
private: private:
/* /*
* The statement * The statement
@@ -369,14 +314,14 @@ class BigFile: public DataAccessor
/* /*
* The statement * The statement
*/ */
sqlite3_stmt* m_statement = nullptr; sqlite3_stmt* m_statement;
}; };
private: private:
/** /**
* The BigFile DB * The BigFile DB
*/ */
sqlite3* m_db = nullptr; sqlite3* m_db;
}; };
#endif #endif
} // namespace Bigfoot } // namespace Bigfoot
@@ -11,12 +11,25 @@
#include <System/Time/Time.hpp> #include <System/Time/Time.hpp>
#include <System/UUID/UUID.hpp> #include <System/UUID/UUID.hpp>
#include <EASTL/optional.h>
#include <EASTL/span.h> #include <EASTL/span.h>
#include <EASTL/string.h> #include <EASTL/string.h>
#include <EASTL/vector.h> #include <EASTL/vector.h>
namespace Bigfoot namespace Bigfoot
{ {
struct AssetMetadata
{
UUID m_uuid = UUID::NULL_UUID;
eastl::string m_name {};
AssetTypeID m_typeID = 0;
eastl::string m_typeName {};
Time m_creationTime = 0;
Time m_modificationTime = 0;
};
class DataAccessor class DataAccessor
{ {
public: public:
@@ -31,10 +44,9 @@ class DataAccessor
* Get an Asset flatbuffer * Get an Asset flatbuffer
* *
* \param p_uuid The asset to get the flatbuffer of * \param p_uuid The asset to get the flatbuffer of
* \return The flatbuffer, or an empty vector if the asset was not found * \return The flatbuffer, or nullopt if the asset was not found
*/ */
[[nodiscard]] virtual eastl::optional<eastl::vector<std::byte>> GetAssetFlatbuffer(const UUID& p_uuid) const = 0;
virtual eastl::vector<std::byte> GetAssetFlatbuffer(const UUID& p_uuid) const = 0;
/** /**
* Get several Asset flatbuffers * Get several Asset flatbuffers
@@ -42,48 +54,41 @@ class DataAccessor
* \param p_uuids The assets to get the flatbuffers of * \param p_uuids The assets to get the flatbuffers of
* \return The flatbuffers that were found * \return The flatbuffers that were found
*/ */
[[nodiscard]]
virtual eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const = 0; virtual eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const = 0;
/** /**
* Get the HardReferences of a given asset * Get an Asset metadata
* *
* \param p_uuid The asset to get the HardReferences of * \param p_uuid The asset to get the metadata of
* \return The HardReferences of the asset * \return The metadata, or nullopt if the asset was not found
*/ */
[[nodiscard]] virtual eastl::optional<AssetMetadata> GetAssetMetadata(const UUID& p_uuid) const = 0;
virtual eastl::vector<UUID> GetAssetHardReferences(const UUID& p_uuid) const = 0;
/** /**
* Get the HardReferences of given assets * Get several Asset metadatas
* *
* \param p_uuids The assets to get the HardReferences of * \param p_uuids The assets to get the metadatas of
* \return The HardReferences of the assets * \return The metadatas that were found
*/ */
[[nodiscard]] virtual eastl::vector<AssetMetadata> GetAssetMetadatas(eastl::span<const UUID> p_uuids) const = 0;
virtual eastl::vector<eastl::vector<UUID>> GetAssetsHardReferences(eastl::span<const UUID> p_uuids) const = 0;
/** /**
* Save an asset * Save an asset
* *
* \param p_uuid The UUID * \p_metadata The metadata
* \param p_flatbuffer The flatbuffer of the asset * \p_flatbuffer The flatbuffer of the asset
* \param p_hardReferences The HardReferences the asset points to
*/ */
virtual void SaveAssetFlatbuffer(const UUID& p_uuid, virtual void SaveAssetFlatbuffer(const AssetMetadata& p_metadata,
const eastl::span<const std::byte> p_flatbuffer, const eastl::span<const std::byte> p_flatbuffer) = 0;
const eastl::span<const UUID> p_hardReferences) = 0;
/** /**
* Save several assets * Save several assets
* *
* \param p_uuids The UUIDs * \p_metadatas The metadatas
* \param p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index * \p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index
* \param p_hardReferences The HardReferences the asset points to
*/ */
virtual void SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids, virtual void SaveAssetFlatbuffers(eastl::span<const AssetMetadata> p_metadatas,
const eastl::span<const eastl::vector<std::byte>> p_flatbuffers, eastl::span<const eastl::vector<std::byte>> p_flatbuffers) = 0;
const eastl::span<const eastl::vector<UUID>> p_hardReferences) = 0;
/** /**
* Check if the Asset exists * Check if the Asset exists
@@ -91,7 +96,6 @@ class DataAccessor
* \param p_uuid The asset to check * \param p_uuid The asset to check
* \param True if it exists, false otherwise * \param True if it exists, false otherwise
*/ */
[[nodiscard]]
virtual bool Has(const UUID& p_uuid) const = 0; virtual bool Has(const UUID& p_uuid) const = 0;
DataAccessor& operator=(const DataAccessor& p_accessor) = default; DataAccessor& operator=(const DataAccessor& p_accessor) = default;
@@ -10,7 +10,7 @@
#include <Utils/Assert/AssertHandler.hpp> #include <Utils/Assert/AssertHandler.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot namespace Bigfoot
{ {
@@ -15,7 +15,7 @@ namespace Bigfoot
/* /*
* Logger * Logger
*/ */
inline Log::LoggerInfo ENGINE_LOGGER { .m_name = "ENGINE_LOGGER", .m_level = Flat::LogLevel::Trace}; inline Log::LoggerInfo ENGINE_LOGGER {"ENGINE_LOGGER", Flat::LogLevel::Trace};
} // namespace Bigfoot } // namespace Bigfoot
#endif #endif
#endif #endif
@@ -1,243 +0,0 @@
/*********************************************************************
* \file Sasquatch.hpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_SASQUATCH_SASQUATCH_HPP
#define BIGFOOT_ENGINE_SASQUATCH_SASQUATCH_HPP
#include <Engine/DataAccessor/DataAccessor.hpp>
#include <System/File/File.hpp>
#include <System/File/MemoryMappedFile.hpp>
#include <System/UUID/UUID.hpp>
#include <Utils/TargetMacros.h>
#include <EASTL/span.h>
#include <EASTL/vector.h>
#include <ankerl/unordered_dense.h>
#include <cstddef>
#include <cstdint>
#include <type_traits>
namespace Bigfoot
{
struct SasquatchHeader
{
static constexpr std::uint32_t MAGIC = 0x53515443; // 'SQTC'
static constexpr std::uint32_t VERSION = 1;
std::uint32_t m_magic = MAGIC;
std::uint32_t m_version = VERSION;
std::uint64_t m_assetCount = 0;
};
static_assert(std::is_trivially_copyable_v<SasquatchHeader>);
/****************************************************************************************/
struct SasquatchEntry
{
std::array<std::byte, UUID::UUID_BYTE_SIZE> m_uuid {};
std::size_t m_assetOffset = 0;
std::size_t m_assetSize = 0;
std::size_t m_hardReferencesOffset = 0;
std::size_t m_hardReferencesSize = 0;
};
static_assert(std::is_trivially_copyable_v<SasquatchEntry>);
/****************************************************************************************/
#if defined(BIGFOOT_TOOLMODE) || defined(BIGFOOT_BUILD_TESTS) || defined(BIGFOOT_BUILD_BENCHMARKS)
class SasquatchWriter
{
public:
/**
* Constructor
* Writes the header
*
* \param p_file The file to write
* \param p_assetCount The number of assets that will be written
* \param p_totalFlatbufferBytes The sum of the sizes of every flatbuffer that will be written
* \param p_totalHardReferencesBytes The sum of the sizes of every asset hardreferences that will be written
*/
SasquatchWriter(const File& p_file,
const std::uint64_t p_assetCount,
const std::size_t p_totalFlatbufferBytes,
const std::size_t p_totalHardReferencesBytes);
SasquatchWriter(const SasquatchWriter& p_writer) = delete;
SasquatchWriter(SasquatchWriter&& p_writer) = delete;
/**
* Destructor
* Writes the entries
*
*/
~SasquatchWriter();
/**
* Writes an asset to the file.
*
* \param p_uuid The UUID of the asset
* \param p_flatbuffer The flatbuffer of the asset
*/
void WriteAsset(const UUID& p_uuid,
eastl::span<const std::byte> p_flatbuffer,
eastl::span<const UUID> p_hardReferences);
SasquatchWriter& operator=(const SasquatchWriter& p_writer) = delete;
SasquatchWriter& operator=(SasquatchWriter&& p_writer) = delete;
private:
static constexpr std::uint64_t PREFETCH_BYTES = 4ULL * 1024 * 1024;
/**
* The number of assets expected
*/
std::uint64_t m_assetCount;
/**
* How far into m_file has already been prefetched
*/
std::size_t m_prefetchedUpTo = 0;
/**
* Current write position in the data region
*/
std::size_t m_currentDataOffset;
/**
* The Sasquatch file being written, mapped at its final size
*/
WritableMemoryMappedFile m_file;
/**
* The entries
*/
eastl::vector<SasquatchEntry> m_entries;
};
/****************************************************************************************/
class Sasquatch: public DataAccessor
{
public:
/**
* Constructor
*
* \param p_file The sasquatch file
*/
Sasquatch(const File& p_file);
Sasquatch(const Sasquatch& p_sasquatch) = delete;
Sasquatch(Sasquatch&& p_sasquatch) = delete;
~Sasquatch() override = default;
/**
* Get the header
*
* \return The header
*/
[[nodiscard]]
const SasquatchHeader& GetHeader() const;
/**
* Get an Asset flatbuffer
*
* \param p_uuid The asset to get the flatbuffer of
* \return The flatbuffer, or an empty vector if the asset was not found
*/
[[nodiscard]]
eastl::vector<std::byte> GetAssetFlatbuffer(const UUID& p_uuid) const override;
/**
* Get several Asset flatbuffers
*
* \param p_uuids The assets to get the flatbuffers of
* \return The flatbuffers that were found
*/
[[nodiscard]]
eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const override;
/**
* Get the HardReferences of a given asset
*
* \param p_uuid The asset to get the HardReferences of
* \return The HardReferences of the asset
*/
[[nodiscard]]
eastl::vector<UUID> GetAssetHardReferences(const UUID& p_uuid) const override;
/**
* Get the HardReferences of given assets
*
* \param p_uuids The assets to get the HardReferences of
* \return The HardReferences of the assets
*/
[[nodiscard]]
eastl::vector<eastl::vector<UUID>> GetAssetsHardReferences(eastl::span<const UUID> p_uuids) const override;
/**
* Sasquatch is read-only: this will always fail
*
*/
void SaveAssetFlatbuffer(const UUID& p_uuid,
eastl::span<const std::byte> p_flatbuffer,
eastl::span<const UUID> p_hardReferences) override;
/**
* Sasquatch is read-only: this will always fail
*
*/
void SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids,
eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
eastl::span<const eastl::vector<UUID>> p_hardReferences) override;
/**
* Check if the Asset exists
*
* \param p_uuid The asset to check
* \param True if it exists, false otherwise
*/
[[nodiscard]]
bool Has(const UUID& p_uuid) const override;
Sasquatch& operator=(const Sasquatch& p_sasquatch) = delete;
Sasquatch& operator=(Sasquatch&& p_sasquatch) = delete;
private:
struct Entry
{
std::size_t m_assetOffset = 0;
std::size_t m_assetSize = 0;
std::size_t m_hardReferencesOffset = 0;
std::size_t m_hardReferencesSize = 0;
};
/**
* The Sasquatch file
*/
MemoryMappedFile m_file;
/**
* The sasquatch header
*/
SasquatchHeader m_header;
/**
* UUID to entry
*/
ankerl::unordered_dense::map<UUID, Entry> m_entries;
};
#endif
} // namespace Bigfoot
#endif
@@ -1,22 +0,0 @@
@AUTO_GENERATED_COMMENT@
/*********************************************************************
* \file SasquatchInfo.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_@SASQUATCH_NAME@_SASQUATCHINFO_GENERATED_HPP
#define BIGFOOT_@SASQUATCH_NAME@_SASQUATCHINFO_GENERATED_HPP
#include <EASTL/string_view.h>
#if defined BIGFOOT_GAME
namespace Bigfoot
{
/*
* Sasquatch location
*/
constexpr eastl::string_view SASQUATCH_@SASQUATCH_NAME@_LOCATION {"@SASQUATCH_LOCATION@"};
} // namespace Bigfoot
#endif
#endif
@@ -1,54 +0,0 @@
/*********************************************************************
* \file SerializationManager.hpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_SERIALIZATIONMANAGER_SERIALIZATIONMANAGER_HPP
#define BIGFOOT_ENGINE_SERIALIZATIONMANAGER_SERIALIZATIONMANAGER_HPP
#include <System/UUID/UUID.hpp>
#include <EASTL/span.h>
namespace Bigfoot::SerializationManager
{
/**
* Load an Asset, along with every HardReference it transitively points to
* Already loaded assets are skipped. Assets that are part of a cyclic dependency are left unloaded
*
* \param p_uuid The asset to load
*/
void LoadAsset(const UUID& p_uuid);
/**
* Load several Assets, along with every HardReference they transitively point to
* Already loaded assets are skipped. Assets that are part of a cyclic dependency are left unloaded
*
* \param p_uuids The assets to load
*/
void LoadAssets(const eastl::span<const UUID> p_uuids);
#ifdef BIGFOOT_TOOLMODE
/**
* Save an Asset
* Fails without saving if a cyclic dependency is detected starting from this asset
*
* \param p_uuid The asset to save
* \return True if the asset was saved, false otherwise
*/
[[nodiscard]]
bool SaveAsset(const UUID& p_uuid);
/**
* Save several Assets
* Fails without saving any of them if a cyclic dependency is detected starting from any of them
*
* \param p_uuids The assets to save
* \return True if the assets were saved, false otherwise
*/
[[nodiscard]]
bool SaveAssets(const eastl::span<const UUID> p_uuids);
#endif
} // namespace Bigfoot::SerializationManager
#endif
@@ -1,266 +0,0 @@
/*********************************************************************
* \file Sasquatch.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <Engine/Sasquatch/Sasquatch.hpp>
#include <Engine/EngineAssertHandler.hpp>
#include <algorithm>
#include <cstring>
namespace Bigfoot
{
#if defined(BIGFOOT_TOOLMODE) || defined(BIGFOOT_BUILD_TESTS) || defined(BIGFOOT_BUILD_BENCHMARKS)
SasquatchWriter::SasquatchWriter(const File& p_file,
const std::uint64_t p_assetCount,
const std::size_t p_totalFlatbufferBytes,
const std::size_t p_totalHardReferencesBytes):
m_assetCount(p_assetCount),
m_currentDataOffset(sizeof(SasquatchHeader) + (m_assetCount * sizeof(SasquatchEntry))),
m_file(p_file,
sizeof(SasquatchHeader) + (m_assetCount * sizeof(SasquatchEntry)) + p_totalFlatbufferBytes +
p_totalHardReferencesBytes)
{
m_entries.reserve(m_assetCount);
SasquatchHeader header;
header.m_assetCount = m_assetCount;
std::memcpy(m_file.GetData().data(), &header, sizeof(SasquatchHeader));
}
/****************************************************************************************/
SasquatchWriter::~SasquatchWriter()
{
ASSERT(EngineAssertHandler,
m_entries.size() == m_assetCount,
"SasquatchWriter expected {} assets, only {} were added",
m_assetCount,
m_entries.size());
m_file.Prefetch(sizeof(SasquatchHeader), m_entries.size() * sizeof(SasquatchEntry));
if (!m_entries.empty())
{
std::memcpy(m_file.GetData().data() + sizeof(SasquatchHeader),
m_entries.data(),
m_entries.size() * sizeof(SasquatchEntry));
}
}
/****************************************************************************************/
void SasquatchWriter::WriteAsset(const UUID& p_uuid,
eastl::span<const std::byte> p_flatbuffer,
eastl::span<const UUID> p_hardReferences)
{
ASSERT(EngineAssertHandler,
m_entries.size() < m_assetCount,
"SasquatchWriter can only hold {} assets",
m_assetCount);
const std::size_t offset = m_currentDataOffset;
const eastl::span<std::byte> data = m_file.GetData();
ASSERT(EngineAssertHandler,
offset + p_flatbuffer.size() + (p_hardReferences.size() * UUID::UUID_BYTE_SIZE) <= data.size(),
"SasquatchWriter can only write {} bytes",
data.size());
const std::size_t writeEnd = offset + p_flatbuffer.size() + (p_hardReferences.size() * UUID::UUID_BYTE_SIZE);
if (writeEnd > m_prefetchedUpTo)
{
const std::size_t prefetchEnd = std::min(writeEnd + PREFETCH_BYTES, data.size());
m_file.Prefetch(m_prefetchedUpTo, prefetchEnd - m_prefetchedUpTo);
m_prefetchedUpTo = prefetchEnd;
}
SasquatchEntry entry;
std::memcpy(entry.m_uuid.data(), p_uuid.ToBytes().data(), UUID::UUID_BYTE_SIZE);
entry.m_assetOffset = offset;
entry.m_assetSize = p_flatbuffer.size();
entry.m_hardReferencesOffset = entry.m_assetOffset + entry.m_assetSize;
entry.m_hardReferencesSize = p_hardReferences.size() * UUID::UUID_BYTE_SIZE;
std::memcpy(data.data() + entry.m_assetOffset, p_flatbuffer.data(), entry.m_assetSize);
for (std::uint32_t i = 0; i < p_hardReferences.size(); ++i)
{
const std::span<const std::byte, UUID::UUID_BYTE_SIZE> rawUUID = p_hardReferences[i].ToBytes();
std::memcpy(data.data() + entry.m_hardReferencesOffset + (static_cast<std::size_t>(i) * UUID::UUID_BYTE_SIZE),
rawUUID.data(),
UUID::UUID_BYTE_SIZE);
}
m_currentDataOffset += entry.m_assetSize + entry.m_hardReferencesSize;
m_entries.push_back(entry);
}
/****************************************************************************************/
Sasquatch::Sasquatch(const File& p_file):
m_file(p_file)
{
const eastl::span<const std::byte> data = m_file.GetData();
CRITICAL_ASSERT(EngineAssertHandler,
data.size() >= sizeof(SasquatchHeader),
"Sasquatch file {} is smaller than its header",
p_file.GetPath());
std::memcpy(&m_header, data.data(), sizeof(SasquatchHeader));
CRITICAL_ASSERT(EngineAssertHandler,
m_header.m_magic == SasquatchHeader::MAGIC,
"Sasquatch file {} has an invalid magic number (got {} / expected {})",
p_file.GetPath(),
m_header.m_magic,
SasquatchHeader::MAGIC);
CRITICAL_ASSERT(EngineAssertHandler,
m_header.m_version == SasquatchHeader::VERSION,
"Sasquatch file {} has an unsupported version (got {} / expected {})",
p_file.GetPath(),
m_header.m_version,
SasquatchHeader::VERSION);
CRITICAL_ASSERT(EngineAssertHandler,
data.size() >= sizeof(SasquatchHeader) + (m_header.m_assetCount * sizeof(SasquatchEntry)),
"Sasquatch file {} index is truncated (got {} / expected at least {})",
p_file.GetPath(),
data.size(),
sizeof(SasquatchHeader) + (m_header.m_assetCount * sizeof(SasquatchEntry)));
eastl::vector<SasquatchEntry> entries(m_header.m_assetCount);
if (!entries.empty())
{
std::memcpy(entries.data(), data.data() + sizeof(SasquatchHeader), entries.size() * sizeof(SasquatchEntry));
}
m_entries.reserve(m_header.m_assetCount);
for (const SasquatchEntry& entry: entries)
{
CRITICAL_ASSERT(EngineAssertHandler,
entry.m_assetOffset + entry.m_assetSize + entry.m_hardReferencesSize <= data.size(),
"Sasquatch file {} has an out-of-bounds asset entry",
p_file.GetPath());
m_entries.emplace(UUID {entry.m_uuid},
Entry {.m_assetOffset = entry.m_assetOffset,
.m_assetSize = entry.m_assetSize,
.m_hardReferencesOffset = entry.m_hardReferencesOffset,
.m_hardReferencesSize = entry.m_hardReferencesSize});
}
}
/****************************************************************************************/
const SasquatchHeader& Sasquatch::GetHeader() const
{
return m_header;
}
/****************************************************************************************/
eastl::vector<std::byte> Sasquatch::GetAssetFlatbuffer(const UUID& p_uuid) const
{
const auto entryIt = m_entries.find(p_uuid);
if (entryIt == m_entries.end())
{
return {};
}
const eastl::span<const std::byte> data = m_file.GetData();
const eastl::span<const std::byte> bytes {data.data() + entryIt->second.m_assetOffset,
static_cast<std::size_t>(entryIt->second.m_assetSize)};
return eastl::vector<std::byte> {bytes.begin(), bytes.end()};
}
/****************************************************************************************/
eastl::vector<eastl::vector<std::byte>> Sasquatch::GetAssetFlatbuffers(const eastl::span<const UUID> p_uuids) const
{
eastl::vector<eastl::vector<std::byte>> flatbuffers;
flatbuffers.reserve(p_uuids.size());
for (const UUID& uuid: p_uuids)
{
flatbuffers.push_back(GetAssetFlatbuffer(uuid));
}
return flatbuffers;
}
/****************************************************************************************/
eastl::vector<UUID> Sasquatch::GetAssetHardReferences(const UUID& p_uuid) const
{
eastl::vector<UUID> hardReferences;
const auto entryIt = m_entries.find(p_uuid);
if (entryIt == m_entries.end())
{
return hardReferences;
}
const eastl::span<const std::byte> data = m_file.GetData();
const eastl::span<const std::byte> bytes {data.data() + entryIt->second.m_hardReferencesOffset,
static_cast<std::size_t>(entryIt->second.m_hardReferencesSize)};
const std::size_t hardReferenceCount = bytes.size() / UUID::UUID_BYTE_SIZE;
hardReferences.reserve(hardReferenceCount);
for (std::size_t i = 0; i < hardReferenceCount; ++i)
{
std::array<std::byte, UUID::UUID_BYTE_SIZE> rawUUID;
std::memcpy(rawUUID.data(), bytes.data() + (i * UUID::UUID_BYTE_SIZE), UUID::UUID_BYTE_SIZE);
hardReferences.emplace_back(rawUUID);
}
return hardReferences;
}
/****************************************************************************************/
eastl::vector<eastl::vector<UUID>> Sasquatch::GetAssetsHardReferences(eastl::span<const UUID> p_uuids) const
{
eastl::vector<eastl::vector<UUID>> hardReferences;
hardReferences.reserve(p_uuids.size());
for (const UUID& uuid: p_uuids)
{
hardReferences.push_back(GetAssetHardReferences(uuid));
}
return hardReferences;
}
/****************************************************************************************/
void Sasquatch::SaveAssetFlatbuffer([[maybe_unused]] const UUID& p_uuid,
[[maybe_unused]] eastl::span<const std::byte> p_flatbuffer,
[[maybe_unused]] eastl::span<const UUID> p_hardReferences)
{
ASSERT(EngineAssertHandler, false, "Sasquatch is read-only, it cannot save assets");
}
/****************************************************************************************/
void Sasquatch::SaveAssetFlatbuffers([[maybe_unused]] const eastl::span<const UUID> p_uuids,
[[maybe_unused]] eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
[[maybe_unused]] eastl::span<const eastl::vector<UUID>> p_hardReferences)
{
ASSERT(EngineAssertHandler, false, "Sasquatch is read-only, it cannot save assets");
}
/****************************************************************************************/
bool Sasquatch::Has(const UUID& p_uuid) const
{
return m_entries.contains(p_uuid);
}
#endif
} // namespace Bigfoot
@@ -1,249 +0,0 @@
/*********************************************************************
* \file SerializationManager.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <Engine/SerializationManager/SerializationManager.hpp>
#include <Engine/Asset/AssetLibrary.hpp>
#include <Engine/DataAccessor/DataAccessor.hpp>
#include <Utils/Algorithm/Graph.hpp>
#include <ankerl/unordered_dense.h>
namespace Bigfoot::SerializationManager
{
/*
* Build the transitive HardReference graph reachable from p_roots
*
* \param p_roots The assets to start the discovery from
* \param p_discovered Every discovered asset that isn't already loaded, including p_roots
* \return Every asset's HardReferences
*/
[[nodiscard]]
ankerl::unordered_dense::map<UUID, eastl::vector<UUID>> BuildDependencyGraph(
const eastl::span<const UUID> p_roots,
ankerl::unordered_dense::set<UUID>& p_discovered)
{
ankerl::unordered_dense::map<UUID, eastl::vector<UUID>> graph;
eastl::vector<UUID> toQuery;
toQuery.reserve(p_roots.size());
for (const UUID& uuid: p_roots)
{
if (!g_activeAssetLibrary->IsLoaded(uuid) && p_discovered.insert(uuid).second)
{
toQuery.push_back(uuid);
}
}
while (!toQuery.empty())
{
eastl::vector<eastl::vector<UUID>> hardReferencesBatch = g_dataAccessor->GetAssetsHardReferences(toQuery);
eastl::vector<UUID> nextToQuery;
for (std::size_t i = 0; i < toQuery.size(); ++i)
{
eastl::vector<UUID>& hardReferences = graph[toQuery[i]];
hardReferences = std::move(hardReferencesBatch[i]);
for (const UUID& hardReference: hardReferences)
{
if (!g_activeAssetLibrary->IsLoaded(hardReference) && p_discovered.insert(hardReference).second)
{
nextToQuery.push_back(hardReference);
}
}
}
toQuery = std::move(nextToQuery);
}
return graph;
}
/****************************************************************************************/
void LoadAssets(const eastl::span<const UUID> p_uuids)
{
ankerl::unordered_dense::set<UUID> discovered;
const ankerl::unordered_dense::map<UUID, eastl::vector<UUID>> graph = BuildDependencyGraph(p_uuids, discovered);
// Assets that are part of a cyclic HardReference dependency are left out of waves and simply never loaded.
eastl::vector<eastl::vector<UUID>> waves;
eastl::vector<UUID> cyclicUuids;
std::ignore = LayeredTopologicalSort(graph, discovered, waves, cyclicUuids);
BIGFOOT_LOG_ERROR_IF(!cyclicUuids.empty(),
ENGINE_LOGGER,
"Cyclic HardReference dependency detected while loading assets, involved UUIDs: {}",
cyclicUuids);
// Waves are loaded one after another since a wave's assets may HardReference the previous wave's; within a
// wave, every asset is independent of the others, so this is where loading could later be parallelized.
for (const eastl::vector<UUID>& wave: waves)
{
const eastl::vector<eastl::vector<std::byte>> assetFlatbuffers = g_dataAccessor->GetAssetFlatbuffers(wave);
for (std::size_t i = 0; i < wave.size(); ++i)
{
const eastl::vector<std::byte>& flatbuffer = assetFlatbuffers[i];
if (flatbuffer.empty())
{
BIGFOOT_LOG_ERROR(ENGINE_LOGGER, "Asset {} could not be found while loading, skipping it", wave[i]);
continue;
}
#ifdef BIGFOOT_NOT_OPTIMIZED
flatbuffers::Verifier verifier {reinterpret_cast<const std::uint8_t*>(flatbuffer.data()),
flatbuffer.size()};
const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier);
CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!");
#endif
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(flatbuffer.data());
AssetContainerBase* container = g_activeAssetLibrary->GetAssetContainer(
flatbuffers::UnPack(*asset->header()->type_id()));
CRITICAL_ASSERT(EngineAssertHandler,
container != nullptr,
"No AssetContainer registered for asset {}",
wave[i]);
std::ignore = container->Insert(flatbuffer);
}
}
}
/****************************************************************************************/
void LoadAsset(const UUID& p_uuid)
{
LoadAssets(eastl::span<const UUID> {&p_uuid, 1});
}
/****************************************************************************************/
#ifdef BIGFOOT_TOOLMODE
/*
* Finds the cyclic dependencies that may exist in Assets
*
* \param p_uuids The assets we want to explore
* \param p_hardReferences The HardReferences of p_uuids, matching by index
* \return Every UUID caught in a cyclic dependency
*/
[[nodiscard]]
eastl::vector<UUID> FindCyclicDependencies(const eastl::span<const UUID> p_uuids,
const eastl::span<const eastl::vector<UUID>> p_hardReferences)
{
ankerl::unordered_dense::map<UUID, eastl::vector<UUID>> graph;
ankerl::unordered_dense::set<UUID> discovered;
eastl::vector<UUID> toQuery;
for (std::size_t i = 0; i < p_uuids.size(); ++i)
{
discovered.insert(p_uuids[i]);
graph[p_uuids[i]] = p_hardReferences[i];
}
for (const eastl::vector<UUID>& hardReferences: p_hardReferences)
{
for (const UUID& hardReference: hardReferences)
{
if (discovered.insert(hardReference).second)
{
toQuery.push_back(hardReference);
}
}
}
while (!toQuery.empty())
{
eastl::vector<eastl::vector<UUID>> hardReferencesBatch = g_dataAccessor->GetAssetsHardReferences(toQuery);
eastl::vector<UUID> nextToQuery;
for (std::size_t i = 0; i < toQuery.size(); ++i)
{
eastl::vector<UUID>& hardReferences = graph[toQuery[i]];
hardReferences = std::move(hardReferencesBatch[i]);
for (const UUID& hardReference: hardReferences)
{
if (discovered.insert(hardReference).second)
{
nextToQuery.push_back(hardReference);
}
}
}
toQuery = std::move(nextToQuery);
}
eastl::vector<eastl::vector<UUID>> waves;
eastl::vector<UUID> cyclicUuids;
std::ignore = LayeredTopologicalSort(graph, discovered, waves, cyclicUuids);
return cyclicUuids;
}
/****************************************************************************************/
bool SaveAsset(const UUID& p_uuid)
{
AssetContainerBase* container = g_activeAssetLibrary->GetAssetContainer(p_uuid);
CRITICAL_ASSERT(EngineAssertHandler, container != nullptr, "No AssetContainer registered for asset {}", p_uuid);
const AssetBase* asset = container->AcquireContainerHandle(p_uuid)->GetAsset();
const eastl::vector<std::byte> flatbuffer = asset->Pack();
const eastl::vector<UUID> hardReferences = asset->GetHardReferences(flatbuffer);
const eastl::vector<UUID> cyclicUuids = FindCyclicDependencies(
eastl::span<const UUID> {&p_uuid, 1},
eastl::span<const eastl::vector<UUID>> {&hardReferences, 1});
BIGFOOT_LOG_ERROR_IF(!cyclicUuids.empty(),
ENGINE_LOGGER,
"Cyclic HardReference dependency detected while saving asset {}, involved UUIDs: {}",
p_uuid,
cyclicUuids);
if (!cyclicUuids.empty())
{
return false;
}
g_dataAccessor->SaveAssetFlatbuffer(p_uuid, flatbuffer, hardReferences);
return true;
}
/****************************************************************************************/
bool SaveAssets(const eastl::span<const UUID> p_uuids)
{
eastl::vector<eastl::vector<std::byte>> flatbuffers;
eastl::vector<eastl::vector<UUID>> hardReferences;
flatbuffers.reserve(p_uuids.size());
hardReferences.reserve(p_uuids.size());
for (const UUID& uuid: p_uuids)
{
AssetContainerBase* container = g_activeAssetLibrary->GetAssetContainer(uuid);
CRITICAL_ASSERT(EngineAssertHandler, container != nullptr, "No AssetContainer registered for asset {}", uuid);
const AssetBase* asset = container->AcquireContainerHandle(uuid)->GetAsset();
const eastl::vector<std::byte> flatbuffer = asset->Pack();
flatbuffers.push_back(flatbuffer);
hardReferences.push_back(asset->GetHardReferences(flatbuffer));
}
const eastl::vector<UUID> cyclicUuids = FindCyclicDependencies(p_uuids, hardReferences);
BIGFOOT_LOG_ERROR_IF(!cyclicUuids.empty(),
ENGINE_LOGGER,
"Cyclic HardReference dependency detected while saving assets, involved UUIDs: {}",
cyclicUuids);
if (!cyclicUuids.empty())
{
return false;
}
g_dataAccessor->SaveAssetFlatbuffers(p_uuids, flatbuffers, hardReferences);
return true;
}
#endif
} // namespace Bigfoot::SerializationManager
+5 -4
View File
@@ -8,6 +8,7 @@
#include <System/SystemAssertHandler.hpp> #include <System/SystemAssertHandler.hpp>
#include <bit>
#include <fstream> #include <fstream>
#include <string> #include <string>
@@ -82,7 +83,7 @@ eastl::vector<std::byte> File::Read(const std::size_t p_offset, const std::size_
eastl::vector<std::byte> data; eastl::vector<std::byte> data;
data.resize(p_size); data.resize(p_size);
file.read(reinterpret_cast<char*>(data.data()), static_cast<std::streamsize>(data.size())); file.read(std::bit_cast<char*>(data.data()), static_cast<std::streamsize>(data.size()));
return data; return data;
} }
@@ -99,7 +100,7 @@ void File::Write(const eastl::span<const std::byte> p_data, const std::size_t p_
CRITICAL_ASSERT(SystemAssertHandler, file.is_open(), "Failed to open file {} for writing", path); CRITICAL_ASSERT(SystemAssertHandler, file.is_open(), "Failed to open file {} for writing", path);
file.seekp(static_cast<std::streamoff>(p_offset), std::ios::beg); file.seekp(static_cast<std::streamoff>(p_offset), std::ios::beg);
file.write(reinterpret_cast<const char*>(p_data.data()), static_cast<std::streamsize>(p_data.size())); file.write(std::bit_cast<const char*>(p_data.data()), static_cast<std::streamsize>(p_data.size()));
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -111,8 +112,8 @@ void File::Delete() const
/****************************************************************************************/ /****************************************************************************************/
File::File(std::filesystem::path p_path): File::File(const std::filesystem::path& p_path):
m_path(std::move(p_path)), m_path(p_path),
m_pathString(m_path.string().c_str()) m_pathString(m_path.string().c_str())
{ {
} }
@@ -10,7 +10,7 @@
#include <string> #include <string>
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
#include <Windows.h> #include <Windows.h>
#elif defined BIGFOOT_LINUX #elif defined BIGFOOT_LINUX
#include <fcntl.h> #include <fcntl.h>
@@ -26,7 +26,7 @@ MemoryMappedFile::MemoryMappedFile(const File& p_file)
const File absoluteFile = p_file.ToAbsolute(); const File absoluteFile = p_file.ToAbsolute();
const eastl::string_view path = absoluteFile.GetPath(); const eastl::string_view path = absoluteFile.GetPath();
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
m_fileHandle = CreateFileA(path.data(), m_fileHandle = CreateFileA(path.data(),
GENERIC_READ, GENERIC_READ,
FILE_SHARE_READ, FILE_SHARE_READ,
@@ -78,7 +78,7 @@ MemoryMappedFile::MemoryMappedFile(const File& p_file)
MemoryMappedFile::~MemoryMappedFile() MemoryMappedFile::~MemoryMappedFile()
{ {
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
if (m_data != nullptr) if (m_data != nullptr)
{ {
[[maybe_unused]] [[maybe_unused]]
@@ -133,7 +133,7 @@ WritableMemoryMappedFile::WritableMemoryMappedFile(const File& p_file, const std
const File absoluteFile = p_file.ToAbsolute(); const File absoluteFile = p_file.ToAbsolute();
const eastl::string_view path = absoluteFile.GetPath(); const eastl::string_view path = absoluteFile.GetPath();
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
m_fileHandle = m_fileHandle =
CreateFileA(path.data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); CreateFileA(path.data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
CRITICAL_ASSERT(SystemAssertHandler, m_fileHandle != INVALID_HANDLE_VALUE, "Failed to create file {}", path); CRITICAL_ASSERT(SystemAssertHandler, m_fileHandle != INVALID_HANDLE_VALUE, "Failed to create file {}", path);
@@ -169,7 +169,7 @@ WritableMemoryMappedFile::WritableMemoryMappedFile(const File& p_file, const std
WritableMemoryMappedFile::~WritableMemoryMappedFile() WritableMemoryMappedFile::~WritableMemoryMappedFile()
{ {
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
if (m_data != nullptr) if (m_data != nullptr)
{ {
[[maybe_unused]] [[maybe_unused]]
@@ -220,7 +220,7 @@ eastl::span<std::byte> WritableMemoryMappedFile::GetData() const
void WritableMemoryMappedFile::Prefetch(const std::size_t p_offset, const std::size_t p_size) const void WritableMemoryMappedFile::Prefetch(const std::size_t p_offset, const std::size_t p_size) const
{ {
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
WIN32_MEMORY_RANGE_ENTRY range {.VirtualAddress = m_data + p_offset, .NumberOfBytes = p_size}; WIN32_MEMORY_RANGE_ENTRY range {.VirtualAddress = m_data + p_offset, .NumberOfBytes = p_size};
[[maybe_unused]] [[maybe_unused]]
const BOOL prefetched = PrefetchVirtualMemory(GetCurrentProcess(), 1, &range, 0); const BOOL prefetched = PrefetchVirtualMemory(GetCurrentProcess(), 1, &range, 0);
@@ -112,7 +112,7 @@ class File
* *
* \param p_path The path * \param p_path The path
*/ */
File(std::filesystem::path p_path); File(const std::filesystem::path& p_path);
/** /**
* The path * The path
@@ -47,7 +47,7 @@ class MemoryMappedFile
MemoryMappedFile& operator=(MemoryMappedFile&& p_file) = delete; MemoryMappedFile& operator=(MemoryMappedFile&& p_file) = delete;
private: private:
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
/** /**
* Handle to the file * Handle to the file
*/ */
@@ -118,7 +118,7 @@ class WritableMemoryMappedFile
WritableMemoryMappedFile& operator=(WritableMemoryMappedFile&& p_file) = delete; WritableMemoryMappedFile& operator=(WritableMemoryMappedFile&& p_file) = delete;
private: private:
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
/** /**
* Handle to the file * Handle to the file
*/ */
@@ -10,7 +10,7 @@
#include <Utils/Assert/AssertHandler.hpp> #include <Utils/Assert/AssertHandler.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot namespace Bigfoot
{ {
@@ -15,7 +15,7 @@ namespace Bigfoot
/* /*
* Logger * Logger
*/ */
inline Log::LoggerInfo SYSTEM_LOGGER { .m_name = "SYSTEM_LOGGER", .m_level = Flat::LogLevel::Trace}; inline Log::LoggerInfo SYSTEM_LOGGER {"SYSTEM_LOGGER", Flat::LogLevel::Trace};
} // namespace Bigfoot } // namespace Bigfoot
#endif #endif
#endif #endif
@@ -65,10 +65,13 @@ class Time
/****************************************************************************************/ /****************************************************************************************/
namespace Flat::Bigfoot namespace Flat
{
namespace Bigfoot
{ {
struct Time; struct Time;
} // namespace Flat::Bigfoot }
} // namespace Flat
/****************************************************************************************/ /****************************************************************************************/
@@ -6,7 +6,6 @@
*********************************************************************/ *********************************************************************/
#ifndef BIGFOOT_SYSTEM_UUID_UUID_HPP #ifndef BIGFOOT_SYSTEM_UUID_UUID_HPP
#define BIGFOOT_SYSTEM_UUID_UUID_HPP #define BIGFOOT_SYSTEM_UUID_UUID_HPP
#include <EASTL/string.h>
#include <ankerl/unordered_dense.h> #include <ankerl/unordered_dense.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <uuid.h> #include <uuid.h>
@@ -53,7 +52,7 @@ class UUID
* \return A string representing the UUID * \return A string representing the UUID
*/ */
[[nodiscard]] [[nodiscard]]
eastl::string ToString() const; std::string ToString() const;
operator bool() const; operator bool() const;
@@ -121,33 +120,33 @@ struct std::hash<Bigfoot::UUID>
template<> template<>
struct fmt::formatter<Bigfoot::UUID> struct fmt::formatter<Bigfoot::UUID>
{ {
static constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
return ctx.begin(); return ctx.begin();
} }
static auto format(const Bigfoot::UUID& p_uuid, format_context& ctx) auto format(const Bigfoot::UUID& p_uuid, format_context& ctx) const
{ {
return fmt::format_to(ctx.out(), "{}", p_uuid.ToString().c_str()); return fmt::format_to(ctx.out(), "{}", p_uuid.ToString());
} }
}; };
/****************************************************************************************/ /****************************************************************************************/
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
#include <quill/DeferredFormatCodec.h> #include <quill/DeferredFormatCodec.h>
template<> template<>
struct fmtquill::formatter<Bigfoot::UUID> struct fmtquill::formatter<Bigfoot::UUID>
{ {
static constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
return ctx.begin(); return ctx.begin();
} }
static auto format(const Bigfoot::UUID& p_uuid, format_context& ctx) auto format(const Bigfoot::UUID& p_uuid, format_context& ctx) const
{ {
return fmtquill::format_to(ctx.out(), "{}", p_uuid.ToString().c_str()); return fmtquill::format_to(ctx.out(), "{}", p_uuid.ToString());
} }
}; };
@@ -159,10 +158,13 @@ struct quill::Codec<Bigfoot::UUID>: quill::DeferredFormatCodec<Bigfoot::UUID>
/****************************************************************************************/ /****************************************************************************************/
namespace Flat::Bigfoot namespace Flat
{
namespace Bigfoot
{ {
struct UUID; struct UUID;
} // namespace Flat::Bigfoot }
} // namespace Flat
/****************************************************************************************/ /****************************************************************************************/
+1 -2
View File
@@ -57,8 +57,7 @@ Time::Time(const std::uint64_t p_epoch):
std::uint32_t Time::GetYear() const std::uint32_t Time::GetYear() const
{ {
constexpr std::uint32_t TM_YEAR_EPOCH = 1900; return m_timeInfo.tm_year + 1900;
return m_timeInfo.tm_year + TM_YEAR_EPOCH;
} }
/****************************************************************************************/ /****************************************************************************************/
+3 -4
View File
@@ -35,7 +35,7 @@ UUID::UUID(const std::string_view p_string):
UUID::UUID(const std::span<const std::byte, UUID_BYTE_SIZE> p_raw) UUID::UUID(const std::span<const std::byte, UUID_BYTE_SIZE> p_raw)
{ {
const std::span<std::uint8_t, UUID_BYTE_SIZE> raw { const std::span<std::uint8_t, UUID_BYTE_SIZE> raw {
const_cast<std::uint8_t*>(reinterpret_cast<const std::uint8_t*>(p_raw.data())), const_cast<std::uint8_t*>(std::bit_cast<const std::uint8_t*>(p_raw.data())),
UUID_BYTE_SIZE}; UUID_BYTE_SIZE};
m_uuid = uuids::uuid {raw}; m_uuid = uuids::uuid {raw};
@@ -50,10 +50,9 @@ std::span<const std::byte, UUID::UUID_BYTE_SIZE> UUID::ToBytes() const
/****************************************************************************************/ /****************************************************************************************/
eastl::string UUID::ToString() const std::string UUID::ToString() const
{ {
const std::string uuid = uuids::to_string(m_uuid); return uuids::to_string(m_uuid);
return eastl::string {uuid.data(), uuid.size()};
} }
/****************************************************************************************/ /****************************************************************************************/
-2
View File
@@ -1,2 +0,0 @@
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/SasquatchBaker)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Executables/SasquatchBaker)
@@ -1,33 +0,0 @@
project(SasquatchBakerCLI)
add_executable(${PROJECT_NAME})
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_link_libraries(${PROJECT_NAME}
PRIVATE
BigfootCompileAndLinkFlags
bfg::lyra
$<LINK_LIBRARY:WHOLE_ARCHIVE,SasquatchBaker>)
file(GLOB_RECURSE _SOURCES
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
file(GLOB_RECURSE _HEADERS
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
)
target_sources(${PROJECT_NAME}
PRIVATE
${_SOURCES}
${_HEADERS}
)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${_SOURCES} ${_HEADERS})
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bigfoot/Tools/Executables)
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME SasquatchBaker)
@@ -1,50 +0,0 @@
/*********************************************************************
* \file main.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <System/File/File.hpp>
#include <Utils/Log/LogMacros.hpp>
#include <Utils/TargetMacros.h>
#include <SasquatchBaker/SasquatchBaker.hpp>
#include <EASTL/string_view.h>
#include <lyra/lyra.hpp>
#include <iostream>
#include <string>
int main(int argc, char** argv)
{
BIGFOOT_NOT_OPTIMIZED_ONLY(::Bigfoot::Singleton<::Bigfoot::Log>::Lifetime logLifetime);
bool showHelp = false;
std::string bigFilePath;
std::string outputPath;
const auto& cli = lyra::help(showHelp) |
lyra::opt(bigFilePath, "bigfile")["-b"]["--bigfile"]("The BigFile to bake (must exist)")
.required() |
lyra::opt(outputPath, "output")["-o"]["--output"]("The Sasquatch file to write").required();
const lyra::parse_result result = cli.parse({argc, argv});
if (!result)
{
std::cerr << result.message() << "\n\n" << cli << '\n';
return 1;
}
if (showHelp)
{
std::cout << cli << '\n';
return 0;
}
const Bigfoot::BigFile bigFile {Bigfoot::File {eastl::string_view {bigFilePath.c_str()}}};
Bigfoot::Bake(bigFile, Bigfoot::File {eastl::string_view {outputPath.c_str()}});
return 0;
}
@@ -1,18 +0,0 @@
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName})
set(PublicDependencies)
set(PrivateDependencies)
set(BigfootPublicDependencies
Engine)
set(BigfootPrivateDependencies
Utils)
bigfoot_create_package_lib(
"${PublicDependencies}"
"${PrivateDependencies}"
"${BigfootPublicDependencies}"
"${BigfootPrivateDependencies}"
"Tools")
bigfoot_create_logger()
@@ -1,24 +0,0 @@
/*********************************************************************
* \file SasquatchBaker.hpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#ifndef BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKER_HPP
#define BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKER_HPP
#include <Engine/BigFile/BigFile.hpp>
#include <System/File/File.hpp>
namespace Bigfoot
{
/**
* Bake every Asset of a BigFile into a Sasquatch file
*
* \param p_bigFile The BigFile to bake
* \param p_outputFile The file to write to
*/
void Bake(const BigFile& p_bigFile, const File& p_outputFile);
} // namespace Bigfoot
#endif
@@ -1,20 +0,0 @@
/*********************************************************************
* \file SasquatchBakerAssertHandler.hpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#ifndef BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKERASSERTHANDLER_HPP
#define BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKERASSERTHANDLER_HPP
#include <Utils/Assert/AssertHandler.hpp>
#include <SasquatchBaker/SasquatchBakerLogger_generated.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot
{
using SasquatchBakerAssertHandler = AssertHandler<SASQUATCHBAKER_LOGGER>;
} // namespace Bigfoot
#endif
#endif
@@ -1,21 +0,0 @@
// AUTO-GENERATED DO NOT TOUCH
/*********************************************************************
* \file SasquatchBakerLogger.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_SASQUATCHBAKERLOGGER_GENERATED_HPP
#define BIGFOOT_SASQUATCHBAKERLOGGER_GENERATED_HPP
#include <Utils/Log/LogMacros.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot
{
/*
* Logger
*/
inline Log::LoggerInfo SASQUATCHBAKER_LOGGER { .m_name = "SASQUATCHBAKER_LOGGER", .m_level = Flat::LogLevel::Trace};
} // namespace Bigfoot
#endif
#endif
@@ -1,65 +0,0 @@
/*********************************************************************
* \file SasquatchBaker.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <SasquatchBaker/SasquatchBaker.hpp>
#include <Engine/Sasquatch/Sasquatch.hpp>
#include <SasquatchBaker/SasquatchBakerAssertHandler.hpp>
namespace Bigfoot
{
void Bake(const BigFile& p_bigFile, const File& p_outputFile)
{
std::uint64_t assetCount = 0;
{
BigFile::Request countRequest {p_bigFile, "SELECT COUNT(*) FROM Asset;"};
[[maybe_unused]]
const bool hasCount = countRequest.Step();
ASSERT(SasquatchBakerAssertHandler, hasCount, "Failed to count the assets of the BigFile");
assetCount = countRequest.Get(0);
}
std::uint64_t totalFlatbufferBytes = 0;
{
BigFile::Request sizeRequest {p_bigFile, "SELECT COALESCE(SUM(LENGTH(Asset)), 0) FROM Asset;"};
[[maybe_unused]]
const bool hasSize = sizeRequest.Step();
ASSERT(SasquatchBakerAssertHandler, hasSize, "Failed to sum the asset sizes of the BigFile");
totalFlatbufferBytes = sizeRequest.Get(0);
}
std::uint64_t totalHardReferencesBytes = 0;
{
BigFile::Request sizeRequest {p_bigFile,
"SELECT COALESCE(SUM(LENGTH(HardReference)), 0) FROM AssetHardReference;"};
[[maybe_unused]]
const bool hasSize = sizeRequest.Step();
ASSERT(SasquatchBakerAssertHandler, hasSize, "Failed to sum the hardreferences sizes of the BigFile");
totalHardReferencesBytes = sizeRequest.Get(0);
}
SasquatchWriter writer {p_outputFile, assetCount, totalFlatbufferBytes, totalHardReferencesBytes};
BigFile::Request request {p_bigFile, "SELECT UUID FROM Asset;"};
while (request.Step())
{
const std::span<const std::byte> rawUUID = request.Get(0);
ASSERT(SasquatchBakerAssertHandler,
rawUUID.size() == UUID::UUID_BYTE_SIZE,
"Unexpected UUID blob size in BigFile (got {} / expected {})",
rawUUID.size(),
UUID::UUID_BYTE_SIZE);
const UUID uuid {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {rawUUID.data(), UUID::UUID_BYTE_SIZE}};
const eastl::vector<std::byte> flatbuffer = p_bigFile.GetAssetFlatbuffer(uuid);
const eastl::vector<UUID> hardReferences = p_bigFile.GetAssetHardReferences(uuid);
writer.WriteAsset(uuid, flatbuffer, hardReferences);
}
}
} // namespace Bigfoot
@@ -1,154 +0,0 @@
/*********************************************************************
* \file Graph.hpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#ifndef BIGFOOT_UTILS_ALGORITHM_GRAPH_HPP
#define BIGFOOT_UTILS_ALGORITHM_GRAPH_HPP
#include <Utils/UtilsAssertHandler.hpp>
#include <EASTL/vector.h>
#include <ankerl/unordered_dense.h>
#include <cstdint>
#include <limits>
namespace Bigfoot
{
/*
* Kahn's algorithm
*
* \param p_graph Every discovered node's outgoing edges (eg: its dependencies)
* \param p_nodes The set of nodes to sort
* \param p_waves The sorted nodes
* \param p_cyclicNodes Nodes that could not be sorted (ie: part of a cycle)
* \return True if a cycle was found
*/
template<class NODE_TYPE>
[[nodiscard]]
bool LayeredTopologicalSort(const ankerl::unordered_dense::map<NODE_TYPE, eastl::vector<NODE_TYPE>>& p_graph,
const ankerl::unordered_dense::set<NODE_TYPE>& p_nodes,
eastl::vector<eastl::vector<NODE_TYPE>>& p_waves,
eastl::vector<NODE_TYPE>& p_cyclicNodes)
{
ASSERT(UtilsAssertHandler, p_waves.empty(), "p_waves must be empty");
ASSERT(UtilsAssertHandler, p_cyclicNodes.empty(), "p_cyclicNodes must be empty");
ASSERT(UtilsAssertHandler,
p_nodes.size() <= std::numeric_limits<std::uint32_t>::max(),
"Can't sort more than {} nodes",
std::numeric_limits<std::uint32_t>::max());
const auto nodeCount = static_cast<std::uint32_t>(p_nodes.size());
ankerl::unordered_dense::map<NODE_TYPE, std::uint32_t> nodeToIndex;
nodeToIndex.reserve(nodeCount);
eastl::vector<NODE_TYPE> indexToNode;
indexToNode.reserve(nodeCount);
for (const NODE_TYPE& node: p_nodes)
{
nodeToIndex.emplace(node, static_cast<std::uint32_t>(indexToNode.size()));
indexToNode.push_back(node);
}
// Step 1: Compute in-degree for each node
eastl::vector<std::uint32_t> inDegree(nodeCount, 0);
// Reverse adjacency (which nodes depend on each node) stored as CSR: adjacencyOffsets[i]..adjacencyOffsets[i + 1]
// is node i's slice of adjacency. Built in two passes (count listeners per node, then fill) so the whole
// structure is a couple of flat allocations instead of one per node.
eastl::vector<std::uint32_t> adjacencyOffsets(nodeCount + 1, 0);
// Initialize queue with nodes having in-degree 0
eastl::vector<std::uint32_t> queue;
queue.reserve(nodeCount);
for (std::uint32_t index = 0; index < nodeCount; ++index)
{
std::uint32_t degree = 0;
for (const NODE_TYPE& edge: p_graph.at(indexToNode[index]))
{
const auto nodeIt = nodeToIndex.find(edge);
if (nodeIt != nodeToIndex.end())
{
++degree;
++adjacencyOffsets[nodeIt->second + 1];
}
}
inDegree[index] = degree;
if (degree == 0)
{
queue.push_back(index);
}
}
for (std::uint32_t index = 0; index < nodeCount; ++index)
{
adjacencyOffsets[index + 1] += adjacencyOffsets[index];
}
eastl::vector<std::uint32_t> adjacency(adjacencyOffsets.back());
eastl::vector<std::uint32_t> cursor(adjacencyOffsets.begin(), adjacencyOffsets.end() - 1);
for (std::uint32_t index = 0; index < nodeCount; ++index)
{
for (const NODE_TYPE& edge: p_graph.at(indexToNode[index]))
{
const auto nodeIt = nodeToIndex.find(edge);
if (nodeIt != nodeToIndex.end())
{
adjacency[cursor[nodeIt->second]++] = index;
}
}
}
// Step 2: Process nodes
std::size_t resolvedCount = 0;
eastl::vector<std::uint32_t> nextQueue;
nextQueue.reserve(nodeCount);
while (!queue.empty())
{
resolvedCount += queue.size();
// Reduce in-degree for neighbors
nextQueue.clear();
for (const std::uint32_t index: queue)
{
for (std::uint32_t i = adjacencyOffsets[index]; i < adjacencyOffsets[index + 1]; ++i)
{
const std::uint32_t next = adjacency[i];
if (--inDegree[next] == 0)
{
nextQueue.push_back(next);
}
}
}
eastl::vector<NODE_TYPE> waveNodes;
waveNodes.reserve(queue.size());
for (const std::uint32_t index: queue)
{
waveNodes.push_back(indexToNode[index]);
}
p_waves.push_back(std::move(waveNodes));
queue.swap(nextQueue);
}
// Step 3 & 4: Check for valid topological order
if (resolvedCount != nodeCount)
{
p_cyclicNodes.reserve(nodeCount - resolvedCount);
for (std::uint32_t index = 0; index < nodeCount; ++index)
{
if (inDegree[index] != 0)
{
p_cyclicNodes.push_back(indexToNode[index]);
}
}
}
return resolvedCount != nodeCount;
}
} // namespace Bigfoot
#endif
@@ -7,23 +7,26 @@
#ifndef BIGFOOT_UTILS_ASSERT_HPP #ifndef BIGFOOT_UTILS_ASSERT_HPP
#define BIGFOOT_UTILS_ASSERT_HPP #define BIGFOOT_UTILS_ASSERT_HPP
#include <Utils/Log/LogMacros.hpp> #include <Utils/Log/LogMacros.hpp>
#include <Utils/TargetMacros.h>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
#include <Utils/Format.hpp>
#include <EASTL/fixed_function.h>
#include <EASTL/string.h>
#include <cstdlib>
#include <source_location> #include <source_location>
#include <string>
#ifdef BIGFOOT_LINUX #if defined BIGFOOT_LINUX
#include <csignal> #include <csignal>
#endif #endif
#ifdef BIGFOOT_WINDOWS #define BIGFOOT_FLUSH_LOG \
do \
{ \
if (Bigfoot::Singleton<Bigfoot::Log>::HasInstance()) \
{ \
Bigfoot::Singleton<Bigfoot::Log>::GetInstance().Flush(); \
} \
} while (false)
#if defined BIGFOOT_WINDOWS
#define BREAK \ #define BREAK \
do \ do \
{ \ { \
@@ -39,68 +42,39 @@
} while (false) } while (false)
#endif #endif
namespace Bigfoot
{
/**
* Assert then break
*
* \param p_condition The condition to check
* \param p_message A function that will return the formatting string describing the issue
* \param p_location The location the assert originates from
*/
template<typename HANDLER>
BIGFOOT_ALWAYS_INLINE void AssertCheck(const bool p_condition,
const eastl::fixed_function<32, eastl::string()>& p_messageFn,
const std::source_location p_location = std::source_location::current())
{
if (!p_condition) [[unlikely]]
{
HANDLER::Handle(p_location, p_messageFn());
BREAK;
}
}
/**
* Assert then break then kill
*
* \param p_condition The condition to check
* \param p_message A function that will return the formatting string describing the issue
* \param p_location The location the assert originates from
*/
template<typename HANDLER>
BIGFOOT_ALWAYS_INLINE void CriticalAssertCheck(const bool p_condition,
const eastl::fixed_function<32, eastl::string()>& p_messageFn,
const std::source_location p_location = std::source_location::current())
{
if (!p_condition) [[unlikely]]
{
HANDLER::Handle(p_location, p_messageFn());
BREAK;
std::abort();
}
}
} // namespace Bigfoot
#define ASSERT(HANDLER, p_assert, p_message, ...) \ #define ASSERT(HANDLER, p_assert, p_message, ...) \
::Bigfoot::AssertCheck<HANDLER>((p_assert), \ do \
[&] \ { \
{ \ constexpr std::source_location location = std::source_location::current(); \
return ::Bigfoot::Format(p_message __VA_OPT__(, ) __VA_ARGS__); \ if (!(p_assert)) [[unlikely]] \
}) { \
HANDLER::Handle(location, p_message __VA_OPT__(, ) __VA_ARGS__); \
BREAK; \
} \
} while (false)
#define SOFT_ASSERT(HANDLER, p_assert, p_message, ...) \ #define SOFT_ASSERT(HANDLER, p_assert, p_message, ...) \
::Bigfoot::AssertCheck<HANDLER>((p_assert), \ do \
[&] \ { \
{ \ constexpr std::source_location location = std::source_location::current(); \
return ::Bigfoot::Format(p_message __VA_OPT__(, ) __VA_ARGS__); \ if (!(p_assert)) [[unlikely]] \
}) { \
HANDLER::Handle(location, p_message __VA_OPT__(, ) __VA_ARGS__); \
BREAK; \
} \
} while (false)
#define CRITICAL_ASSERT(HANDLER, p_assert, p_message, ...) \ #define CRITICAL_ASSERT(HANDLER, p_assert, p_message, ...) \
::Bigfoot::CriticalAssertCheck<HANDLER>((p_assert), \ do \
[&] \ { \
{ \ constexpr std::source_location location = std::source_location::current(); \
return ::Bigfoot::Format(p_message __VA_OPT__(, ) __VA_ARGS__); \ if (!(p_assert)) [[unlikely]] \
}) { \
HANDLER::Handle(location, p_message __VA_OPT__(, ) __VA_ARGS__); \
BREAK; \
std::abort(); \
} \
} while (false)
#else #else
#define ASSERT(HANDLER, p_assert, p_message, ...) #define ASSERT(HANDLER, p_assert, p_message, ...)
@@ -9,9 +9,9 @@
#include <Utils/Assert/Assert.hpp> #include <Utils/Assert/Assert.hpp>
#include <Utils/Log/Log.hpp> #include <Utils/Log/Log.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
#include <EASTL/string.h> #include <fmt/format.h>
#include <source_location> #include <source_location>
@@ -32,13 +32,15 @@ class AssertHandler
* Handle an assertion. * Handle an assertion.
* *
* \param p_location Location of the assertion. * \param p_location Location of the assertion.
* \param p_message Message describing the assertion failure. * \param p_format Format string for the assertion message.
* \param p_args Arguments for the format string.
*/ */
static void Handle(const std::source_location& p_location, const eastl::string& p_message) template<typename... ARGS>
static void Handle(const std::source_location& p_location, fmt::format_string<ARGS...> p_format, ARGS&&... p_args)
{ {
BIGFOOT_LOG_FATAL(LOGGER, BIGFOOT_LOG_FATAL(LOGGER,
"Assert: {} (File:{}, Line:{}, Function:{}\n", "Assert: {} (File:{}, Line:{}, Function:{}\n",
p_message, fmt::format(p_format, std::forward<ARGS>(p_args)...),
p_location.file_name(), p_location.file_name(),
p_location.line(), p_location.line(),
p_location.function_name()); p_location.function_name());
+13 -9
View File
@@ -6,33 +6,37 @@
*********************************************************************/ *********************************************************************/
#ifndef BIGFOOT_UTILS_CASTER_HPP #ifndef BIGFOOT_UTILS_CASTER_HPP
#define BIGFOOT_UTILS_CASTER_HPP #define BIGFOOT_UTILS_CASTER_HPP
#include <type_traits> #include <EASTL/type_traits.h>
namespace Bigfoot namespace Bigfoot
{ {
template<class TO, class FROM> template<class TO,
requires(std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>) class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr TO* Cast(FROM* p_object) constexpr TO* Cast(FROM* p_object)
{ {
return static_cast<TO*>(p_object); return static_cast<TO*>(p_object);
} }
template<class TO, class FROM> template<class TO,
requires(std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>) class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr const TO* Cast(const FROM* p_object) constexpr const TO* Cast(const FROM* p_object)
{ {
return static_cast<const TO*>(p_object); return static_cast<const TO*>(p_object);
} }
template<class TO, class FROM> template<class TO,
requires(std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>) class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr TO& Cast(FROM& p_object) constexpr TO& Cast(FROM& p_object)
{ {
return static_cast<TO&>(p_object); return static_cast<TO&>(p_object);
} }
template<class TO, class FROM> template<class TO,
requires(std::is_base_of_v<FROM, TO> || std::is_base_of_v<TO, FROM>) class FROM,
eastl::enable_if_t<eastl::is_base_of_v<FROM, TO> || eastl::is_base_of_v<TO, FROM>, bool> = true>
constexpr const TO& Cast(const FROM& p_object) constexpr const TO& Cast(const FROM& p_object)
{ {
return static_cast<const TO&>(p_object); return static_cast<const TO&>(p_object);
@@ -28,7 +28,7 @@ class SlotMapKey
private: private:
static constexpr std::uint32_t VERSION_BIT_COUNT = sizeof(VersionType) * std::numeric_limits<unsigned char>::digits; static constexpr std::uint32_t VERSION_BIT_COUNT = sizeof(VersionType) * std::numeric_limits<unsigned char>::digits;
static constexpr std::uint32_t INDEX_BIT_COUNT = sizeof(IndexType) * std::numeric_limits<unsigned char>::digits; static constexpr std::uint32_t INDEX_BIT_COUNT = sizeof(IndexType) * std::numeric_limits<unsigned char>::digits;
static_assert(VERSION_BIT_COUNT + INDEX_BIT_COUNT <= std::numeric_limits<std::uint64_t>::digits, static_assert(VERSION_BIT_COUNT + INDEX_BIT_COUNT <= 64,
"We cant construct a 64 bit key from the given Version and Index types!"); "We cant construct a 64 bit key from the given Version and Index types!");
static constexpr std::uint64_t INDEX_MASK = (static_cast<std::uint64_t>(1) << INDEX_BIT_COUNT) - 1; static constexpr std::uint64_t INDEX_MASK = (static_cast<std::uint64_t>(1) << INDEX_BIT_COUNT) - 1;
@@ -115,10 +115,10 @@ class DenseSlotMap
public: public:
using SlotMapKey = SLOT_MAP_KEY_TYPE; using SlotMapKey = SLOT_MAP_KEY_TYPE;
using iterator = eastl::vector<T>::iterator; using iterator = typename eastl::vector<T>::iterator;
using const_iterator = eastl::vector<T>::const_iterator; using const_iterator = typename eastl::vector<T>::const_iterator;
using reverse_iterator = eastl::vector<T>::reverse_iterator; using reverse_iterator = typename eastl::vector<T>::reverse_iterator;
using const_reverse_iterator = eastl::vector<T>::const_reverse_iterator; using const_reverse_iterator = typename eastl::vector<T>::const_reverse_iterator;
/** /**
* Check if the map has the key * Check if the map has the key
@@ -402,6 +402,7 @@ class DenseSlotMap
m_freeListHead = p_key.GetIndex(); m_freeListHead = p_key.GetIndex();
} }
private:
/** /**
* The actual storage for our data * The actual storage for our data
*/ */
@@ -430,13 +431,12 @@ class DenseSlotMap
template<class T, class SLOT_MAP_KEY_TYPE = SlotMapKey<>> template<class T, class SLOT_MAP_KEY_TYPE = SlotMapKey<>>
class StableSlotMap class StableSlotMap
{ {
public: private:
static constexpr std::size_t PAGE_SIZE = 64; static constexpr std::size_t PAGE_SIZE = 64;
private:
struct AlignedSlot struct AlignedSlot
{ {
alignas(T) eastl::array<std::byte, sizeof(T)> m_bytes; alignas(T) std::byte m_bytes[sizeof(T)];
}; };
struct Page struct Page
@@ -467,8 +467,7 @@ class StableSlotMap
T* Get(const std::size_t p_offset) T* Get(const std::size_t p_offset)
{ {
ASSERT(UtilsAssertHandler, m_occupied[p_offset], "Requesting a dead data!"); ASSERT(UtilsAssertHandler, m_occupied[p_offset], "Requesting a dead data!");
void* const bytes = m_data[p_offset].m_bytes.data(); return std::launder(reinterpret_cast<T*>(m_data[p_offset].m_bytes));
return std::launder(static_cast<T*>(bytes));
} }
/** /**
@@ -480,8 +479,7 @@ class StableSlotMap
const T* Get(const std::size_t p_offset) const const T* Get(const std::size_t p_offset) const
{ {
ASSERT(UtilsAssertHandler, m_occupied[p_offset], "Requesting a dead data!"); ASSERT(UtilsAssertHandler, m_occupied[p_offset], "Requesting a dead data!");
const void* const bytes = m_data[p_offset].m_bytes.data(); return std::launder(reinterpret_cast<const T*>(m_data[p_offset].m_bytes));
return std::launder(static_cast<const T*>(bytes));
} }
/** /**
@@ -529,8 +527,7 @@ class StableSlotMap
IteratorImpl() = default; IteratorImpl() = default;
// Allows an iterator to be implicitly used as a const_iterator. // Allows an iterator to be implicitly used as a const_iterator.
template<class OTHER_VALUE_TYPE> template<class OTHER_VALUE_TYPE, class = std::enable_if_t<std::is_same_v<VALUE_TYPE, const OTHER_VALUE_TYPE>>>
requires std::is_same_v<VALUE_TYPE, const OTHER_VALUE_TYPE>
IteratorImpl(const IteratorImpl<OTHER_VALUE_TYPE>& p_other): IteratorImpl(const IteratorImpl<OTHER_VALUE_TYPE>& p_other):
m_map(p_other.m_map), m_map(p_other.m_map),
m_pageIt(p_other.m_pageIt), m_pageIt(p_other.m_pageIt),
@@ -780,7 +777,7 @@ class StableSlotMap
Page* const page = GetPageAt(pageIndex); Page* const page = GetPageAt(pageIndex);
const std::size_t offsetInPage = GetDataOffset(key); const std::size_t offsetInPage = GetDataOffset(key);
new (page->m_data[offsetInPage].m_bytes.data()) T(std::forward<ARGS>(p_args)...); new (page->m_data[offsetInPage].m_bytes) T(std::forward<ARGS>(p_args)...);
page->m_occupied.set(offsetInPage); page->m_occupied.set(offsetInPage);
return key; return key;
@@ -838,7 +835,7 @@ class StableSlotMap
{ {
std::destroy_at(page->Get(offset)); std::destroy_at(page->Get(offset));
const std::size_t keyIndex = (pageIndex * PAGE_SIZE) + offset; const std::size_t keyIndex = pageIndex * PAGE_SIZE + offset;
RecycleKey(SlotMapKey {m_keys[keyIndex].GetVersion(), static_cast<SlotMapKey::IndexType>(keyIndex)}); RecycleKey(SlotMapKey {m_keys[keyIndex].GetVersion(), static_cast<SlotMapKey::IndexType>(keyIndex)});
} }
page->m_occupied.reset(); page->m_occupied.reset();
@@ -873,9 +870,9 @@ class StableSlotMap
[[nodiscard]] [[nodiscard]]
iterator begin() iterator begin()
{ {
iterator result {this}; iterator it {this};
result.SeekFirstFrom(m_pages.begin()); it.SeekFirstFrom(m_pages.begin());
return result; return it;
} }
[[nodiscard]] [[nodiscard]]
@@ -887,9 +884,9 @@ class StableSlotMap
[[nodiscard]] [[nodiscard]]
const_iterator begin() const const_iterator begin() const
{ {
const_iterator result {this}; const_iterator it {this};
result.SeekFirstFrom(m_pages.begin()); it.SeekFirstFrom(m_pages.begin());
return result; return it;
} }
[[nodiscard]] [[nodiscard]]
@@ -1027,6 +1024,7 @@ class StableSlotMap
return m_pages[p_pageIndex].get(); return m_pages[p_pageIndex].get();
} }
private:
/** /**
* The pages * The pages
*/ */
@@ -1,31 +0,0 @@
/*********************************************************************
* \file Format.hpp
*
* \author Romain BOULLARD
* \date September 2026
*********************************************************************/
#ifndef BIGFOOT_UTILS_FORMAT_HPP
#define BIGFOOT_UTILS_FORMAT_HPP
#include <EASTL/string.h>
#include <fmt/format.h>
#include <iterator>
namespace Bigfoot
{
/**
* Format a string, like fmt::format, but returning an eastl::string instead of a std::string.
*
* \param p_format The format string
* \param p_args The arguments for the format string
* \return The formatted eastl::string
*/
template<typename... ARGS>
eastl::string Format(fmt::format_string<ARGS...> p_format, ARGS&&... p_args)
{
fmt::memory_buffer buffer;
fmt::format_to(std::back_inserter(buffer), p_format, std::forward<ARGS>(p_args)...);
return eastl::string {buffer.data(), buffer.size()};
}
} // namespace Bigfoot
#endif
@@ -8,43 +8,40 @@
#define BIGFOOT_UTILS_LOG_EASTLFORMATTERS_HPP #define BIGFOOT_UTILS_LOG_EASTLFORMATTERS_HPP
#include <Utils/TargetMacros.h> #include <Utils/TargetMacros.h>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined(BIGFOOT_NOT_OPTIMIZED)
#include <quill/core/Codec.h> #include <quill/core/Codec.h>
#endif #endif
#include <EASTL/string.h> #include <EASTL/string.h>
#include <EASTL/string_view.h> #include <EASTL/string_view.h>
#include <EASTL/vector.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <cstddef>
// STRING // STRING
template<> template<>
struct fmt::formatter<eastl::string> struct fmt::formatter<eastl::string>
{ {
static constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
return ctx.begin(); return ctx.begin();
} }
static auto format(const eastl::string& p_string, format_context& ctx) auto format(const eastl::string& p_string, format_context& ctx) const
{ {
return fmt::format_to(ctx.out(), "{}", p_string.c_str()); return fmt::format_to(ctx.out(), "{}", p_string.c_str());
} }
}; };
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
template<> template<>
struct fmtquill::formatter<eastl::string> struct fmtquill::formatter<eastl::string>
{ {
static constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
return ctx.begin(); return ctx.begin();
} }
static auto format(const eastl::string& p_string, format_context& ctx) auto format(const eastl::string& p_string, format_context& ctx) const
{ {
return fmtquill::format_to(ctx.out(), "{}", p_string.c_str()); return fmtquill::format_to(ctx.out(), "{}", p_string.c_str());
} }
@@ -56,27 +53,27 @@ struct fmtquill::formatter<eastl::string>
template<> template<>
struct fmt::formatter<eastl::string_view> struct fmt::formatter<eastl::string_view>
{ {
static constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
return ctx.begin(); return ctx.begin();
} }
static auto format(const eastl::string_view& p_stringView, format_context& ctx) auto format(const eastl::string_view& p_stringView, format_context& ctx) const
{ {
return fmt::format_to(ctx.out(), "{}", p_stringView.data()); return fmt::format_to(ctx.out(), "{}", p_stringView.data());
} }
}; };
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
template<> template<>
struct fmtquill::formatter<eastl::string_view> struct fmtquill::formatter<eastl::string_view>
{ {
static constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
return ctx.begin(); return ctx.begin();
} }
static auto format(const eastl::string_view& p_stringView, format_context& ctx) auto format(const eastl::string_view& p_stringView, format_context& ctx) const
{ {
return fmtquill::format_to(ctx.out(), "{}", p_stringView.data()); return fmtquill::format_to(ctx.out(), "{}", p_stringView.data());
} }
@@ -115,61 +112,4 @@ struct quill::Codec<eastl::string_view>: Bigfoot::Codec::string_view<eastl::stri
{ {
}; };
#endif #endif
// VECTOR
template<class T>
struct fmt::formatter<eastl::vector<T>>
{
constexpr auto parse(format_parse_context& ctx)
{
return ctx.begin();
}
auto format(const eastl::vector<T>& p_vector, format_context& ctx) const
{
auto out = fmt::format_to(ctx.out(), "[");
for (std::size_t i = 0; i < p_vector.size(); ++i)
{
if (i > 0)
{
out = fmt::format_to(out, ", ");
}
out = fmt::format_to(out, "{}", p_vector[i]);
}
return fmt::format_to(out, "]");
}
};
#ifdef BIGFOOT_NOT_OPTIMIZED
#include <quill/DeferredFormatCodec.h>
template<class T>
struct fmtquill::formatter<eastl::vector<T>>
{
constexpr auto parse(format_parse_context& ctx)
{
return ctx.begin();
}
auto format(const eastl::vector<T>& p_vector, format_context& ctx) const
{
auto out = fmtquill::format_to(ctx.out(), "[");
for (std::size_t i = 0; i < p_vector.size(); ++i)
{
if (i > 0)
{
out = fmtquill::format_to(out, ", ");
}
out = fmtquill::format_to(out, "{}", p_vector[i]);
}
return fmtquill::format_to(out, "]");
}
};
template<class T>
struct quill::Codec<eastl::vector<T>>: quill::DeferredFormatCodec<eastl::vector<T>>
{
};
#endif
#endif #endif
@@ -2,8 +2,7 @@ namespace Bigfoot.Flat;
enum LogSinkType: byte enum LogSinkType: byte
{ {
Console, Console
File
} }
enum LogLevel: byte enum LogLevel: byte
@@ -8,11 +8,10 @@
#define BIGFOOT_UTILS_LOG_LOG_HPP #define BIGFOOT_UTILS_LOG_LOG_HPP
#include <Utils/Log/EASTLFormatters.hpp> #include <Utils/Log/EASTLFormatters.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
#include <Utils/Log/Log_generated.hpp> #include <Utils/Log/Log_generated.hpp>
#include <EASTL/array.h> #include <EASTL/array.h>
#include <EASTL/string_view.h>
#ifdef BIGFOOT_WINDOWS #ifdef BIGFOOT_WINDOWS
#pragma warning(disable: 4702) #pragma warning(disable: 4702)
@@ -22,8 +21,7 @@
#include <quill/LogMacros.h> #include <quill/LogMacros.h>
#include <quill/Logger.h> #include <quill/Logger.h>
#include <quill/sinks/ConsoleSink.h> #include <quill/sinks/ConsoleSink.h>
#include <quill/sinks/FileSink.h> #if defined BIGFOOT_WINDOWS
#ifdef BIGFOOT_WINDOWS
#pragma warning(default: 4702) #pragma warning(default: 4702)
#endif #endif
@@ -38,11 +36,6 @@ class Log
Flat::LogLevel m_level; Flat::LogLevel m_level;
}; };
/**
* The path of the file the File sink writes to
*/
static constexpr eastl::string_view FILE_SINK_PATH = "Bigfoot.log";
Log(); Log();
Log(const Log& p_logger) = delete; Log(const Log& p_logger) = delete;
@@ -102,7 +95,7 @@ class Log
/* /*
* The sinks * The sinks
*/ */
eastl::array<std::shared_ptr<quill::Sink>, 2> m_sinks; eastl::array<std::shared_ptr<quill::Sink>, 1> m_sinks;
}; };
} // namespace Bigfoot } // namespace Bigfoot
#endif #endif
@@ -9,16 +9,7 @@
#include <Utils/Log/Log.hpp> #include <Utils/Log/Log.hpp>
#include <Utils/Singleton.hpp> #include <Utils/Singleton.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
#define BIGFOOT_FLUSH_LOG \
do \
{ \
if (Bigfoot::Singleton<Bigfoot::Log>::HasInstance()) \
{ \
Bigfoot::Singleton<Bigfoot::Log>::GetInstance().Flush(); \
} \
} while (false)
#define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...) \ #define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...) \
do \ do \
{ \ { \
@@ -110,67 +101,4 @@
#define BIGFOOT_LOG_ERROR(loggerName, fmt, ...) #define BIGFOOT_LOG_ERROR(loggerName, fmt, ...)
#define BIGFOOT_LOG_FATAL(loggerName, fmt, ...) #define BIGFOOT_LOG_FATAL(loggerName, fmt, ...)
#endif #endif
#ifdef BIGFOOT_NOT_OPTIMIZED
#define BIGFOOT_LOG_DEBUG_IF(condition, loggerName, fmt, ...) \
do \
{ \
if (condition) \
{ \
BIGFOOT_LOG_DEBUG(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_TRACE_IF(condition, loggerName, fmt, ...) \
do \
{ \
if (condition) \
{ \
BIGFOOT_LOG_TRACE(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_INFO_IF(condition, loggerName, fmt, ...) \
do \
{ \
if (condition) \
{ \
BIGFOOT_LOG_INFO(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_WARN_IF(condition, loggerName, fmt, ...) \
do \
{ \
if (condition) \
{ \
BIGFOOT_LOG_WARN(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_ERROR_IF(condition, loggerName, fmt, ...) \
do \
{ \
if (condition) \
{ \
BIGFOOT_LOG_ERROR(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_FATAL_IF(condition, loggerName, fmt, ...) \
do \
{ \
if (condition) \
{ \
BIGFOOT_LOG_FATAL(loggerName, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#else
#define BIGFOOT_LOG_DEBUG_IF(condition, loggerName, fmt, ...)
#define BIGFOOT_LOG_TRACE_IF(condition, loggerName, fmt, ...)
#define BIGFOOT_LOG_INFO_IF(condition, loggerName, fmt, ...)
#define BIGFOOT_LOG_WARN_IF(condition, loggerName, fmt, ...)
#define BIGFOOT_LOG_ERROR_IF(condition, loggerName, fmt, ...)
#define BIGFOOT_LOG_FATAL_IF(condition, loggerName, fmt, ...)
#endif
#endif #endif
@@ -29,30 +29,27 @@ namespace Flat {
enum class LogSinkType : int8_t { enum class LogSinkType : int8_t {
Console = 0, Console = 0,
File = 1,
MIN = Console, MIN = Console,
MAX = File MAX = Console
}; };
inline const LogSinkType (&EnumValuesLogSinkType())[2] { inline const LogSinkType (&EnumValuesLogSinkType())[1] {
static const LogSinkType values[] = { static const LogSinkType values[] = {
LogSinkType::Console, LogSinkType::Console
LogSinkType::File
}; };
return values; return values;
} }
inline const char * const *EnumNamesLogSinkType() { inline const char * const *EnumNamesLogSinkType() {
static const char * const names[3] = { static const char * const names[2] = {
"Console", "Console",
"File",
nullptr nullptr
}; };
return names; return names;
} }
inline const char *EnumNameLogSinkType(LogSinkType e) { inline const char *EnumNameLogSinkType(LogSinkType e) {
if (::flatbuffers::IsOutRange(e, LogSinkType::Console, LogSinkType::File)) return ""; if (::flatbuffers::IsOutRange(e, LogSinkType::Console, LogSinkType::Console)) return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesLogSinkType()[index]; return EnumNamesLogSinkType()[index];
} }
@@ -101,14 +98,13 @@ inline const char *EnumNameLogLevel(LogLevel e) {
inline const ::flatbuffers::TypeTable *LogSinkTypeTypeTable() { inline const ::flatbuffers::TypeTable *LogSinkTypeTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = { static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_CHAR, 0, 0 },
{ ::flatbuffers::ET_CHAR, 0, 0 } { ::flatbuffers::ET_CHAR, 0, 0 }
}; };
static const ::flatbuffers::TypeFunction type_refs[] = { static const ::flatbuffers::TypeFunction type_refs[] = {
Bigfoot::Flat::LogSinkTypeTypeTable Bigfoot::Flat::LogSinkTypeTypeTable
}; };
static const ::flatbuffers::TypeTable tt = { static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_ENUM, 2, type_codes, type_refs, nullptr, nullptr, nullptr ::flatbuffers::ST_ENUM, 1, type_codes, type_refs, nullptr, nullptr, nullptr
}; };
return &tt; return &tt;
} }
@@ -15,7 +15,7 @@ namespace Bigfoot
/* /*
* Logger * Logger
*/ */
inline Log::LoggerInfo @LOGGER_NAME@ { .m_name = "@LOGGER_NAME@", .m_level = Flat::LogLevel::Trace}; inline Log::LoggerInfo @LOGGER_NAME@ {"@LOGGER_NAME@", Flat::LogLevel::Trace};
} // namespace Bigfoot } // namespace Bigfoot
#endif #endif
#endif #endif
@@ -33,7 +33,6 @@ class TaggedType
return m_value; return m_value;
} }
[[nodiscard]]
constexpr TYPE Get() const constexpr TYPE Get() const
{ {
return m_value; return m_value;
@@ -7,39 +7,33 @@
#ifndef BIGFOOT_UTILS_TARGETMACROS_H #ifndef BIGFOOT_UTILS_TARGETMACROS_H
#define BIGFOOT_UTILS_TARGETMACROS_H #define BIGFOOT_UTILS_TARGETMACROS_H
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
#define BIGFOOT_WINDOWS_OR_LINUX(p_windows, p_linux) p_windows #define BIGFOOT_WINDOWS_OR_LINUX(p_windows, p_linux) p_windows
#endif #endif
#ifdef BIGFOOT_LINUX #if defined BIGFOOT_LINUX
#define BIGFOOT_WINDOWS_OR_LINUX(p_windows, p_linux) p_linux #define BIGFOOT_WINDOWS_OR_LINUX(p_windows, p_linux) p_linux
#endif #endif
#ifdef BIGFOOT_WINDOWS #if defined BIGFOOT_OPTIMIZED
#define BIGFOOT_ALWAYS_INLINE [[msvc::forceinline]]
#elif defined BIGFOOT_LINUX
#define BIGFOOT_ALWAYS_INLINE [[gnu::always_inline]] inline
#endif
#ifdef BIGFOOT_OPTIMIZED
#define BIGFOOT_OPTIMIZED_ONLY(...) __VA_ARGS__ #define BIGFOOT_OPTIMIZED_ONLY(...) __VA_ARGS__
#define BIGFOOT_NOT_OPTIMIZED_ONLY(...) #define BIGFOOT_NOT_OPTIMIZED_ONLY(...)
#define BIGFOOT_OPTIMIZED_OR_NOT(p_optimized, p_notOptimized) p_optimized #define BIGFOOT_OPTIMIZED_OR_NOT(p_optimized, p_notOptimized) p_optimized
#endif #endif
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
#define BIGFOOT_OPTIMIZED_ONLY(...) #define BIGFOOT_OPTIMIZED_ONLY(...)
#define BIGFOOT_NOT_OPTIMIZED_ONLY(...) __VA_ARGS__ #define BIGFOOT_NOT_OPTIMIZED_ONLY(...) __VA_ARGS__
#define BIGFOOT_OPTIMIZED_OR_NOT(p_optimized, p_notOptimized) p_notOptimized #define BIGFOOT_OPTIMIZED_OR_NOT(p_optimized, p_notOptimized) p_notOptimized
#endif #endif
#ifdef BIGFOOT_TOOLMODE #if defined BIGFOOT_TOOLMODE
#define BIGFOOT_TOOLMODE_ONLY(...) __VA_ARGS__ #define BIGFOOT_TOOLMODE_ONLY(...) __VA_ARGS__
#define BIGFOOT_GAME_ONLY(...) #define BIGFOOT_GAME_ONLY(...)
#define BIGFOOT_GAME_OR_TOOLMODE(p_game, p_toolmode) p_toolmode #define BIGFOOT_GAME_OR_TOOLMODE(p_game, p_toolmode) p_toolmode
#endif #endif
#ifdef BIGFOOT_GAME #if defined BIGFOOT_GAME
#define BIGFOOT_TOOLMODE_ONLY(...) #define BIGFOOT_TOOLMODE_ONLY(...)
#define BIGFOOT_GAME_ONLY(...) __VA_ARGS__ #define BIGFOOT_GAME_ONLY(...) __VA_ARGS__
#define BIGFOOT_GAME_OR_TOOLMODE(p_game, p_toolmode) p_game #define BIGFOOT_GAME_OR_TOOLMODE(p_game, p_toolmode) p_game
@@ -9,7 +9,7 @@
#include <Utils/Assert/AssertHandler.hpp> #include <Utils/Assert/AssertHandler.hpp>
#include <Utils/UtilsLogger_generated.hpp> #include <Utils/UtilsLogger_generated.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot namespace Bigfoot
{ {
@@ -15,7 +15,7 @@ namespace Bigfoot
/* /*
* Logger * Logger
*/ */
inline Log::LoggerInfo UTILS_LOGGER { .m_name = "UTILS_LOGGER", .m_level = Flat::LogLevel::Trace}; inline Log::LoggerInfo UTILS_LOGGER {"UTILS_LOGGER", Flat::LogLevel::Trace};
} // namespace Bigfoot } // namespace Bigfoot
#endif #endif
#endif #endif
@@ -7,22 +7,17 @@
#ifndef BIGFOOT_UTILS_VERSION_HPP #ifndef BIGFOOT_UTILS_VERSION_HPP
#define BIGFOOT_UTILS_VERSION_HPP #define BIGFOOT_UTILS_VERSION_HPP
#include <Utils/Caster.hpp> #include <Utils/Caster.hpp>
#include <Utils/Format.hpp>
#include <Utils/TargetMacros.h> #include <Utils/TargetMacros.h>
#include <EASTL/string.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <cstdint> #include <cstdint>
#include <string>
namespace Bigfoot namespace Bigfoot
{ {
class Version class Version
{ {
private:
static constexpr std::uint32_t MAJOR_SHIFT = 16;
static constexpr std::uint32_t MINOR_SHIFT = 8;
public: public:
Version() = default; Version() = default;
@@ -44,7 +39,7 @@ class Version
* \param p_patch Patch * \param p_patch Patch
*/ */
constexpr Version(const std::uint8_t p_major, const std::uint8_t p_minor, const std::uint8_t p_patch): constexpr Version(const std::uint8_t p_major, const std::uint8_t p_minor, const std::uint8_t p_patch):
m_combined((p_major << MAJOR_SHIFT) | (p_minor << MINOR_SHIFT) | p_patch) m_combined((p_major << 16) | (p_minor << 8) | p_patch)
{ {
} }
@@ -104,7 +99,7 @@ class Version
* \return The string * \return The string
*/ */
[[nodiscard]] [[nodiscard]]
eastl::string ToString() const; std::string ToString() const;
[[nodiscard]] [[nodiscard]]
constexpr auto operator<=>(const Version& p_version) const = default; constexpr auto operator<=>(const Version& p_version) const = default;
@@ -119,6 +114,7 @@ class Version
/****************************************************************************************/ /****************************************************************************************/
#if defined BIGFOOT_NOT_OPTIMIZED
template<> template<>
struct fmt::formatter<Bigfoot::Version> struct fmt::formatter<Bigfoot::Version>
{ {
@@ -131,7 +127,8 @@ struct fmt::formatter<Bigfoot::Version>
template<typename FormatContext> template<typename FormatContext>
auto format(const Bigfoot::Version& p_version, FormatContext& p_context) const auto format(const Bigfoot::Version& p_version, FormatContext& p_context) const
{ {
return fmt::format_to(p_context.out(), "{}", p_version.ToString().c_str()); return fmt::format_to(p_context.out(), "{}", p_version.ToString());
} }
}; };
#endif #endif
#endif
+2 -9
View File
@@ -6,7 +6,7 @@
*********************************************************************/ *********************************************************************/
#include <Utils/Log/Log.hpp> #include <Utils/Log/Log.hpp>
#ifdef BIGFOOT_NOT_OPTIMIZED #if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot namespace Bigfoot
{ {
@@ -17,12 +17,6 @@ Log::Log()
m_sinks[static_cast<std::size_t>(Flat::LogSinkType::Console)] = m_sinks[static_cast<std::size_t>(Flat::LogSinkType::Console)] =
quill::Frontend::create_or_get_sink<quill::ConsoleSink>( quill::Frontend::create_or_get_sink<quill::ConsoleSink>(
std::string {Flat::EnumNameLogSinkType(Flat::LogSinkType::Console)}); std::string {Flat::EnumNameLogSinkType(Flat::LogSinkType::Console)});
quill::FileSinkConfig fileSinkConfig;
fileSinkConfig.set_open_mode('w');
m_sinks[static_cast<std::size_t>(Flat::LogSinkType::File)] = quill::Frontend::create_or_get_sink<quill::FileSink>(
std::string {FILE_SINK_PATH.data()},
fileSinkConfig);
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -31,8 +25,7 @@ quill::Logger* Log::RegisterLogger(const LoggerInfo& p_loggerInfo)
{ {
quill::Logger* logger = quill::Frontend::create_or_get_logger( quill::Logger* logger = quill::Frontend::create_or_get_logger(
p_loggerInfo.m_name, p_loggerInfo.m_name,
{m_sinks[static_cast<std::size_t>(Flat::LogSinkType::Console)], m_sinks[static_cast<std::size_t>(Flat::LogSinkType::Console)]);
m_sinks[static_cast<std::size_t>(Flat::LogSinkType::File)]});
SetLoggerLevel(p_loggerInfo); SetLoggerLevel(p_loggerInfo);
return logger; return logger;
-2
View File
@@ -4,7 +4,6 @@
* \author Romain BOULLARD * \author Romain BOULLARD
* \date October 2025 * \date October 2025
*********************************************************************/ *********************************************************************/
// NOLINTBEGIN
#include <Utils/Profiler.hpp> #include <Utils/Profiler.hpp>
#if defined BIGFOOT_WINDOWS #if defined BIGFOOT_WINDOWS
@@ -97,4 +96,3 @@
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif #endif
// NOLINTEND
+2 -2
View File
@@ -8,8 +8,8 @@
namespace Bigfoot namespace Bigfoot
{ {
eastl::string Version::ToString() const std::string Version::ToString() const
{ {
return Format("{}.{}.{}", GetMajor(), GetMinor(), GetPatch()); return fmt::format("{}.{}.{}", GetMajor(), GetMinor(), GetPatch());
} }
} // namespace Bigfoot } // namespace Bigfoot
-5
View File
@@ -1,5 +0,0 @@
InheritParentConfig: true
Checks: >
-cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-avoid-magic-numbers,
-readability-magic-numbers
+1 -4
View File
@@ -2,7 +2,4 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Misc)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/System) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/System)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine)
if(${TOOLMODE})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Tools)
endif()
+29 -101
View File
@@ -10,7 +10,6 @@
#include <AssetsForTesting/Asset/AssetB.hpp> #include <AssetsForTesting/Asset/AssetB.hpp>
#include <AssetsForTesting/Asset/AssetC.hpp> #include <AssetsForTesting/Asset/AssetC.hpp>
#include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace Bigfoot namespace Bigfoot
@@ -18,66 +17,43 @@ namespace Bigfoot
class AssetFixture: public ::testing::Test class AssetFixture: public ::testing::Test
{ {
protected: protected:
void SetUp() override AssetA m_asset;
{
SetActiveAssetLibrary(&m_library);
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
const UUID uuidA = m_assetA.GetHeader().uuid;
const UUID uuidB = m_assetB.GetHeader().uuid;
m_assetA.GetAsset().ref_a = SoftReference<AssetA> {uuidA};
m_assetB.GetAsset().ref_a = HardReference<AssetA> {uuidA};
m_assetB.GetAsset().refs_a.push_back(SoftReference<AssetA> {uuidA});
m_assetC.GetAsset().inner_table->asset_a_ref = HardReference<AssetA> {uuidA};
m_assetC.GetAsset().inner_table->asset_a_refs.push_back(HardReference<AssetA> {uuidA});
m_assetC.GetAsset().inner_table->asset_a_refs.push_back(HardReference<AssetA> {uuidA});
m_assetC.GetAsset().asset_b_ref = HardReference<AssetB> {uuidB};
m_assetC.GetAsset().asset_b_refs.push_back(SoftReference<AssetB> {uuidB});
}
void TearDown() override
{
SetActiveAssetLibrary(&g_assetLibrary);
}
AssetLibrary m_library;
AssetContainer<AssetA> m_containerA;
AssetContainer<AssetB> m_containerB;
AssetA m_assetA;
AssetB m_assetB;
AssetC m_assetC;
}; };
/****************************************************************************************/ /****************************************************************************************/
TEST_F(AssetFixture, Constructor_ShouldInitializeHeaderTypeIdAndTypeName) TEST_F(AssetFixture, Constructor_ShouldInitializeHeaderTypeIdAndTypeName)
{ {
EXPECT_EQ(m_assetA.GetHeader().type_id, AssetA::GetTypeID()); EXPECT_EQ(m_asset.GetHeader().type_id, AssetA::GetTypeID());
EXPECT_EQ(m_assetA.GetHeader().type_name, eastl::string {AssetA::GetTypeName()}); EXPECT_EQ(m_asset.GetHeader().type_name, eastl::string {AssetA::GetTypeName()});
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(AssetFixture, SetName_ShouldSetTheName) TEST_F(AssetFixture, SetName_ShouldSetTheName)
{ {
m_assetA.SetName("MyAsset"); m_asset.SetName("MyAsset");
EXPECT_STREQ(m_assetA.GetHeader().name.c_str(), "MyAsset"); EXPECT_STREQ(m_asset.GetHeader().name.c_str(), "MyAsset");
}
/****************************************************************************************/
TEST_F(AssetFixture, SetVersion_ShouldSetTheVersion)
{
m_asset.SetVersion(5);
EXPECT_EQ(m_asset.GetHeader().version, 5);
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(AssetFixture, GetAsset_ShouldReturnAMutableReferenceToTheUnderlyingAsset) TEST_F(AssetFixture, GetAsset_ShouldReturnAMutableReferenceToTheUnderlyingAsset)
{ {
m_assetA.GetAsset().health = 10; m_asset.GetAsset().health = 10;
EXPECT_EQ(m_assetA.GetAsset().health, 10); EXPECT_EQ(m_asset.GetAsset().health, 10);
EXPECT_EQ(std::as_const(m_assetA).GetAsset().health, 10); EXPECT_EQ(std::as_const(m_asset).GetAsset().health, 10);
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -107,68 +83,20 @@ TEST_F(AssetFixture, GetTypeName_ShouldReturnTheFlatbufferFullyQualifiedName)
TEST_F(AssetFixture, PackThenUnpack_ShouldRoundTripTheHeaderAndTheAsset) TEST_F(AssetFixture, PackThenUnpack_ShouldRoundTripTheHeaderAndTheAsset)
{ {
m_assetA.SetName("MyAsset"); m_asset.SetName("MyAsset");
m_assetA.GetAsset().health = 42; m_asset.SetVersion(3);
m_assetA.GetAsset().mana = 7; m_asset.GetAsset().health = 42;
m_asset.GetAsset().mana = 7;
AssetA unpacked; AssetA unpacked;
unpacked.Unpack(m_assetA.Pack()); unpacked.Unpack(m_asset.Pack());
EXPECT_EQ(unpacked.GetHeader().uuid, m_assetA.GetHeader().uuid); EXPECT_EQ(unpacked.GetHeader().uuid, m_asset.GetHeader().uuid);
EXPECT_STREQ(unpacked.GetHeader().name.c_str(), m_assetA.GetHeader().name.c_str()); EXPECT_STREQ(unpacked.GetHeader().name.c_str(), m_asset.GetHeader().name.c_str());
EXPECT_EQ(unpacked.GetHeader().type_id, m_assetA.GetHeader().type_id); EXPECT_EQ(unpacked.GetHeader().version, m_asset.GetHeader().version);
EXPECT_STREQ(unpacked.GetHeader().type_name.c_str(), m_assetA.GetHeader().type_name.c_str()); EXPECT_EQ(unpacked.GetHeader().type_id, m_asset.GetHeader().type_id);
EXPECT_EQ(unpacked.GetAsset().health, m_assetA.GetAsset().health); EXPECT_STREQ(unpacked.GetHeader().type_name.c_str(), m_asset.GetHeader().type_name.c_str());
EXPECT_EQ(unpacked.GetAsset().mana, m_assetA.GetAsset().mana); EXPECT_EQ(unpacked.GetAsset().health, m_asset.GetAsset().health);
} EXPECT_EQ(unpacked.GetAsset().mana, m_asset.GetAsset().mana);
/****************************************************************************************/
TEST_F(AssetFixture, GetHardReferences_ShouldReturnTheHardReferencesOfTheAsset)
{
const eastl::vector<UUID> hardReferences = m_assetC.GetHardReferences(m_assetC.Pack());
EXPECT_THAT(hardReferences, ::testing::UnorderedElementsAre(m_assetA.GetHeader().uuid, m_assetB.GetHeader().uuid));
}
/****************************************************************************************/
TEST_F(AssetFixture, CreateAsset_ShouldReturnTheCreatedAsset)
{
EXPECT_NE(CreateAsset<AssetA>(), nullptr);
}
/****************************************************************************************/
TEST_F(AssetFixture, CreateAsset_ShouldCreateUniqueAssets)
{
const AssetA* first = CreateAsset<AssetA>();
const AssetA* second = CreateAsset<AssetA>();
EXPECT_NE(first->GetHeader().uuid, second->GetHeader().uuid);
}
/****************************************************************************************/
TEST_F(AssetFixture, CreateAsset_ShouldReturnTheSameAssetAsItsContainerHandle)
{
const AssetA* asset = CreateAsset<AssetA>();
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(asset->GetHeader().uuid);
EXPECT_EQ(handle->GetAsset(), asset);
}
/****************************************************************************************/
TEST_F(AssetFixture, CreateAsset_ShouldInsertTheAssetIntoItsCorrespondingContainer)
{
const AssetA* assetA = CreateAsset<AssetA>();
const AssetB* assetB = CreateAsset<AssetB>();
EXPECT_TRUE(m_containerA.Has(assetA->GetHeader().uuid));
EXPECT_FALSE(m_containerB.Has(assetA->GetHeader().uuid));
EXPECT_TRUE(m_containerB.Has(assetB->GetHeader().uuid));
EXPECT_FALSE(m_containerA.Has(assetB->GetHeader().uuid));
} }
} // namespace Bigfoot } // namespace Bigfoot
+43 -130
View File
@@ -17,14 +17,18 @@ class ContainerHandleFixture: public ::testing::Test
protected: protected:
void SetUp() override void SetUp() override
{ {
m_handle = m_containerA.Insert(); const auto key = m_containerA.Insert();
m_uuid = m_handle->GetAsset()->GetHeader().uuid;
m_uuid = m_containerA.Get(key)->GetHeader().uuid;
m_handle = m_containerA.AcquireContainerHandle(m_uuid);
} }
AssetContainer<AssetA> m_containerA; AssetContainer<AssetA> m_containerA;
UUID m_uuid; UUID m_uuid;
ContainerHandle* m_handle = nullptr;
ContainerHandle* m_handle;
}; };
/****************************************************************************************/ /****************************************************************************************/
@@ -84,40 +88,6 @@ TEST_F(ContainerHandleFixture, DecrementSoftRefCount_ShouldDecrementTheSoftRefCo
/****************************************************************************************/ /****************************************************************************************/
TEST_F(ContainerHandleFixture, DecrementHardRefCount_ShouldQueueTheAssetForRemovalWhenItReachesZero)
{
m_handle->IncrementHardRefCount();
m_handle->DecrementHardRefCount();
EXPECT_TRUE(m_containerA.IsMarkedForRemove(m_uuid));
}
/****************************************************************************************/
TEST_F(ContainerHandleFixture, DecrementHardRefCount_ShouldNotQueueTheAssetForRemovalIfItDoesNotReachZero)
{
m_handle->IncrementHardRefCount();
m_handle->IncrementHardRefCount();
m_handle->DecrementHardRefCount();
EXPECT_FALSE(m_containerA.IsMarkedForRemove(m_uuid));
}
/****************************************************************************************/
TEST_F(ContainerHandleFixture, IncrementHardRefCount_ShouldCancelAPendingRemovalWhenGoingFromZero)
{
m_handle->IncrementHardRefCount();
m_handle->DecrementHardRefCount();
ASSERT_TRUE(m_containerA.IsMarkedForRemove(m_uuid));
m_handle->IncrementHardRefCount();
EXPECT_FALSE(m_containerA.IsMarkedForRemove(m_uuid));
}
/****************************************************************************************/
class AssetContainerFixture: public ::testing::Test class AssetContainerFixture: public ::testing::Test
{ {
protected: protected:
@@ -128,8 +98,8 @@ class AssetContainerFixture: public ::testing::Test
TEST_F(AssetContainerFixture, Has_ShouldReturnTrueIfTheContainerHasTheAsset) TEST_F(AssetContainerFixture, Has_ShouldReturnTrueIfTheContainerHasTheAsset)
{ {
const ContainerHandle* handle = m_containerA.Insert(); const auto key = m_containerA.Insert();
EXPECT_TRUE(m_containerA.Has(handle->GetAsset()->GetHeader().uuid)); EXPECT_TRUE(m_containerA.Has(m_containerA.Get(key)->GetHeader().uuid));
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -143,10 +113,11 @@ TEST_F(AssetContainerFixture, Has_ShouldReturnFalseIfTheContainerDoesNotHaveTheA
TEST_F(AssetContainerFixture, AcquireHandle_ShouldReturnTheAssociatedContainerHandle) TEST_F(AssetContainerFixture, AcquireHandle_ShouldReturnTheAssociatedContainerHandle)
{ {
const ContainerHandle* handle = m_containerA.Insert(); const auto key = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
EXPECT_EQ(m_containerA.AcquireContainerHandle(uuid), handle); const ContainerHandle* handle = m_containerA.AcquireContainerHandle(m_containerA.Get(key)->GetHeader().uuid);
EXPECT_EQ(static_cast<const AssetA*>(handle->GetAsset())->GetHeader().uuid,
m_containerA.Get(key)->GetHeader().uuid);
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -159,111 +130,53 @@ TEST_F(AssetContainerFixture, AcquireHandle_ShouldCreateTheAssociatedContainerHa
/****************************************************************************************/ /****************************************************************************************/
TEST_F(AssetContainerFixture, Insert_ShouldReturnAHandleWithTheInsertedAsset) TEST_F(AssetContainerFixture, Insert_ShouldReturnValidAndUniqueSlotKeyOnInsert)
{ {
const ContainerHandle* handle = m_containerA.Insert(); const SlotMapKey slotKey = m_containerA.Insert();
EXPECT_NE(handle, nullptr); EXPECT_TRUE(slotKey.Valid());
EXPECT_NE(handle->GetAsset(), nullptr); EXPECT_NE(slotKey, m_containerA.Insert());
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(AssetContainerFixture, Insert_ShouldReuseTheExistingHandleWhenInsertingAnAssetWithAnAlreadyExistingUUID) TEST_F(AssetContainerFixture, Insert_ShouldReturnTheSameSlotKeyInCaseOfDuplicatedUUID)
{ {
ContainerHandle* const firstHandle = m_containerA.Insert(); const SlotMapKey slotKey = m_containerA.Insert();
const AssetBase* const firstAsset = firstHandle->GetAsset();
const eastl::vector<std::byte> packed = firstAsset->Pack();
ContainerHandle* const secondHandle = m_containerA.Insert(packed); AssetA duplicate;
duplicate.Unpack(m_containerA.Get(slotKey)->Pack());
EXPECT_EQ(secondHandle, firstHandle); EXPECT_EQ(slotKey, m_containerA.Insert(std::move(duplicate)));
EXPECT_EQ(secondHandle->GetAsset(), firstAsset); }
/****************************************************************************************/
TEST_F(AssetContainerFixture, Get_ShouldReturnTheAssetWithTheSlotKey)
{
const SlotMapKey slotKey = m_containerA.Insert();
EXPECT_NE(m_containerA.Get(slotKey), nullptr);
EXPECT_NE(std::as_const(m_containerA).Get(slotKey), nullptr);
}
/****************************************************************************************/
TEST_F(AssetContainerFixture, Get_ShouldReturnNullptrIfSlotKeyNotInContainer)
{
EXPECT_EQ(m_containerA.Get(SlotMapKey<> {1, 0}), nullptr);
EXPECT_EQ(std::as_const(m_containerA).Get(SlotMapKey<> {1, 0}), nullptr);
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(AssetContainerFixture, Remove_ShouldRemoveTheAsset) TEST_F(AssetContainerFixture, Remove_ShouldRemoveTheAsset)
{ {
const ContainerHandle* handle = m_containerA.Insert(); const SlotMapKey slotKey = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid; const UUID uuid = m_containerA.Get(slotKey)->GetHeader().uuid;
m_containerA.Remove(uuid); m_containerA.Remove(uuid);
EXPECT_EQ(handle->GetAsset(), nullptr); EXPECT_EQ(m_containerA.Get(slotKey), nullptr);
EXPECT_FALSE(m_containerA.Has(uuid)); EXPECT_FALSE(m_containerA.Has(uuid));
} }
/****************************************************************************************/
TEST_F(AssetContainerFixture, IsMarkedForRemove_ShouldReturnTrueIfTheAssetIsMarkedForDelete)
{
const ContainerHandle* handle = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
m_containerA.QueueForRemoval(uuid);
EXPECT_TRUE(m_containerA.IsMarkedForRemove(uuid));
}
/****************************************************************************************/
TEST_F(AssetContainerFixture, IsMarkedForRemove_ShouldReturnFalseIfTheAssetIsNotMarkedForDelete)
{
const ContainerHandle* handle = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
EXPECT_FALSE(m_containerA.IsMarkedForRemove(uuid));
}
/****************************************************************************************/
TEST_F(AssetContainerFixture, QueueForRemoval_ShouldMarkTheAssetForRemoval)
{
const ContainerHandle* handle = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
m_containerA.QueueForRemoval(uuid);
EXPECT_TRUE(m_containerA.IsMarkedForRemove(uuid));
}
/****************************************************************************************/
TEST_F(AssetContainerFixture, CancelRemoval_ShouldUnmarkAQueuedAsset)
{
const ContainerHandle* handle = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
m_containerA.QueueForRemoval(uuid);
m_containerA.CancelRemoval(uuid);
EXPECT_FALSE(m_containerA.IsMarkedForRemove(uuid));
}
/****************************************************************************************/
TEST_F(AssetContainerFixture, ProcessPendingRemovals_ShouldRemoveQueuedAssets)
{
const ContainerHandle* handle = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
m_containerA.QueueForRemoval(uuid);
m_containerA.ProcessPendingRemovals();
EXPECT_EQ(handle->GetAsset(), nullptr);
EXPECT_FALSE(m_containerA.Has(uuid));
}
/****************************************************************************************/
TEST_F(AssetContainerFixture, ProcessPendingRemovals_ShouldNotRemoveAssetsThatAreNotQueued)
{
const ContainerHandle* handle = m_containerA.Insert();
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
m_containerA.ProcessPendingRemovals();
EXPECT_NE(handle->GetAsset(), nullptr);
EXPECT_TRUE(m_containerA.Has(uuid));
}
} // namespace Bigfoot } // namespace Bigfoot
-167
View File
@@ -73,173 +73,6 @@ TEST_F(AssetLibraryFixture, GetAssetContainer_ShouldReturnNullptrIfTheContainerD
/****************************************************************************************/ /****************************************************************************************/
TEST_F(AssetLibraryFixture, GetAssetContainer_ShouldReturnTheContainerThatHasTheAsset)
{
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
const UUID uuid = m_containerB.Insert()->GetAsset()->GetHeader().uuid;
EXPECT_EQ(m_library.GetAssetContainer(uuid), &m_containerB);
EXPECT_EQ(std::as_const(m_library).GetAssetContainer(uuid), &m_containerB);
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, GetAssetContainer_ShouldReturnNullptrIfNoContainerHasTheAsset)
{
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
const UUID uuid;
EXPECT_EQ(m_library.GetAssetContainer(uuid), nullptr);
EXPECT_EQ(std::as_const(m_library).GetAssetContainer(uuid), nullptr);
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, IsLoaded_ShouldReturnTrueIfTheAssetIsLoaded)
{
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
const UUID uuid = m_containerB.Insert()->GetAsset()->GetHeader().uuid;
EXPECT_TRUE(m_library.IsLoaded(uuid));
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, IsLoaded_ShouldReturnFalseIfTheAssetIsNotLoaded)
{
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
const UUID uuid;
EXPECT_FALSE(m_library.IsLoaded(uuid));
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, IsLoaded_ShouldReturnFalseIfTheAssetWasRemovedFromItsContainer)
{
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
const UUID uuid = m_containerB.Insert()->GetAsset()->GetHeader().uuid;
ASSERT_TRUE(m_library.IsLoaded(uuid));
m_containerB.Remove(uuid);
EXPECT_FALSE(m_library.IsLoaded(uuid));
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, ProcessPendingRemovals_ShouldProcessRemovalsOnEveryContainer)
{
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
const UUID uuidA = m_containerA.Insert()->GetAsset()->GetHeader().uuid;
const UUID uuidB = m_containerB.Insert()->GetAsset()->GetHeader().uuid;
m_containerA.QueueForRemoval(uuidA);
m_containerB.QueueForRemoval(uuidB);
m_library.ProcessPendingRemovals();
EXPECT_FALSE(m_containerA.Has(uuidA));
EXPECT_FALSE(m_containerB.Has(uuidB));
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, ProcessPendingRemovals_ShouldNotRemoveAssetsThatAreNotQueued)
{
std::ignore = m_library.Insert(&m_containerA);
const UUID uuid = m_containerA.Insert()->GetAsset()->GetHeader().uuid;
m_library.ProcessPendingRemovals();
EXPECT_TRUE(m_containerA.Has(uuid));
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, ProcessPendingRemovals_ShouldCascadeThroughHardReferencedAssetsOneLevelPerCall)
{
const ScopedActiveAssetLibrary activeAssetLibraryScoped {&m_library};
std::ignore = m_library.Insert(&m_containerA);
std::ignore = m_library.Insert(&m_containerB);
std::ignore = m_library.Insert(&m_containerC);
UUID leafUUID;
UUID middleUUID;
UUID rootUUID;
{
// leaf
AssetA* leaf = CreateAsset<AssetA>();
leafUUID = leaf->GetHeader().uuid;
// middle --> leaf
AssetB* middle = CreateAsset<AssetB>();
middle->GetAsset().ref_a = HardReference<AssetA> {leafUUID};
middleUUID = middle->GetHeader().uuid;
// root
// / \
// v v
// middle --> leaf
AssetC* root = CreateAsset<AssetC>();
root->GetAsset().asset_b_ref = HardReference<AssetB> {middleUUID};
root->GetAsset().inner_table->asset_a_ref = HardReference<AssetA> {leafUUID};
rootUUID = root->GetHeader().uuid;
const HardReference<AssetC> rootRef {rootUUID};
const HardReference<AssetB> middleRef {middleUUID};
const HardReference<AssetA> leafRef {leafUUID};
ASSERT_NE(rootRef.Get(), nullptr);
ASSERT_NE(middleRef.Get(), nullptr);
ASSERT_NE(leafRef.Get(), nullptr);
}
// Releasing the outer HardReferences only drops root's count to zero: middle and leaf are
// still kept alive by root's own internal HardReferences to them.
EXPECT_TRUE(m_containerC.IsMarkedForRemove(rootUUID));
EXPECT_FALSE(m_containerB.IsMarkedForRemove(middleUUID));
EXPECT_FALSE(m_containerA.IsMarkedForRemove(leafUUID));
EXPECT_TRUE(m_library.IsLoaded(rootUUID));
EXPECT_TRUE(m_library.IsLoaded(middleUUID));
EXPECT_TRUE(m_library.IsLoaded(leafUUID));
// 1st pass: removing root destroys its HardReference to middle, dropping middle's count to
// zero; leaf is still held alive by middle's own HardReference to it.
m_library.ProcessPendingRemovals();
EXPECT_FALSE(m_library.IsLoaded(rootUUID));
EXPECT_TRUE(m_containerB.IsMarkedForRemove(middleUUID));
EXPECT_TRUE(m_library.IsLoaded(middleUUID));
EXPECT_TRUE(m_library.IsLoaded(leafUUID));
// 2nd pass: removing middle destroys its HardReference to leaf, dropping leaf's count to zero.
m_library.ProcessPendingRemovals();
EXPECT_FALSE(m_library.IsLoaded(middleUUID));
EXPECT_TRUE(m_containerA.IsMarkedForRemove(leafUUID));
EXPECT_TRUE(m_library.IsLoaded(leafUUID));
// 3rd pass: nothing references leaf anymore, it finally gets removed.
m_library.ProcessPendingRemovals();
EXPECT_FALSE(m_library.IsLoaded(leafUUID));
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, SetActiveAssetLibrary_ShouldSetTheActiveAssetLibraryToTheGivenLibrary) TEST_F(AssetLibraryFixture, SetActiveAssetLibrary_ShouldSetTheActiveAssetLibraryToTheGivenLibrary)
{ {
SetActiveAssetLibrary(&m_library); SetActiveAssetLibrary(&m_library);
@@ -1,34 +0,0 @@
/*********************************************************************
* \file AssetTypeID.cpp
*
* \author Romain BOULLARD
* \date August 2026
*********************************************************************/
#include <Engine/Asset/AssetTypeID.hpp>
#include <Engine/Asset/AssetTypeID_generated.hpp>
#include <gtest/gtest.h>
#include <limits>
namespace Bigfoot
{
TEST(AssetTypeID, Pack_ShouldGiveAFlatAssetTypeIDWithTheSameValue)
{
constexpr AssetTypeID assetTypeID = 42;
const ::Flat::Bigfoot::AssetTypeID flatAssetTypeID = flatbuffers::Pack(assetTypeID);
EXPECT_EQ(flatAssetTypeID.value(), assetTypeID);
}
/****************************************************************************************/
TEST(AssetTypeID, UnPack_ShouldGiveBackTheOriginalValue)
{
constexpr AssetTypeID assetTypeID = 42;
const ::Flat::Bigfoot::AssetTypeID flatAssetTypeID = flatbuffers::Pack(assetTypeID);
EXPECT_EQ(flatbuffers::UnPack(flatAssetTypeID), assetTypeID);
}
} // namespace Bigfoot
+340 -155
View File
@@ -1,49 +1,26 @@
/********************************************************************* /*********************************************************************
* \file Reference.cpp * \file AssetLibrary.cpp
* *
* \author Romain BOULLARD * \author Romain BOULLARD
* \date August 2026 * \date July 2026
*********************************************************************/ *********************************************************************/
#include <Engine/Asset/Reference.hpp>
#include <Engine/Asset/AssetLibrary.hpp> #include <Engine/Asset/AssetLibrary.hpp>
#include <AssetsForTesting/Asset/AssetA.hpp> #include <AssetsForTesting/Asset/AssetA.hpp>
#include <AssetsForTesting/Asset/AssetB.hpp>
#include <AssetsForTesting/Asset/AssetC.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace Bigfoot namespace Bigfoot
{ {
template<class REFERENCE> class HardReferenceFixture: public ::testing::Test
struct RefCountTraits;
template<>
struct RefCountTraits<HardReference<AssetA>>
{
[[nodiscard]]
static std::uint32_t Get(const ContainerHandle* p_handle)
{
return p_handle->GetHardRefCount();
}
};
template<>
struct RefCountTraits<SoftReference<AssetA>>
{
[[nodiscard]]
static std::uint32_t Get(const ContainerHandle* p_handle)
{
return p_handle->GetSoftRefCount();
}
};
template<class REFERENCE>
class ReferenceFixture: public ::testing::Test
{ {
protected: protected:
void SetUp() override void SetUp() override
{ {
SetActiveAssetLibrary(&m_library); SetActiveAssetLibrary(&m_library);
std::ignore = m_library.Insert(&m_containerA); std::ignore = m_library.Insert(&m_containerA);
} }
@@ -52,244 +29,452 @@ class ReferenceFixture: public ::testing::Test
SetActiveAssetLibrary(&g_assetLibrary); SetActiveAssetLibrary(&g_assetLibrary);
} }
[[nodiscard]]
static std::uint32_t GetRefCount(const ContainerHandle* p_handle)
{
return RefCountTraits<REFERENCE>::Get(p_handle);
}
AssetContainer<AssetA> m_containerA; AssetContainer<AssetA> m_containerA;
AssetLibrary m_library; AssetLibrary m_library;
}; };
class ReferenceTypeNameGenerator
{
public:
template<typename T>
static std::string GetName([[maybe_unused]] int p_index)
{
if constexpr (std::is_same_v<T, HardReference<AssetA>>)
{
return "HardReference";
}
if constexpr (std::is_same_v<T, SoftReference<AssetA>>)
{
return "SoftReference";
}
}
};
using ReferenceTypes = ::testing::Types<HardReference<AssetA>, SoftReference<AssetA>>;
TYPED_TEST_SUITE(ReferenceFixture, ReferenceTypes, ReferenceTypeNameGenerator);
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, GetUUID_ShouldReturnTheUUID) TEST_F(HardReferenceFixture, GetUUID_ShouldReturnTheUUID)
{ {
UUID uuid; UUID uuid;
TypeParam ref {uuid}; HardReference<AssetA> hardRef {uuid};
EXPECT_EQ(ref.GetUUID(), uuid); EXPECT_EQ(hardRef.GetUUID(), uuid);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, Get_ShouldReturnTheAsset) TEST_F(HardReferenceFixture, Get_ShouldReturnTheAsset)
{ {
const AssetA* inserted = CreateAsset<AssetA>(); const auto key = m_containerA.Insert();
const UUID uuid = inserted->GetHeader().uuid; const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
TypeParam ref {uuid}; HardReference<AssetA> hardRef {uuid};
EXPECT_EQ(ref.Get(), inserted); EXPECT_EQ(hardRef.Get(), m_containerA.Get(key));
EXPECT_EQ(std::as_const(ref).Get(), inserted); EXPECT_EQ(std::as_const(hardRef).Get(), std::as_const(m_containerA).Get(key));
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, Get_ShouldReturnNullptrIfTheAssetDoesNotExist) TEST_F(HardReferenceFixture, Get_ShouldReturnNullptrIfTheAssetDoesNotExist)
{ {
UUID uuid; UUID uuid;
TypeParam ref {uuid}; HardReference<AssetA> hardRef {uuid};
EXPECT_EQ(ref.Get(), nullptr); EXPECT_EQ(hardRef.Get(), nullptr);
EXPECT_EQ(std::as_const(ref).Get(), nullptr); EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, Get_ShouldReturnNullptrAfterTheAssetIsRemovedFromTheContainer) TEST_F(HardReferenceFixture, Get_ShouldReturnNullptrAfterTheAssetIsRemovedFromTheContainer)
{ {
const AssetA* inserted = CreateAsset<AssetA>(); const auto key = m_containerA.Insert();
const UUID uuid = inserted->GetHeader().uuid; const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
TypeParam ref {uuid}; HardReference<AssetA> hardRef {uuid};
this->m_containerA.Remove(uuid); m_containerA.Remove(uuid);
EXPECT_EQ(ref.Get(), nullptr); EXPECT_EQ(hardRef.Get(), nullptr);
EXPECT_EQ(std::as_const(ref).Get(), nullptr); EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, ShouldTouchTheRefCountOfTheHandle) TEST_F(HardReferenceFixture, ShouldTouchTheHardRefCountOfTheHandle)
{ {
UUID uuid; UUID uuid;
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid); const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
EXPECT_EQ(this->GetRefCount(handle), 0); EXPECT_EQ(handle->GetHardRefCount(), 0);
{ {
TypeParam ref1 {uuid}; HardReference<AssetA> hardRef1 {uuid};
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
{ {
TypeParam ref2 {uuid}; HardReference<AssetA> hardRef2 {uuid};
EXPECT_EQ(this->GetRefCount(handle), 2); EXPECT_EQ(handle->GetHardRefCount(), 2);
} }
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
} }
EXPECT_EQ(this->GetRefCount(handle), 0); EXPECT_EQ(handle->GetHardRefCount(), 0);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, CopyConstructor_ShouldIncrementTheRefCountAndCopyTheState) TEST_F(HardReferenceFixture, CopyConstructor_ShouldIncrementTheHardRefCountAndCopyTheState)
{ {
const AssetA* inserted = CreateAsset<AssetA>(); const auto key = m_containerA.Insert();
const UUID uuid = inserted->GetHeader().uuid; const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid); const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
TypeParam ref1 {uuid}; HardReference<AssetA> hardRef1 {uuid};
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
TypeParam ref2 {ref1}; HardReference<AssetA> hardRef2 {hardRef1};
EXPECT_EQ(this->GetRefCount(handle), 2); EXPECT_EQ(handle->GetHardRefCount(), 2);
EXPECT_EQ(ref2.GetUUID(), uuid); EXPECT_EQ(hardRef2.GetUUID(), uuid);
EXPECT_EQ(ref2.Get(), inserted); EXPECT_EQ(hardRef2.Get(), m_containerA.Get(key));
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, MoveConstructor_ShouldTransferTheStateWithoutChangingTheRefCount) TEST_F(HardReferenceFixture, MoveConstructor_ShouldTransferTheStateWithoutChangingTheHardRefCount)
{ {
const AssetA* inserted = CreateAsset<AssetA>(); const auto key = m_containerA.Insert();
const UUID uuid = inserted->GetHeader().uuid; const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid); const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
TypeParam ref1 {uuid}; HardReference<AssetA> hardRef1 {uuid};
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
TypeParam ref2 {std::move(ref1)}; HardReference<AssetA> hardRef2 {std::move(hardRef1)};
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
EXPECT_EQ(ref2.GetUUID(), uuid); EXPECT_EQ(hardRef2.GetUUID(), uuid);
EXPECT_EQ(ref2.Get(), inserted); EXPECT_EQ(hardRef2.Get(), m_containerA.Get(key));
EXPECT_EQ(ref1.GetUUID(), UUID::NULL_UUID); EXPECT_EQ(hardRef1.GetUUID(), UUID::NULL_UUID);
EXPECT_EQ(ref1.Get(), nullptr); EXPECT_EQ(hardRef1.Get(), nullptr);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, CopyAssignment_ShouldReleaseThePreviousHandleAndAcquireTheNewOne) TEST_F(HardReferenceFixture, CopyAssignment_ShouldReleaseThePreviousHandleAndAcquireTheNewOne)
{ {
UUID uuidA; UUID uuidA;
UUID uuidB; UUID uuidB;
const ContainerHandle* handleA = this->m_containerA.AcquireContainerHandle(uuidA); const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
const ContainerHandle* handleB = this->m_containerA.AcquireContainerHandle(uuidB); const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
TypeParam refA {uuidA}; HardReference<AssetA> hardRefA {uuidA};
TypeParam refB {uuidB}; HardReference<AssetA> hardRefB {uuidB};
EXPECT_EQ(this->GetRefCount(handleA), 1); EXPECT_EQ(handleA->GetHardRefCount(), 1);
EXPECT_EQ(this->GetRefCount(handleB), 1); EXPECT_EQ(handleB->GetHardRefCount(), 1);
refB = refA; hardRefB = hardRefA;
EXPECT_EQ(this->GetRefCount(handleA), 2); EXPECT_EQ(handleA->GetHardRefCount(), 2);
EXPECT_EQ(this->GetRefCount(handleB), 0); EXPECT_EQ(handleB->GetHardRefCount(), 0);
EXPECT_EQ(refB.GetUUID(), uuidA); EXPECT_EQ(hardRefB.GetUUID(), uuidA);
EXPECT_EQ(refB.Get(), refA.Get()); EXPECT_EQ(hardRefB.Get(), hardRefA.Get());
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, CopyAssignment_SelfAssignment_ShouldNotChangeTheRefCount) TEST_F(HardReferenceFixture, CopyAssignment_SelfAssignment_ShouldNotChangeTheHardRefCount)
{ {
UUID uuid; UUID uuid;
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid); const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
TypeParam ref {uuid}; HardReference<AssetA> hardRef {uuid};
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
TypeParam* selfPtr = &ref; HardReference<AssetA>* selfPtr = &hardRef;
ref = *selfPtr; hardRef = *selfPtr;
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
EXPECT_EQ(ref.GetUUID(), uuid); EXPECT_EQ(hardRef.GetUUID(), uuid);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, MoveAssignment_ShouldReleaseThePreviousHandleAndTransferTheNewOne) TEST_F(HardReferenceFixture, MoveAssignment_ShouldReleaseThePreviousHandleAndTransferTheNewOne)
{ {
UUID uuidA; UUID uuidA;
UUID uuidB; UUID uuidB;
const ContainerHandle* handleA = this->m_containerA.AcquireContainerHandle(uuidA); const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
const ContainerHandle* handleB = this->m_containerA.AcquireContainerHandle(uuidB); const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
TypeParam refA {uuidA}; HardReference<AssetA> hardRefA {uuidA};
TypeParam refB {uuidB}; HardReference<AssetA> hardRefB {uuidB};
EXPECT_EQ(this->GetRefCount(handleA), 1); EXPECT_EQ(handleA->GetHardRefCount(), 1);
EXPECT_EQ(this->GetRefCount(handleB), 1); EXPECT_EQ(handleB->GetHardRefCount(), 1);
refB = std::move(refA); hardRefB = std::move(hardRefA);
EXPECT_EQ(this->GetRefCount(handleA), 1); EXPECT_EQ(handleA->GetHardRefCount(), 1);
EXPECT_EQ(this->GetRefCount(handleB), 0); EXPECT_EQ(handleB->GetHardRefCount(), 0);
EXPECT_EQ(refB.GetUUID(), uuidA); EXPECT_EQ(hardRefB.GetUUID(), uuidA);
EXPECT_EQ(refA.GetUUID(), UUID::NULL_UUID); EXPECT_EQ(hardRefA.GetUUID(), UUID::NULL_UUID);
EXPECT_EQ(refA.Get(), nullptr); EXPECT_EQ(hardRefA.Get(), nullptr);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, MoveAssignment_SelfAssignment_ShouldNotChangeTheRefCount) TEST_F(HardReferenceFixture, MoveAssignment_SelfAssignment_ShouldNotChangeTheHardRefCount)
{ {
UUID uuid; UUID uuid;
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid); const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
TypeParam ref {uuid}; HardReference<AssetA> hardRef {uuid};
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
TypeParam* selfPtr = &ref; HardReference<AssetA>* selfPtr = &hardRef;
ref = std::move(*selfPtr); hardRef = std::move(*selfPtr);
EXPECT_EQ(this->GetRefCount(handle), 1); EXPECT_EQ(handle->GetHardRefCount(), 1);
EXPECT_EQ(ref.GetUUID(), uuid); EXPECT_EQ(hardRef.GetUUID(), uuid);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, EqualityOperator_ShouldReturnTrueForReferencesWithTheSameUUID) TEST_F(HardReferenceFixture, EqualityOperator_ShouldReturnTrueForReferencesWithTheSameUUID)
{ {
UUID uuid; UUID uuid;
TypeParam ref1 {uuid}; HardReference<AssetA> hardRef1 {uuid};
TypeParam ref2 {uuid}; HardReference<AssetA> hardRef2 {uuid};
EXPECT_EQ(ref1, ref2); EXPECT_EQ(hardRef1, hardRef2);
} }
/****************************************************************************************/ /****************************************************************************************/
TYPED_TEST(ReferenceFixture, EqualityOperator_ShouldReturnFalseForReferencesWithDifferentUUIDs) TEST_F(HardReferenceFixture, EqualityOperator_ShouldReturnFalseForReferencesWithDifferentUUIDs)
{ {
UUID uuid1; UUID uuid1;
UUID uuid2; UUID uuid2;
TypeParam ref1 {uuid1}; HardReference<AssetA> hardRef1 {uuid1};
TypeParam ref2 {uuid2}; HardReference<AssetA> hardRef2 {uuid2};
EXPECT_NE(ref1, ref2); EXPECT_NE(hardRef1, hardRef2);
}
/****************************************************************************************/
class SoftReferenceFixture: public ::testing::Test
{
protected:
void SetUp() override
{
SetActiveAssetLibrary(&m_library);
std::ignore = m_library.Insert(&m_containerA);
}
void TearDown() override
{
SetActiveAssetLibrary(&g_assetLibrary);
}
AssetContainer<AssetA> m_containerA;
AssetLibrary m_library;
};
/****************************************************************************************/
TEST_F(SoftReferenceFixture, GetUUID_ShouldReturnTheUUID)
{
UUID uuid;
SoftReference<AssetA> hardRef {uuid};
EXPECT_EQ(hardRef.GetUUID(), uuid);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, Get_ShouldReturnTheAsset)
{
const auto key = m_containerA.Insert();
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
SoftReference<AssetA> hardRef {uuid};
EXPECT_EQ(hardRef.Get(), m_containerA.Get(key));
EXPECT_EQ(std::as_const(hardRef).Get(), std::as_const(m_containerA).Get(key));
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, Get_ShouldReturnNullptrIfTheAssetDoesNotExist)
{
UUID uuid;
SoftReference<AssetA> hardRef {uuid};
EXPECT_EQ(hardRef.Get(), nullptr);
EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, Get_ShouldReturnNullptrAfterTheAssetIsRemovedFromTheContainer)
{
const auto key = m_containerA.Insert();
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
SoftReference<AssetA> hardRef {uuid};
m_containerA.Remove(uuid);
EXPECT_EQ(hardRef.Get(), nullptr);
EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, ShouldTouchTheSoftRefCountOfTheHandle)
{
UUID uuid;
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
EXPECT_EQ(handle->GetSoftRefCount(), 0);
{
SoftReference<AssetA> softRef1 {uuid};
EXPECT_EQ(handle->GetSoftRefCount(), 1);
{
SoftReference<AssetA> softRef2 {uuid};
EXPECT_EQ(handle->GetSoftRefCount(), 2);
}
EXPECT_EQ(handle->GetSoftRefCount(), 1);
}
EXPECT_EQ(handle->GetSoftRefCount(), 0);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, CopyConstructor_ShouldIncrementTheSoftRefCountAndCopyTheState)
{
const auto key = m_containerA.Insert();
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
SoftReference<AssetA> softRef1 {uuid};
EXPECT_EQ(handle->GetSoftRefCount(), 1);
SoftReference<AssetA> softRef2 {softRef1};
EXPECT_EQ(handle->GetSoftRefCount(), 2);
EXPECT_EQ(softRef2.GetUUID(), uuid);
EXPECT_EQ(softRef2.Get(), m_containerA.Get(key));
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, MoveConstructor_ShouldTransferTheStateWithoutChangingTheSoftRefCount)
{
const auto key = m_containerA.Insert();
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
SoftReference<AssetA> softRef1 {uuid};
EXPECT_EQ(handle->GetSoftRefCount(), 1);
SoftReference<AssetA> softRef2 {std::move(softRef1)};
EXPECT_EQ(handle->GetSoftRefCount(), 1);
EXPECT_EQ(softRef2.GetUUID(), uuid);
EXPECT_EQ(softRef2.Get(), m_containerA.Get(key));
EXPECT_EQ(softRef1.GetUUID(), UUID::NULL_UUID);
EXPECT_EQ(softRef1.Get(), nullptr);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, CopyAssignment_ShouldReleaseThePreviousHandleAndAcquireTheNewOne)
{
UUID uuidA;
UUID uuidB;
const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
SoftReference<AssetA> softRefA {uuidA};
SoftReference<AssetA> softRefB {uuidB};
EXPECT_EQ(handleA->GetSoftRefCount(), 1);
EXPECT_EQ(handleB->GetSoftRefCount(), 1);
softRefB = softRefA;
EXPECT_EQ(handleA->GetSoftRefCount(), 2);
EXPECT_EQ(handleB->GetSoftRefCount(), 0);
EXPECT_EQ(softRefB.GetUUID(), uuidA);
EXPECT_EQ(softRefB.Get(), softRefA.Get());
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, CopyAssignment_SelfAssignment_ShouldNotChangeTheSoftRefCount)
{
UUID uuid;
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
SoftReference<AssetA> softRef {uuid};
EXPECT_EQ(handle->GetSoftRefCount(), 1);
SoftReference<AssetA>* selfPtr = &softRef;
softRef = *selfPtr;
EXPECT_EQ(handle->GetSoftRefCount(), 1);
EXPECT_EQ(softRef.GetUUID(), uuid);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, MoveAssignment_ShouldReleaseThePreviousHandleAndTransferTheNewOne)
{
UUID uuidA;
UUID uuidB;
const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
SoftReference<AssetA> softRefA {uuidA};
SoftReference<AssetA> softRefB {uuidB};
EXPECT_EQ(handleA->GetSoftRefCount(), 1);
EXPECT_EQ(handleB->GetSoftRefCount(), 1);
softRefB = std::move(softRefA);
EXPECT_EQ(handleA->GetSoftRefCount(), 1);
EXPECT_EQ(handleB->GetSoftRefCount(), 0);
EXPECT_EQ(softRefB.GetUUID(), uuidA);
EXPECT_EQ(softRefA.GetUUID(), UUID::NULL_UUID);
EXPECT_EQ(softRefA.Get(), nullptr);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, MoveAssignment_SelfAssignment_ShouldNotChangeTheSoftRefCount)
{
UUID uuid;
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
SoftReference<AssetA> softRef {uuid};
EXPECT_EQ(handle->GetSoftRefCount(), 1);
SoftReference<AssetA>* selfPtr = &softRef;
softRef = std::move(*selfPtr);
EXPECT_EQ(handle->GetSoftRefCount(), 1);
EXPECT_EQ(softRef.GetUUID(), uuid);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, EqualityOperator_ShouldReturnTrueForReferencesWithTheSameUUID)
{
UUID uuid;
SoftReference<AssetA> softRef1 {uuid};
SoftReference<AssetA> softRef2 {uuid};
EXPECT_EQ(softRef1, softRef2);
}
/****************************************************************************************/
TEST_F(SoftReferenceFixture, EqualityOperator_ShouldReturnFalseForReferencesWithDifferentUUIDs)
{
UUID uuid1;
UUID uuid2;
SoftReference<AssetA> softRef1 {uuid1};
SoftReference<AssetA> softRef2 {uuid2};
EXPECT_NE(softRef1, softRef2);
} }
} // namespace Bigfoot } // namespace Bigfoot
+205 -399
View File
@@ -11,11 +11,7 @@
#include <EngineTests/BigFileInfo_generated.hpp> #include <EngineTests/BigFileInfo_generated.hpp>
#include <AssetsForTesting/Asset/AssetA.hpp> #include <AssetsForTesting/Asset/AssetA.hpp>
#include <AssetsForTesting/Asset/AssetB.hpp>
#include <AssetsForTesting/Asset/AssetC.hpp>
#include <EASTL/array.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <chrono> #include <chrono>
@@ -29,49 +25,8 @@ class BigFileFixture: public ::testing::Test
protected: protected:
void SetUp() override void SetUp() override
{ {
m_bigFile.Clear(); BigFile::Request {m_bigFile, "DELETE FROM Asset;"}.Execute();
} BigFile::Request {m_bigFile, "DELETE FROM AssetMetadata;"}.Execute();
/*
* Packs an asset and saves it to the BigFile
*
* \param p_asset The asset to save
* \return The UUID the asset was saved under
*/
template<class ASSET>
UUID SaveAsset(ASSET& p_asset)
{
const eastl::vector<std::byte> flatbuffer = p_asset.Pack();
m_bigFile.SaveAssetFlatbuffer(p_asset.GetHeader().uuid, flatbuffer, p_asset.GetHardReferences(flatbuffer));
return p_asset.GetHeader().uuid;
}
/*
* Packs and saves several assets to the BigFile in a single SaveAssetFlatbuffers
*
* \param p_assets The assets to save
*/
void SaveAssets(const eastl::vector<AssetBase*>& p_assets)
{
eastl::vector<UUID> uuids;
eastl::vector<eastl::vector<std::byte>> flatbuffers;
eastl::vector<eastl::vector<UUID>> hardReferences;
uuids.reserve(p_assets.size());
flatbuffers.reserve(p_assets.size());
hardReferences.reserve(p_assets.size());
for (AssetBase* const asset: p_assets)
{
eastl::vector<std::byte> flatbuffer = asset->Pack();
hardReferences.push_back(asset->GetHardReferences(flatbuffer));
uuids.push_back(asset->GetHeader().uuid);
flatbuffers.push_back(std::move(flatbuffer));
}
m_bigFile.SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences);
} }
BigFile m_bigFile {File {BIGFILE_ENGINETESTS_LOCATION}}; BigFile m_bigFile {File {BIGFILE_ENGINETESTS_LOCATION}};
@@ -79,39 +34,11 @@ class BigFileFixture: public ::testing::Test
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, Clear_ShouldRemoveAllAssetsMetadataAndHardReferences) TEST_F(BigFileFixture, GetAssetFlatbuffer_ShouldReturnNulloptForNonExistentUUID)
{
AssetA referencedAsset;
referencedAsset.SetName("referenced");
SaveAsset(referencedAsset);
AssetB asset;
asset.SetName("hello");
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAsset.GetHeader().uuid};
SaveAsset(asset);
ASSERT_TRUE(m_bigFile.Has(referencedAsset.GetHeader().uuid));
ASSERT_TRUE(m_bigFile.Has(asset.GetHeader().uuid));
ASSERT_FALSE(m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid).empty());
m_bigFile.Clear();
EXPECT_FALSE(m_bigFile.Has(referencedAsset.GetHeader().uuid));
EXPECT_FALSE(m_bigFile.Has(asset.GetHeader().uuid));
EXPECT_TRUE(m_bigFile.GetAssetFlatbuffer(referencedAsset.GetHeader().uuid).empty());
EXPECT_TRUE(m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid).empty());
EXPECT_TRUE(m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid).empty());
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetFlatbuffer_ShouldReturnEmptyForNonExistentUUID)
{ {
const UUID uuid; const UUID uuid;
EXPECT_TRUE(m_bigFile.GetAssetFlatbuffer(uuid).empty()); EXPECT_FALSE(m_bigFile.GetAssetFlatbuffer(uuid).has_value());
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -122,422 +49,294 @@ TEST_F(BigFileFixture, GetAssetFlatbuffer_ShouldGetTheAssetFlatbuffer)
asset.SetName("hello"); asset.SetName("hello");
asset.GetAsset().health = 42; asset.GetAsset().health = 42;
asset.GetAsset().mana = 7; asset.GetAsset().mana = 7;
SaveAsset(asset); const eastl::vector<std::byte> flatbuffer = asset.Pack();
const eastl::vector<std::byte> savedFlatbuffer = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid); const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
EXPECT_EQ(savedFlatbuffer, asset.Pack()); .m_name = asset.GetHeader().name,
.m_typeID = asset.GetHeader().type_id,
.m_typeName = asset.GetHeader().type_name};
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer);
const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer = m_bigFile.GetAssetFlatbuffer(
asset.GetHeader().uuid);
ASSERT_TRUE(savedFlatbuffer.has_value());
EXPECT_EQ(*savedFlatbuffer, flatbuffer);
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldReturnEmptyForUUIDsThatDoNotExist) TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldOmitUUIDsThatDoNotExist)
{ {
AssetA assetA; AssetA assetA;
assetA.SetName("hello"); assetA.SetName("hello");
SaveAsset(assetA); const eastl::vector<std::byte> flatbufferA = assetA.Pack();
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
.m_name = assetA.GetHeader().name,
.m_typeID = assetA.GetHeader().type_id,
.m_typeName = assetA.GetHeader().type_name},
flatbufferA);
AssetA assetB; AssetA assetB;
assetB.SetName("world"); assetB.SetName("world");
SaveAsset(assetB); const eastl::vector<std::byte> flatbufferB = assetB.Pack();
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetB.GetHeader().uuid,
.m_name = assetB.GetHeader().name,
.m_typeID = assetB.GetHeader().type_id,
.m_typeName = assetB.GetHeader().type_name},
flatbufferB);
const eastl::array<UUID, 3> uuids {assetA.GetHeader().uuid, UUID {}, assetB.GetHeader().uuid}; const eastl::vector<UUID> uuids {assetA.GetHeader().uuid, UUID {}, assetB.GetHeader().uuid};
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids);
ASSERT_EQ(flatbuffers.size(), 3);
EXPECT_EQ(flatbuffers[0], assetA.Pack());
EXPECT_TRUE(flatbuffers[1].empty());
EXPECT_EQ(flatbuffers[2], assetB.Pack());
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldReturnEmptyForASingleUUIDThatDoesNotExist)
{
const eastl::array<UUID, 1> uuids {UUID {}};
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids);
ASSERT_EQ(flatbuffers.size(), 1);
EXPECT_TRUE(flatbuffers[0].empty());
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldDuplicateResultsForADuplicateUUID)
{
AssetA assetA;
assetA.SetName("hello");
SaveAsset(assetA);
const eastl::array<UUID, 2> uuids {assetA.GetHeader().uuid, assetA.GetHeader().uuid};
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids); const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids);
ASSERT_EQ(flatbuffers.size(), 2); ASSERT_EQ(flatbuffers.size(), 2);
EXPECT_EQ(flatbuffers[0], assetA.Pack()); EXPECT_TRUE((flatbuffers[0] == flatbufferA && flatbuffers[1] == flatbufferB) ||
EXPECT_EQ(flatbuffers[1], assetA.Pack()); (flatbuffers[0] == flatbufferB && flatbuffers[1] == flatbufferA));
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, GetAssetHardReference_ShouldReturnEmptyVectorForNonExistentUUID) TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldNotDuplicateResultsForADuplicateUUID)
{
AssetA assetA;
assetA.SetName("hello");
const eastl::vector<std::byte> flatbufferA = assetA.Pack();
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
.m_name = assetA.GetHeader().name,
.m_typeID = assetA.GetHeader().type_id,
.m_typeName = assetA.GetHeader().type_name},
flatbufferA);
const eastl::vector<UUID> uuids {assetA.GetHeader().uuid, assetA.GetHeader().uuid};
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids);
ASSERT_EQ(flatbuffers.size(), 1);
EXPECT_EQ(flatbuffers[0], flatbufferA);
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetMetadata_ShouldReturnNulloptForNonExistentUUID)
{ {
const UUID uuid; const UUID uuid;
const eastl::vector<UUID> hardReferences = m_bigFile.GetAssetHardReferences(uuid); EXPECT_FALSE(m_bigFile.GetAssetMetadata(uuid).has_value());
EXPECT_TRUE(hardReferences.empty());
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, GetAssetHardReference_ShouldGetTheAssetHardReferences) TEST_F(BigFileFixture, GetAssetMetadata_ShouldGetTheAssetMetadata)
{ {
AssetA referencedAssetX; AssetA asset;
referencedAssetX.SetName("referencedX");
AssetA referencedAssetY;
referencedAssetY.SetName("referencedY");
AssetB asset;
asset.SetName("hello"); asset.SetName("hello");
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid}; asset.GetAsset().health = 42;
asset.GetAsset().refs_a.push_back(SoftReference<AssetA> {referencedAssetY.GetHeader().uuid}); asset.GetAsset().mana = 7;
SaveAsset(asset); const eastl::vector<std::byte> flatbuffer = asset.Pack();
const eastl::vector<UUID> hardReferences = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid); const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
.m_name = asset.GetHeader().name,
.m_typeID = asset.GetHeader().type_id,
.m_typeName = asset.GetHeader().type_name};
EXPECT_THAT(hardReferences, ::testing::ElementsAre(referencedAssetX.GetHeader().uuid)); m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer);
const eastl::optional<AssetMetadata> savedMetadata = m_bigFile.GetAssetMetadata(asset.GetHeader().uuid);
ASSERT_TRUE(savedMetadata.has_value());
EXPECT_EQ(savedMetadata->m_uuid, metadata.m_uuid);
EXPECT_EQ(savedMetadata->m_name, metadata.m_name);
EXPECT_EQ(savedMetadata->m_typeID, metadata.m_typeID);
EXPECT_EQ(savedMetadata->m_typeName, metadata.m_typeName);
EXPECT_GT(savedMetadata->m_creationTime, Time {0});
EXPECT_GT(savedMetadata->m_modificationTime, Time {0});
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, GetAssetHardReferences_ShouldReturnEmptyVectorsForUUIDsThatDoNotExistOrHaveNoReferences) TEST_F(BigFileFixture, GetAssetMetadatas_ShouldOmitUUIDsThatDoNotExist)
{ {
AssetA referencedAsset; AssetA assetA;
referencedAsset.SetName("referenced"); assetA.SetName("hello");
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
.m_name = assetA.GetHeader().name,
.m_typeID = assetA.GetHeader().type_id,
.m_typeName = assetA.GetHeader().type_name},
assetA.Pack());
AssetA assetWithoutReferences; AssetA assetB;
assetWithoutReferences.SetName("noRefs"); assetB.SetName("world");
SaveAsset(assetWithoutReferences); m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetB.GetHeader().uuid,
.m_name = assetB.GetHeader().name,
AssetB assetWithReferences; .m_typeID = assetB.GetHeader().type_id,
assetWithReferences.SetName("withRefs"); .m_typeName = assetB.GetHeader().type_name},
assetWithReferences.GetAsset().ref_a = HardReference<AssetA> {referencedAsset.GetHeader().uuid}; assetB.Pack());
SaveAsset(assetWithReferences);
const UUID missingUUID; const UUID missingUUID;
const eastl::array<UUID, 3> uuids {assetWithoutReferences.GetHeader().uuid, const eastl::vector<UUID> uuids {assetA.GetHeader().uuid, missingUUID, assetB.GetHeader().uuid};
missingUUID,
assetWithReferences.GetHeader().uuid};
const eastl::vector<eastl::vector<UUID>> hardReferences = m_bigFile.GetAssetsHardReferences(uuids); const eastl::vector<AssetMetadata> metadatas = m_bigFile.GetAssetMetadatas(uuids);
ASSERT_EQ(hardReferences.size(), 3); ASSERT_EQ(metadatas.size(), 2);
EXPECT_TRUE(hardReferences[0].empty()); EXPECT_TRUE((metadatas[0].m_uuid == assetA.GetHeader().uuid && metadatas[0].m_name == "hello" &&
EXPECT_TRUE(hardReferences[1].empty()); metadatas[1].m_uuid == assetB.GetHeader().uuid && metadatas[1].m_name == "world") ||
ASSERT_EQ(hardReferences[2].size(), 1); (metadatas[0].m_uuid == assetB.GetHeader().uuid && metadatas[0].m_name == "world" &&
EXPECT_EQ(hardReferences[2][0], referencedAsset.GetHeader().uuid); metadatas[1].m_uuid == assetA.GetHeader().uuid && metadatas[1].m_name == "hello"));
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetHardReferences_ShouldDuplicateResultsForADuplicateUUID)
{
AssetA referencedAssetX;
referencedAssetX.SetName("referencedX");
AssetA referencedAssetY;
referencedAssetY.SetName("referencedY");
AssetB asset;
asset.SetName("hello");
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid};
asset.GetAsset().refs_a.push_back(SoftReference<AssetA> {referencedAssetY.GetHeader().uuid});
SaveAsset(asset);
const eastl::array<UUID, 2> uuids {asset.GetHeader().uuid, asset.GetHeader().uuid};
const eastl::vector<eastl::vector<UUID>> hardReferences = m_bigFile.GetAssetsHardReferences(uuids);
ASSERT_EQ(hardReferences.size(), 2);
for (const eastl::vector<UUID>& entry: hardReferences)
{
EXPECT_THAT(entry, ::testing::ElementsAre(referencedAssetX.GetHeader().uuid));
}
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetTime_ShouldReturnNulloptForNonExistentUUID)
{
const UUID uuid;
EXPECT_FALSE(m_bigFile.GetAssetTime(uuid).has_value());
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetTime_ShouldReturnCreationAndModificationTimeOnFirstSave)
{
AssetA asset;
asset.SetName("hello");
const std::uint64_t beforeSave = Time::Now().GetEpoch();
SaveAsset(asset);
const eastl::optional<BigFile::AssetTime> assetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
ASSERT_TRUE(assetTime.has_value());
constexpr std::uint64_t TOLERANCE_MICROSECONDS = 1'000'000;
const std::uint64_t creationEpoch = assetTime->m_creationTime.GetEpoch();
const std::uint64_t delta = creationEpoch > beforeSave ? creationEpoch - beforeSave : beforeSave - creationEpoch;
EXPECT_LE(delta, TOLERANCE_MICROSECONDS);
EXPECT_EQ(assetTime->m_creationTime, assetTime->m_modificationTime);
}
/****************************************************************************************/
TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldUpdateModificationTimeButNotCreationTimeOnSecondSave)
{
AssetA asset;
asset.SetName("hello");
SaveAsset(asset);
const eastl::optional<BigFile::AssetTime> firstAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
ASSERT_TRUE(firstAssetTime.has_value());
std::this_thread::sleep_for(std::chrono::milliseconds(20));
asset.GetAsset().health = 42;
SaveAsset(asset);
const eastl::optional<BigFile::AssetTime> secondAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
ASSERT_TRUE(secondAssetTime.has_value());
EXPECT_EQ(secondAssetTime->m_creationTime, firstAssetTime->m_creationTime);
EXPECT_GT(secondAssetTime->m_modificationTime.GetEpoch(), firstAssetTime->m_modificationTime.GetEpoch());
}
/****************************************************************************************/
TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldUpdateModificationTimeButNotCreationTimeOnSecondSave)
{
AssetA asset;
asset.SetName("hello");
SaveAssets({&asset});
const eastl::optional<BigFile::AssetTime> firstAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
ASSERT_TRUE(firstAssetTime.has_value());
std::this_thread::sleep_for(std::chrono::milliseconds(20));
asset.GetAsset().health = 42;
SaveAssets({&asset});
const eastl::optional<BigFile::AssetTime> secondAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
ASSERT_TRUE(secondAssetTime.has_value());
EXPECT_EQ(secondAssetTime->m_creationTime, firstAssetTime->m_creationTime);
EXPECT_GT(secondAssetTime->m_modificationTime.GetEpoch(), firstAssetTime->m_modificationTime.GetEpoch());
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetsTime_ShouldReturnNulloptForUUIDsThatDoNotExist)
{
AssetA asset;
asset.SetName("hello");
SaveAsset(asset);
const UUID missingUUID;
const eastl::array<UUID, 2> uuids {asset.GetHeader().uuid, missingUUID};
const eastl::vector<eastl::optional<BigFile::AssetTime>> times = m_bigFile.GetAssetsTime(uuids);
ASSERT_EQ(times.size(), 2);
EXPECT_TRUE(times[0].has_value());
EXPECT_FALSE(times[1].has_value());
}
/****************************************************************************************/
TEST_F(BigFileFixture, GetAssetsTime_ShouldDuplicateResultsForADuplicateUUID)
{
AssetA asset;
asset.SetName("hello");
SaveAsset(asset);
const eastl::optional<BigFile::AssetTime> expected = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
ASSERT_TRUE(expected.has_value());
const eastl::array<UUID, 2> uuids {asset.GetHeader().uuid, asset.GetHeader().uuid};
const eastl::vector<eastl::optional<BigFile::AssetTime>> times = m_bigFile.GetAssetsTime(uuids);
ASSERT_EQ(times.size(), 2);
ASSERT_TRUE(times[0].has_value());
ASSERT_TRUE(times[1].has_value());
EXPECT_EQ(*times[0], *expected);
EXPECT_EQ(*times[1], *expected);
}
/****************************************************************************************/
TEST_F(BigFileFixture, Clear_ShouldRemoveAssetTime)
{
AssetA asset;
asset.SetName("hello");
SaveAsset(asset);
ASSERT_TRUE(m_bigFile.GetAssetTime(asset.GetHeader().uuid).has_value());
m_bigFile.Clear();
EXPECT_FALSE(m_bigFile.GetAssetTime(asset.GetHeader().uuid).has_value());
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldSaveTheAsset) TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldSaveTheAsset)
{ {
AssetA referencedAsset; AssetA asset;
referencedAsset.SetName("referenced");
AssetB asset;
asset.SetName("hello"); asset.SetName("hello");
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAsset.GetHeader().uuid}; asset.GetAsset().health = 42;
SaveAsset(asset); asset.GetAsset().mana = 7;
const eastl::vector<std::byte> flatbuffer = asset.Pack();
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
.m_name = asset.GetHeader().name,
.m_typeID = asset.GetHeader().type_id,
.m_typeName = asset.GetHeader().type_name};
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer);
EXPECT_TRUE(m_bigFile.Has(asset.GetHeader().uuid)); EXPECT_TRUE(m_bigFile.Has(asset.GetHeader().uuid));
const eastl::vector<UUID> hardReferences = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
ASSERT_EQ(hardReferences.size(), 1);
EXPECT_EQ(hardReferences[0], referencedAsset.GetHeader().uuid);
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldUpdateTheDataWhenCalledTwice) TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldUpdateTheDataWhenCalledTwice)
{ {
AssetA referencedAssetX; const UUID uuid;
referencedAssetX.SetName("referencedX");
AssetA referencedAssetY; AssetA asset;
referencedAssetY.SetName("referencedY"); asset.GetAsset().health = 1;
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = uuid,
.m_name = "hello",
.m_typeID = AssetA::GetTypeID(),
.m_typeName = eastl::string {AssetA::GetTypeName()}},
asset.Pack());
AssetB asset; const eastl::optional<AssetMetadata> savedMetadata1 = m_bigFile.GetAssetMetadata(uuid);
asset.GetAsset().count = 1; ASSERT_TRUE(savedMetadata1.has_value());
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid}; EXPECT_EQ(savedMetadata1->m_name, "hello");
SaveAsset(asset); EXPECT_EQ(savedMetadata1->m_typeID, AssetA::GetTypeID());
EXPECT_EQ(savedMetadata1->m_typeName, eastl::string {AssetA::GetTypeName()});
EXPECT_EQ(savedMetadata1->m_modificationTime, savedMetadata1->m_creationTime);
const eastl::vector<std::byte> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid); const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(uuid);
ASSERT_FALSE(savedFlatbuffer1.empty()); ASSERT_TRUE(savedFlatbuffer1.has_value());
AssetB savedAsset1; AssetA savedAsset1;
savedAsset1.Unpack(savedFlatbuffer1); savedAsset1.Unpack(*savedFlatbuffer1);
EXPECT_EQ(savedAsset1.GetAsset().count, 1); EXPECT_EQ(savedAsset1.GetAsset().health, 1);
const eastl::vector<UUID> hardReferences1 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
ASSERT_EQ(hardReferences1.size(), 1);
EXPECT_EQ(hardReferences1[0], referencedAssetX.GetHeader().uuid);
std::this_thread::sleep_for(std::chrono::milliseconds(20)); std::this_thread::sleep_for(std::chrono::milliseconds(20));
asset.GetAsset().count = 2; asset.GetAsset().health = 2;
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetY.GetHeader().uuid}; m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = uuid,
SaveAsset(asset); .m_name = "world",
.m_typeID = AssetA::GetTypeID(),
.m_typeName = eastl::string {AssetA::GetTypeName()}},
asset.Pack());
const eastl::vector<std::byte> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid); const eastl::optional<AssetMetadata> savedMetadata2 = m_bigFile.GetAssetMetadata(uuid);
ASSERT_FALSE(savedFlatbuffer2.empty()); ASSERT_TRUE(savedMetadata2.has_value());
EXPECT_EQ(savedMetadata2->m_name, "world");
EXPECT_EQ(savedMetadata2->m_typeID, AssetA::GetTypeID());
EXPECT_EQ(savedMetadata2->m_typeName, eastl::string {AssetA::GetTypeName()});
EXPECT_GT(savedMetadata2->m_modificationTime, savedMetadata2->m_creationTime);
AssetB savedAsset2; EXPECT_LT(savedMetadata1->m_modificationTime, savedMetadata2->m_modificationTime);
savedAsset2.Unpack(savedFlatbuffer2);
EXPECT_EQ(savedAsset2.GetAsset().count, 2);
const eastl::vector<UUID> hardReferences2 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid); const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(uuid);
ASSERT_EQ(hardReferences2.size(), 1); ASSERT_TRUE(savedFlatbuffer2.has_value());
EXPECT_EQ(hardReferences2[0], referencedAssetY.GetHeader().uuid);
EXPECT_NE(hardReferences2[0], referencedAssetX.GetHeader().uuid); AssetA savedAsset2;
savedAsset2.Unpack(*savedFlatbuffer2);
EXPECT_EQ(savedAsset2.GetAsset().health, 2);
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldSaveTheAssets) TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldSaveTheAssets)
{ {
AssetA referencedAssetA; AssetA assetA;
referencedAssetA.SetName("referencedA");
AssetA referencedAssetB;
referencedAssetB.SetName("referencedB");
AssetB assetA;
assetA.SetName("hello"); assetA.SetName("hello");
assetA.GetAsset().count = 42; assetA.GetAsset().health = 42;
assetA.GetAsset().ref_a = HardReference<AssetA> {referencedAssetA.GetHeader().uuid};
AssetB assetB; AssetA assetB;
assetB.SetName("world"); assetB.SetName("world");
assetB.GetAsset().count = 7; assetB.GetAsset().health = 7;
assetB.GetAsset().ref_a = HardReference<AssetA> {referencedAssetB.GetHeader().uuid};
SaveAssets({&assetA, &assetB}); const eastl::vector<AssetMetadata> metadatas {AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
.m_name = assetA.GetHeader().name,
.m_typeID = assetA.GetHeader().type_id,
.m_typeName = assetA.GetHeader().type_name},
AssetMetadata {.m_uuid = assetB.GetHeader().uuid,
.m_name = assetB.GetHeader().name,
.m_typeID = assetB.GetHeader().type_id,
.m_typeName = assetB.GetHeader().type_name}};
const eastl::vector<eastl::vector<std::byte>> flatbuffers {assetA.Pack(), assetB.Pack()};
m_bigFile.SaveAssetFlatbuffers(metadatas, flatbuffers);
EXPECT_TRUE(m_bigFile.Has(assetA.GetHeader().uuid)); EXPECT_TRUE(m_bigFile.Has(assetA.GetHeader().uuid));
EXPECT_TRUE(m_bigFile.Has(assetB.GetHeader().uuid)); EXPECT_TRUE(m_bigFile.Has(assetB.GetHeader().uuid));
const eastl::vector<UUID> hardReferencesA = m_bigFile.GetAssetHardReferences(assetA.GetHeader().uuid);
ASSERT_EQ(hardReferencesA.size(), 1);
EXPECT_EQ(hardReferencesA[0], referencedAssetA.GetHeader().uuid);
const eastl::vector<UUID> hardReferencesB = m_bigFile.GetAssetHardReferences(assetB.GetHeader().uuid);
ASSERT_EQ(hardReferencesB.size(), 1);
EXPECT_EQ(hardReferencesB[0], referencedAssetB.GetHeader().uuid);
} }
/****************************************************************************************/ /****************************************************************************************/
TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldUpdateTheDataWhenCalledTwice) TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldUpdateTheDataWhenCalledTwice)
{ {
AssetA referencedAssetX; const UUID uuid;
referencedAssetX.SetName("referencedX");
AssetA referencedAssetY; AssetA asset;
referencedAssetY.SetName("referencedY"); asset.GetAsset().health = 1;
const eastl::vector<AssetMetadata> metadatas1 {AssetMetadata {.m_uuid = uuid,
.m_name = "hello",
.m_typeID = AssetA::GetTypeID(),
.m_typeName = eastl::string {AssetA::GetTypeName()}}};
const eastl::vector<eastl::vector<std::byte>> flatbuffers1 {asset.Pack()};
m_bigFile.SaveAssetFlatbuffers(metadatas1, flatbuffers1);
AssetB asset; const eastl::optional<AssetMetadata> savedMetadata1 = m_bigFile.GetAssetMetadata(uuid);
asset.GetAsset().count = 1; ASSERT_TRUE(savedMetadata1.has_value());
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid}; EXPECT_EQ(savedMetadata1->m_name, "hello");
SaveAssets({&asset}); EXPECT_EQ(savedMetadata1->m_modificationTime, savedMetadata1->m_creationTime);
eastl::vector<std::byte> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid); const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(uuid);
ASSERT_FALSE(savedFlatbuffer1.empty()); ASSERT_TRUE(savedFlatbuffer1.has_value());
AssetB savedAsset1; AssetA savedAsset1;
savedAsset1.Unpack(savedFlatbuffer1); savedAsset1.Unpack(*savedFlatbuffer1);
EXPECT_EQ(savedAsset1.GetAsset().count, 1); EXPECT_EQ(savedAsset1.GetAsset().health, 1);
const eastl::vector<UUID> hardReferences1 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
ASSERT_EQ(hardReferences1.size(), 1);
EXPECT_EQ(hardReferences1[0], referencedAssetX.GetHeader().uuid);
std::this_thread::sleep_for(std::chrono::milliseconds(20)); std::this_thread::sleep_for(std::chrono::milliseconds(20));
asset.GetAsset().count = 2; asset.GetAsset().health = 2;
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetY.GetHeader().uuid}; const eastl::vector<AssetMetadata> metadatas2 {AssetMetadata {.m_uuid = uuid,
SaveAssets({&asset}); .m_name = "world",
.m_typeID = AssetA::GetTypeID(),
.m_typeName = eastl::string {AssetA::GetTypeName()}}};
const eastl::vector<eastl::vector<std::byte>> flatbuffers2 {asset.Pack()};
m_bigFile.SaveAssetFlatbuffers(metadatas2, flatbuffers2);
const eastl::vector<std::byte> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid); const eastl::optional<AssetMetadata> savedMetadata2 = m_bigFile.GetAssetMetadata(uuid);
ASSERT_FALSE(savedFlatbuffer2.empty()); ASSERT_TRUE(savedMetadata2.has_value());
EXPECT_EQ(savedMetadata2->m_name, "world");
EXPECT_GT(savedMetadata2->m_modificationTime, savedMetadata2->m_creationTime);
AssetB savedAsset2; EXPECT_LT(savedMetadata1->m_modificationTime, savedMetadata2->m_modificationTime);
savedAsset2.Unpack(savedFlatbuffer2);
EXPECT_EQ(savedAsset2.GetAsset().count, 2);
const eastl::vector<UUID> hardReferences2 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid); const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(uuid);
ASSERT_EQ(hardReferences2.size(), 1); ASSERT_TRUE(savedFlatbuffer2.has_value());
EXPECT_EQ(hardReferences2[0], referencedAssetY.GetHeader().uuid);
AssetA savedAsset2;
savedAsset2.Unpack(*savedFlatbuffer2);
EXPECT_EQ(savedAsset2.GetAsset().health, 2);
} }
/****************************************************************************************/ /****************************************************************************************/
@@ -548,7 +347,14 @@ TEST_F(BigFileFixture, Has_ShouldReturnTrueIfTheAssetExists)
asset.SetName("hello"); asset.SetName("hello");
asset.GetAsset().health = 42; asset.GetAsset().health = 42;
asset.GetAsset().mana = 7; asset.GetAsset().mana = 7;
SaveAsset(asset); const eastl::vector<std::byte> flatbuffer = asset.Pack();
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
.m_name = asset.GetHeader().name,
.m_typeID = asset.GetHeader().type_id,
.m_typeName = asset.GetHeader().type_name};
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer);
EXPECT_TRUE(m_bigFile.Has(asset.GetHeader().uuid)); EXPECT_TRUE(m_bigFile.Has(asset.GetHeader().uuid));
} }
+1 -3
View File
@@ -10,6 +10,4 @@ bigfoot_create_package_tests(
"${BigfootDependencies}" "${BigfootDependencies}"
"") "")
bigfoot_create_bigfile("Tests/Bigfoot") bigfoot_create_bigfile("Tests/Bigfoot")
bigfoot_create_sasquatch_info()
@@ -6,8 +6,7 @@
*********************************************************************/ *********************************************************************/
#include <Engine/DataAccessor/DataAccessor.hpp> #include <Engine/DataAccessor/DataAccessor.hpp>
#include <EngineTests/DataAccessorMock.hpp> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace Bigfoot namespace Bigfoot
@@ -15,6 +14,34 @@ namespace Bigfoot
class DataAccessorFixture: public ::testing::Test class DataAccessorFixture: public ::testing::Test
{ {
protected: protected:
class DataAccessorMock: public DataAccessor
{
public:
MOCK_METHOD(eastl::optional<eastl::vector<std::byte>>,
GetAssetFlatbuffer,
(const UUID& p_uuid),
(const, override));
MOCK_METHOD(eastl::vector<eastl::vector<std::byte>>,
GetAssetFlatbuffers,
(eastl::span<const UUID> p_uuids),
(const, override));
MOCK_METHOD(eastl::optional<AssetMetadata>, GetAssetMetadata, (const UUID& p_uuid), (const, override));
MOCK_METHOD(eastl::vector<AssetMetadata>,
GetAssetMetadatas,
(eastl::span<const UUID> p_uuids),
(const, override));
MOCK_METHOD(void,
SaveAssetFlatbuffer,
(const AssetMetadata& p_metaData, const eastl::span<const std::byte> p_flatbuffer),
(override));
MOCK_METHOD(void,
SaveAssetFlatbuffers,
(eastl::span<const AssetMetadata> p_metadatas,
eastl::span<const eastl::vector<std::byte>> p_flatbuffers),
(override));
MOCK_METHOD(bool, Has, (const UUID& p_uuid), (const, override));
};
void SetUp() override void SetUp() override
{ {
m_original = g_dataAccessor; m_original = g_dataAccessor;
@@ -26,7 +53,7 @@ class DataAccessorFixture: public ::testing::Test
} }
DataAccessorMock m_accessor; DataAccessorMock m_accessor;
DataAccessor* m_original = nullptr; DataAccessor* m_original;
}; };
/****************************************************************************************/ /****************************************************************************************/
@@ -13,8 +13,6 @@ int main(int argc, char** argv)
{ {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
GTEST_FLAG_SET(death_test_style, "threadsafe");
BIGFOOT_NOT_OPTIMIZED_ONLY(::Bigfoot::Singleton<::Bigfoot::Log>::Lifetime m_lifetime); BIGFOOT_NOT_OPTIMIZED_ONLY(::Bigfoot::Singleton<::Bigfoot::Log>::Lifetime m_lifetime);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();

Some files were not shown because too many files have changed in this diff Show More