1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
// This file is part of the 64k demo project.
// It tests the asset manager's ability to retrieve packed data.
// Verifies data integrity and size reporting.
#if defined(USE_TEST_ASSETS)
#include "test_assets.h"
#else
#include "generated/assets.h"
#endif /* defined(USE_TEST_ASSETS) */
#include <assert.h>
#include <stdio.h>
#include <string.h>
int main() {
printf("Running AssetManager test...\n");
size_t size = 0;
const uint8_t* data1 = GetAsset(AssetId::ASSET_TEST_ASSET_1, &size);
assert(data1 != nullptr);
assert(size > 0);
const char* expected_prefix = "This is a test asset file.";
if (strncmp((const char*)data1, expected_prefix, strlen(expected_prefix)) ==
0) {
printf("Asset content verification: SUCCESS\n");
} else {
printf("Asset content verification: FAILED\n");
printf("Got: %.*s\n", (int)size, (const char*)data1);
return 1;
}
// Test caching: request the same asset again and verify pointer is identical
size_t size2 = 0;
const uint8_t* data2 = GetAsset(AssetId::ASSET_TEST_ASSET_1, &size2);
assert(data2 != nullptr);
assert(size2 == size);
assert(data1 == data2); // Pointers should be the same for cached static asset
printf("Asset caching test: SUCCESS\n");
// Test ASSET_LAST_ID - should not return a valid asset
size_t last_id_size = 0;
const uint8_t* last_id_data = GetAsset(AssetId::ASSET_LAST_ID, &last_id_size);
assert(last_id_data == nullptr);
assert(last_id_size == 0);
printf("ASSET_LAST_ID test: SUCCESS\n");
printf("Asset size: %zu bytes\n", size);
// Test procedural asset
printf("\nRunning Procedural Asset test...\n");
size_t proc_size = 0;
const uint8_t* proc_data_1 =
GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size);
assert(proc_data_1 != nullptr);
assert(proc_size == 256 * 256 * 4); // 256x256 RGBA8
// Verify first few bytes are not all zero (noise should produce non-zero
// data)
bool non_zero_data = false;
for (size_t i = 0; i < 16; ++i) { // Check first 16 bytes
if (proc_data_1[i] != 0) {
non_zero_data = true;
break;
}
}
assert(non_zero_data);
printf("Procedural asset content verification: SUCCESS\n");
// Test DropAsset for procedural asset and re-generation
DropAsset(AssetId::ASSET_PROC_NOISE_256, proc_data_1);
// After dropping, GetAsset should generate new data
const uint8_t* proc_data_2 =
GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size);
assert(proc_data_2 != nullptr);
// assert(proc_data_1 != proc_data_2); // Removed: Allocator might reuse the
// same address
// Verify content again to ensure it was re-generated correctly
non_zero_data = false;
for (size_t i = 0; i < 16; ++i) {
if (proc_data_2[i] != 0) {
non_zero_data = true;
break;
}
}
assert(non_zero_data);
printf("Procedural asset DropAsset and re-generation test: SUCCESS\n");
// Test Unknown Procedural Function
printf("\nRunning Unknown Procedural Function test...\n");
size_t unknown_size = 0;
// This should print an error to stderr: "Error: Unknown procedural function..."
const uint8_t* unknown_data = GetAsset(AssetId::ASSET_PROC_UNKNOWN, &unknown_size);
assert(unknown_data == nullptr);
assert(unknown_size == 0);
printf("Unknown Procedural Function test: SUCCESS\n");
// Test Failing Procedural Function
printf("\nRunning Failing Procedural Function test...\n");
size_t fail_size = 0;
// This should print an error to stderr: "Error: Procedural generation failed..."
const uint8_t* fail_data = GetAsset(AssetId::ASSET_PROC_FAIL, &fail_size);
assert(fail_data == nullptr);
assert(fail_size == 0);
printf("Failing Procedural Function test: SUCCESS\n");
// Test Out-of-Bounds ID (beyond ASSET_LAST_ID)
// Casting to AssetId to suppress compiler warnings if checking strict enum types
printf("\nRunning Out-of-Bounds ID test...\n");
size_t oob_size = 0;
const uint8_t* oob_data = GetAsset((AssetId)((int)AssetId::ASSET_LAST_ID + 1), &oob_size);
assert(oob_data == nullptr);
assert(oob_size == 0);
printf("Out-of-Bounds ID test: SUCCESS\n");
// Test DropAsset edge cases
printf("\nRunning DropAsset edge cases test...\n");
// Invalid ID
DropAsset((AssetId)((int)AssetId::ASSET_LAST_ID + 1), nullptr);
// Mismatched pointer (should do nothing)
// We use proc_data_2 which is valid, but pass a different ID (e.g. ASSET_TEST_ASSET_1 which is static)
DropAsset(AssetId::ASSET_TEST_ASSET_1, proc_data_2);
// Verify proc_data_2 is still valid (by checking it's in cache).
// Note: GetAsset will just return the cached pointer. If DropAsset worked, it would have been cleared.
// But wait, DropAsset clears it from cache.
// The correct test for "mismatched pointer" is: pass the correct ID but WRONG pointer.
// This ensures we don't clear the cache if the user passes a stale/wrong pointer.
// Let's try to drop ASSET_PROC_NOISE_256 with a dummy pointer.
uint8_t dummy_ptr;
DropAsset(AssetId::ASSET_PROC_NOISE_256, &dummy_ptr);
// Check if asset is still in cache (should be, as we didn't drop the real one)
// We can't peek into g_asset_cache directly from here (it's static).
// But GetAsset should return the SAME pointer as proc_data_2 without re-generation.
// If it was dropped, GetAsset would re-generate and likely return a NEW pointer (new allocation).
const uint8_t* proc_data_3 = GetAsset(AssetId::ASSET_PROC_NOISE_256, nullptr);
assert(proc_data_3 == proc_data_2);
printf("DropAsset edge cases test: SUCCESS\n");
printf("Procedural Asset test PASSED\n");
printf("AssetManager test PASSED\n");
return 0;
}
|