1 /*
2  * This software is licensed under the terms of the MIT License.
3  * See COPYING for further information.
4  * ---
5  * Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
6  * Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
7  */
8 
9 #ifndef IGUARD_resource_resource_h
10 #define IGUARD_resource_resource_h
11 
12 #include "taisei.h"
13 
14 #include "hashtable.h"
15 
16 typedef enum ResourceType {
17 	RES_TEXTURE,
18 	RES_ANIM,
19 	RES_SFX,
20 	RES_BGM,
21 	RES_BGM_METADATA,
22 	RES_SHADER_OBJECT,
23 	RES_SHADER_PROGRAM,
24 	RES_MODEL,
25 	RES_POSTPROCESS,
26 	RES_SPRITE,
27 	RES_FONT,
28 	RES_NUMTYPES,
29 } ResourceType;
30 
31 typedef enum ResourceFlags {
32 	RESF_OPTIONAL = 1,
33 	RESF_PERMANENT = 2,
34 	RESF_PRELOAD = 4,
35 	RESF_UNSAFE = 8,
36 } ResourceFlags;
37 
38 #define RESF_DEFAULT 0
39 
40 // Converts a vfs path into an abstract resource name to be used as the hashtable key.
41 // This method is optional, the default strategy is to take the path minus the prefix and extension.
42 // The returned name must be free()'d.
43 typedef char* (*ResourceNameProc)(const char *path);
44 
45 // Converts an abstract resource name into a vfs path from which a resource with that name could be loaded.
46 // The path may not actually exist or be usable. The load function (see below) shall deal with such cases.
47 // The returned path must be free()'d.
48 // May return NULL on failure, but does not have to.
49 typedef char* (*ResourceFindProc)(const char *name);
50 
51 // Tells whether the resource handler should attempt to load a file, specified by a vfs path.
52 typedef bool (*ResourceCheckProc)(const char *path);
53 
54 // Begins loading a resource specified by path.
55 // May be called asynchronously.
56 // The return value is not interpreted in any way, it's just passed to the corresponding ResourceEndLoadProc later.
57 typedef void* (*ResourceBeginLoadProc)(const char *path, uint flags);
58 
59 // Finishes loading a resource and returns a pointer to it.
60 // Will be called from the main thread only.
61 // On failure, must return NULL and not crash the program.
62 typedef void* (*ResourceEndLoadProc)(void *opaque, const char *path, uint flags);
63 
64 // Unloads a resource, freeing all allocated to it memory.
65 typedef void (*ResourceUnloadProc)(void *res);
66 
67 // Called during resource subsystem initialization
68 typedef void (*ResourceInitProc)(void);
69 
70 // Called after the resources and rendering subsystems have been initialized
71 typedef void (*ResourcePostInitProc)(void);
72 
73 // Called during resource subsystem shutdown
74 typedef void (*ResourceShutdownProc)(void);
75 
76 typedef struct ResourceHandler {
77 	ResourceType type;
78 
79 	char *typename;
80 	char *subdir;
81 
82 	struct {
83 		ResourceNameProc name;
84 		ResourceFindProc find;
85 		ResourceCheckProc check;
86 		ResourceBeginLoadProc begin_load;
87 		ResourceEndLoadProc end_load;
88 		ResourceUnloadProc unload;
89 		ResourceInitProc init;
90 		ResourcePostInitProc post_init;
91 		ResourceShutdownProc shutdown;
92 	} procs;
93 
94 	struct {
95 		ht_str2ptr_ts_t mapping;
96 	} private;
97 } ResourceHandler;
98 
99 typedef struct Resource {
100 	ResourceType type;
101 	ResourceFlags flags;
102 	void *data;
103 } Resource;
104 
105 void init_resources(void);
106 void load_resources(void);
107 void free_resources(bool all);
108 
109 
110 Resource *_get_resource(ResourceType type, const char *name, hash_t hash, ResourceFlags flags) attr_nonnull_all;
111 void *_get_resource_data(ResourceType type, const char *name, hash_t hash, ResourceFlags flags) attr_nonnull_all;
112 
113 attr_nonnull_all
get_resource(ResourceType type,const char * name,ResourceFlags flags)114 INLINE Resource *get_resource(ResourceType type, const char *name, ResourceFlags flags) {
115 	return _get_resource(type, name, ht_str2ptr_hash(name), flags);
116 }
117 
118 attr_nonnull_all
get_resource_data(ResourceType type,const char * name,ResourceFlags flags)119 INLINE void *get_resource_data(ResourceType type, const char *name, ResourceFlags flags) {
120 	return _get_resource_data(type, name, ht_str2ptr_hash(name), flags);
121 }
122 
123 void preload_resource(ResourceType type, const char *name, ResourceFlags flags);
124 void preload_resources(ResourceType type, ResourceFlags flags, const char *firstname, ...) attr_sentinel;
125 void *resource_for_each(ResourceType type, void *(*callback)(const char *name, Resource *res, void *arg), void *arg);
126 
127 void resource_util_strip_ext(char *path);
128 char *resource_util_basename(const char *prefix, const char *path);
129 const char *resource_util_filename(const char *path);
130 
131 #endif // IGUARD_resource_resource_h
132