blob: 09260e0ee1220c00303006cf7cee98fab7018956 (
plain) (
blame)
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
|
#include "asset.hpp"
extern "C" {
#include "memory.h"
#include "pack.h"
#include "plat.h"
#include "str.h"
}
#define max_asset_types 32
struct RLoader {
char magic[4];
Asset_Loader* loader;
};
struct Manager {
RLoader loaders[max_asset_types];
Manager() {
int i;
for (i = 0; i < max_asset_types; i++) {
loaders[i].loader = 0;
}
}
RLoader* find_loader(const char* magic) {
uint32_t hash = hash_string(magic);
int bucket = (int)(hash % max_asset_types);
int i;
for (i = 0; i < max_asset_types; i++) {
RLoader& e = loaders[bucket];
if (!e.loader || (
e.magic[0] == magic[0] &&
e.magic[1] == magic[1] &&
e.magic[2] == magic[2] &&
e.magic[3] == magic[3]
)) return &e;
bucket = (bucket + 1) % max_asset_types;
}
return 0;
}
Asset_Loader& get_loader(const char* magic) {
RLoader* r = find_loader(magic);
assert(r != 0 && r->loader != 0);
return *r->loader;
}
void set_loader(const char* magic, Asset_Loader* l) {
RLoader* r = find_loader(magic);
assert(r != 0 && r->loader == 0);
r->magic[0] = magic[0];
r->magic[1] = magic[1];
r->magic[2] = magic[2];
r->magic[3] = magic[3];
r->loader = l;
}
} manager;
void register_asset_loader(
const char* magic,
Asset_Loader* loader
) {
manager.set_loader(magic, loader);
}
void Asset_Arena::init(Arena* arena, const char* pack_name) {
p = pack_open(pack_name, arena);
a = arena;
assets = 0;
}
void Asset_Arena::destroy() {
Asset* a;
for (a = assets; a; a = a->next) {
a->unload(a->loader);
}
pack_close(p);
}
void Asset_Arena::claim(Asset* a) {
if (assets) {
a->next = assets;
assets = a;
} else assets = a;
}
Asset* Asset_Arena::load(const char* name) {
char magic[4];
Pack_File* f = pack_open_file(p, name);
if (!f) return 0;
pack_read(f, magic, 4);
pack_seek(f, 0, seek_rel_start);
Asset_Loader& loader = manager.get_loader(magic);
Asset* asset = loader.load(a, f);
asset->loader = &loader;
pack_close_file(f);
claim(asset);
return asset;
}
|