Jackalope / jrf (public) (License: GPLv3 or later version) (since 2019-11-21) (hash sha1)
Libriary for reading and writing resource files: vertices, indices, meshes, images, models and scene data.
Supports reading from filesystem as well as from zip files.
It uses unique binary container format for those resources.
It is used in tool for converting popular formats like wavefront .obj file, TARGA image to this container and also used in resource loader as part of graphics framework.

It requires jlib libriary (see my user repositories) and libzip.
It is possible to remove libzip dependency.
List of commits:
Subject Hash Author Date (UTC)
ResourceHandle instead of ResourceUnion. e38ee04ee3b9d07118a9ce687d872bbe3ee9bcca Jackalope 2020-06-03 21:33:34
Convert array of images to image array. 3a46e488e402842fa713d4689ede7c948779c58d Jackalope 2020-06-03 01:47:05
Wavefront obj file converter. aa9023cf916fb5af85bc181a04c3e9252f97c098 Jackalope 2020-06-03 01:45:56
Forget to add config to installation! 9eb91f41049b2f0dcda1442c1750da4266e97376 Jackalope 2020-06-01 16:26:51
Better config, solving some issues with linking to jrf. 11ab2d21090cf684c08954ffabea0fe317afcc0a Jackalope 2020-06-01 16:24:51
Link jrf-shared to jlib-shared and jrf-static to jrf-static. b965856e0f894aa48555b9ccfef812bd15d2e3a6 Jackalope 2020-06-01 16:23:26
Version 0.2.2 d6aaf170a2db27ddcd429a89fd873341ea8a0082 Jackalope 2020-05-31 23:47:23
Move definitions to configuration file. a7b28738de65520eddd08cbd5d8c958fa16eedbe Jackalope 2020-05-31 21:45:28
CMake: build both shared and static with JRF_SHARED and JRF_STATIC options. When is subdirectory, select only one instead. 0dc49150959af90cd9210367a61113eca85650eb Jackalope 2020-05-31 21:38:50
CMake: version check changed. 500bcbe11c7f1e418e5d8116e89654d160c8dbd6 Jackalope 2020-05-31 21:37:47
Reduced warnings. 865f2c52ed60c37c050a1033905bb2df278032a0 Jackalope 2020-05-27 15:03:07
Make "find_package(jlib 0.2.0 REQUIRED)" optional 58bfc04890fab24adf5fc84963cb1a3bca7a8706 Jackalope 2020-05-24 16:39:14
changed notice about native compilation 0ed7e9e5e72a2d13e8add619f7999a51634f8e9c Jackalope 2020-05-24 16:37:54
Version 0.2.1 02d30aa69e9026a3f96d8549a297fccfbefbda47 Jackalope 2020-05-24 14:31:31
Why there is Doxyfile? 16cf9fe9e64353a2a717668cc4083465e2f8dff5 Jackalope 2020-05-24 14:25:20
Add license notice to CMakeLists.txt db2e7f018714cd2643c7928a8cce966d3da25059 Jackalope 2020-05-24 14:23:39
Make zip functionality optional 8e4409ba503637e5981f98c4df39ff4d649351de Jackalope 2020-05-24 14:23:18
remove LTO option 9b39746de0abc22a2ae8d2ce8c2db253dd9ad71a Jackalope 2020-05-24 13:41:20
more lost changes c52ad1ddc9fe753cb2ec6f388e4a88f9dfb0fadf Jackalope 2020-05-24 13:30:51
added lost changes 1e60b3d0d8ecda7995f3a102257d8f3c0ca4b15e Jackalope 2020-05-24 13:27:42
Commit e38ee04ee3b9d07118a9ce687d872bbe3ee9bcca - ResourceHandle instead of ResourceUnion.
Author: Jackalope
Author date (UTC): 2020-06-03 21:33
Committer name: Jackalope
Committer date (UTC): 2020-06-05 00:35
Parent(s): 3a46e488e402842fa713d4689ede7c948779c58d
Signing key:
Tree: 3e4c52b351a39674a3b07e2f8daff9ddab704751
File Lines added Lines deleted
include/jrf/jrf.h 14 14
include/jrf/mesh.h 1 1
include/jrf/read.h 65 64
include/jrf/scene.h 6 6
include/jrf/write.h 40 33
File include/jrf/jrf.h changed (mode: 100644) (index eabe4a1..d07ed38)
... ... namespace jrf
32 32 template<> struct Resource<ResourceType::MODEL> { using T = Model; }; template<> struct Resource<ResourceType::MODEL> { using T = Model; };
33 33 template<> struct Resource<ResourceType::SCENE> { using T = Scene; }; template<> struct Resource<ResourceType::SCENE> { using T = Scene; };
34 34
35 union ResourceUnion {
36 Image image;
37 Vertices vertices;
38 Indices indices;
39 Mesh mesh;
40 Model model;
41 Scene scene;
35 union ResourceHandle {
36 Image *p_image;
37 Vertices *p_vertices;
38 Indices *p_indices;
39 Mesh *p_mesh;
40 Model *p_model;
41 Scene *p_scene;
42 42 }; };
43 43
44 44 static const constexpr union { static const constexpr union {
 
... ... namespace jrf
54 54 ResourceType type; ResourceType type;
55 55 }; };
56 56
57 void inline destroy(ResourceType type, ResourceUnion *p_ru) {
57 void inline destroy(ResourceType type, ResourceHandle rh) {
58 58 switch(type) { switch(type) {
59 case ResourceType::IMAGE: p_ru->image .destroy(); break;
60 case ResourceType::VERTICES: p_ru->vertices.destroy(); break;
61 case ResourceType::INDICES: p_ru->indices .destroy(); break;
62 case ResourceType::MESH: p_ru->mesh .destroy(); break;
63 case ResourceType::MODEL: p_ru->model .destroy(); break;
64 case ResourceType::SCENE: p_ru->scene .destroy(); break;
59 case ResourceType::IMAGE: rh.p_image ->destroy(); break;
60 case ResourceType::VERTICES: rh.p_vertices->destroy(); break;
61 case ResourceType::INDICES: rh.p_indices ->destroy(); break;
62 case ResourceType::MESH: rh.p_mesh ->destroy(); break;
63 case ResourceType::MODEL: rh.p_model ->destroy(); break;
64 case ResourceType::SCENE: rh.p_scene ->destroy(); break;
65 65 default: return; default: return;
66 66 } }
67 67 } }
File include/jrf/mesh.h changed (mode: 100644) (index e2acfcb..781910f)
... ... struct jrf::Indices {
79 79 void destroy() { void destroy() {
80 80 jl::deallocate(&p_data); jl::deallocate(&p_data);
81 81 } }
82 uint8_t *p_data;
82 void *p_data;
83 83 uint64_t size; uint64_t size;
84 84 IndexFormat format; IndexFormat format;
85 85 }; };
File include/jrf/read.h changed (mode: 100644) (index 9a42965..a409cfa)
23 23 #include <jlib/io_agent_mem_ro.h> #include <jlib/io_agent_mem_ro.h>
24 24 #include <jlib/fs.h> #include <jlib/fs.h>
25 25
26 namespace jrf {
26 namespace jrf::detail
27 {
27 28 template<typename IO = jl::io_agent> [[nodiscard]] template<typename IO = jl::io_agent> [[nodiscard]]
28 29 Result read_str(IO *p_io, jl::string *p_dst) { Result read_str(IO *p_io, jl::string *p_dst) {
29 30 jl::darray<char> path_tmp; jl::darray<char> path_tmp;
 
... ... namespace jrf {
39 40 *p_dst = {path_tmp.begin(), path_tmp.end()}; *p_dst = {path_tmp.begin(), path_tmp.end()};
40 41 return Result::SUCCESS; return Result::SUCCESS;
41 42 } }
42 template<typename T, typename IO = jl::io_agent> [[nodiscard]]
43 Result read(Data<T> *p, IO *p_io) {
44 if (p_io->read(&p->mode, sizeof(p->mode)) != sizeof(p->mode))
43 template<typename IO = jl::io_agent> [[nodiscard]]
44 Result read(Image *p, IO *p_mediator) {
45 if (p_mediator->read(&p->extent, sizeof(p->extent)) != sizeof(p->extent))
46 return Result::MEDIATOR_ERROR;
47 if (p_mediator->read(&p->format, sizeof(p->format)) != sizeof(p->format))
48 return Result::MEDIATOR_ERROR;
49 p->size = p->extent.size();
50 if (p->size == 0) {
51 p->p_pixels = nullptr;
52 return Result::FILE_NO_DATA;
53 }
54 if (not jl::allocate_bytes(&p->p_pixels, p->size))
55 return Result::ALLOCATION_FAIL;
56 if (p_mediator->read(p->p_pixels, p->size) != int64_t(p->size)) {
57 p->destroy();
45 58 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
46 switch(p->mode) {
47 case ResourceMode::NONE: break;
48 case ResourceMode::DATA: {
49 Result res = read(&p->u.data, p_io);
50 if (res != Result::SUCCESS)
51 return res;
52 } break;
53 case ResourceMode::PATH: {
54 auto res = read_str(p_io, &p->u.path);
55 if (res != Result::SUCCESS)
56 return res;
57 }
58 59 } }
59 60 return Result::SUCCESS; return Result::SUCCESS;
60 61 } }
 
... ... namespace jrf {
105 106 return Result::SUCCESS; return Result::SUCCESS;
106 107 } }
107 108 template<typename IO = jl::io_agent> [[nodiscard]] template<typename IO = jl::io_agent> [[nodiscard]]
109 Result read(Mesh *p, IO *p_mediator);
110
111 template<typename T, typename IO = jl::io_agent> [[nodiscard]]
112 Result read(Data<T> *p, IO *p_io) {
113 if (p_io->read(&p->mode, sizeof(p->mode)) != sizeof(p->mode))
114 return Result::MEDIATOR_ERROR;
115 switch(p->mode) {
116 case ResourceMode::NONE: break;
117 case ResourceMode::DATA: {
118 Result res = read(&p->u.data, p_io);
119 if (res != Result::SUCCESS)
120 return res;
121 } break;
122 case ResourceMode::PATH: {
123 auto res = read_str(p_io, &p->u.path);
124 if (res != Result::SUCCESS)
125 return res;
126 }
127 }
128 return Result::SUCCESS;
129 }
130 template<typename IO> [[nodiscard]]
108 131 Result read(Mesh *p, IO *p_mediator) { Result read(Mesh *p, IO *p_mediator) {
109 132 Result res; Result res;
110 133 res = read(&p->vert, p_mediator); res = read(&p->vert, p_mediator);
 
... ... namespace jrf {
116 139 return res; return res;
117 140 } }
118 141 template<typename IO = jl::io_agent> [[nodiscard]] template<typename IO = jl::io_agent> [[nodiscard]]
119 Result read(Image *p, IO *p_mediator) {
120 if (p_mediator->read(&p->extent, sizeof(p->extent)) != sizeof(p->extent))
121 return Result::MEDIATOR_ERROR;
122 if (p_mediator->read(&p->format, sizeof(p->format)) != sizeof(p->format))
123 return Result::MEDIATOR_ERROR;
124 p->size = p->extent.size();
125 if (p->size == 0) {
126 p->p_pixels = nullptr;
127 return Result::FILE_NO_DATA;
128 }
129 if (not jl::allocate_bytes(&p->p_pixels, p->size))
130 return Result::ALLOCATION_FAIL;
131 if (p_mediator->read(p->p_pixels, p->size) != int64_t(p->size)) {
132 p->destroy();
133 return Result::MEDIATOR_ERROR;
134 }
135 return Result::SUCCESS;
136 }
137 template<typename IO = jl::io_agent> [[nodiscard]]
138 142 Result read(Model *p, IO *p_mediator) { Result read(Model *p, IO *p_mediator) {
139 143 Result res; Result res;
140 144 res = read(&p->mesh, p_mediator); res = read(&p->mesh, p_mediator);
 
... ... namespace jrf {
151 155 if (res != Result::SUCCESS) if (res != Result::SUCCESS)
152 156 return res; return res;
153 157 auto *p_io = jl::io_agent_p_alt_cast(p_mediator); auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
154 if (not p_io->read_items(&p->options.pos))
158 if (not p_io->read_items(&p->options.position))
155 159 goto CANCEL; goto CANCEL;
156 if (not p_io->read_items(&p->options.shift))
160 if (not p_io->read_items(&p->options.offset))
157 161 goto CANCEL; goto CANCEL;
158 162 if (not p_io->read_items(&p->options.transform)) if (not p_io->read_items(&p->options.transform))
159 163 goto CANCEL; goto CANCEL;
 
... ... CANCEL:
165 169 template<typename IO = jl::io_agent> [[nodiscard]] template<typename IO = jl::io_agent> [[nodiscard]]
166 170 Result read(Scene *p, IO *p_mediator) { Result read(Scene *p, IO *p_mediator) {
167 171 auto *p_io = jl::io_agent_p_alt_cast(p_mediator); auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
168 if (not p_io->read_items(&p->options.shift))
172 if (not p_io->read_items(&p->options.offset))
169 173 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
170 if (not p_io->read_items(&p->options.shift_po2))
174 if (not p_io->read_items(&p->options.offset_shift))
171 175 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
172 176 uint64_t entry_count; uint64_t entry_count;
173 177 if (not p_io->read_items(&entry_count)) if (not p_io->read_items(&entry_count))
 
... ... CANCEL:
189 193 } }
190 194 return Result::SUCCESS; return Result::SUCCESS;
191 195 } }
192 }
193
194 namespace jrf::details {
195 template<typename IO = jl::io_agent>
196 [[nodiscard]] inline
197 Result read(IO *p_io, ResourceType type, ResourceUnion *p_ru) {
196 template<typename IO = jl::io_agent> [[nodiscard]]
197 Result read(IO *p_io, ResourceType type, ResourceHandle rh) {
198 198 switch(type) { switch(type) {
199 case ResourceType::IMAGE: return read(&p_ru->image, p_io);
200 case ResourceType::VERTICES: return read(&p_ru->vertices, p_io);
201 case ResourceType::INDICES: return read(&p_ru->indices, p_io);
202 case ResourceType::MESH: return read(&p_ru->mesh, p_io);
203 case ResourceType::MODEL: return read(&p_ru->model, p_io);
204 case ResourceType::SCENE: return read(&p_ru->scene, p_io);
199 case ResourceType::IMAGE: return read(rh.p_image, p_io);
200 case ResourceType::VERTICES: return read(rh.p_vertices, p_io);
201 case ResourceType::INDICES: return read(rh.p_indices, p_io);
202 case ResourceType::MESH: return read(rh.p_mesh, p_io);
203 case ResourceType::MODEL: return read(rh.p_model, p_io);
204 case ResourceType::SCENE: return read(rh.p_scene, p_io);
205 205 default: return Result::UNKNOWN_RESOURCE_TYPE; default: return Result::UNKNOWN_RESOURCE_TYPE;
206 206 } }
207 207 } }
208 208 } }
209 209 namespace jrf namespace jrf
210 210 { {
211 template<typename IO = jl::io_agent> [[nodiscard]] inline
212 Result read(IO *p_mediator, ResourceUnion *p_ru) {
211 template<typename IO = jl::io_agent> [[nodiscard]]
212 Result read(IO *p_mediator, ResourceHandle rh, ResourceType *p_out_type) {
213 213 EntryHeader header; EntryHeader header;
214 214 if (not p_mediator->read(&header, sizeof (EntryHeader))) if (not p_mediator->read(&header, sizeof (EntryHeader)))
215 215 return MEDIATOR_ERROR; return MEDIATOR_ERROR;
216 216 if (header.magic != MAGIC.integer) if (header.magic != MAGIC.integer)
217 217 return Result::FILE_WRONG_HEADER; return Result::FILE_WRONG_HEADER;
218 return details::read(p_mediator, header.type, p_ru);
218 *p_out_type = header.type;
219 return detail::read(p_mediator, header.type, rh);
219 220 } }
220 template<ResourceType RT, typename IO = jl::io_agent> [[nodiscard]] inline
221 template<ResourceType RT, typename IO = jl::io_agent> [[nodiscard]]
221 222 Result read(IO *p_io, typename Resource<RT>::T *p_resource) { Result read(IO *p_io, typename Resource<RT>::T *p_resource) {
222 223 EntryHeader header; EntryHeader header;
223 224 if (not p_io->read(&header, sizeof (EntryHeader))) if (not p_io->read(&header, sizeof (EntryHeader)))
 
... ... namespace jrf
226 227 return Result::FILE_WRONG_HEADER; return Result::FILE_WRONG_HEADER;
227 228 if (header.type != RT) if (header.type != RT)
228 229 return Result::RESOURCE_TYPE_MISMATCH; return Result::RESOURCE_TYPE_MISMATCH;
229 return read(p_resource, p_io);
230 return detail::read(p_resource, p_io);
230 231 } }
231 template<ResourceType RT> [[nodiscard]] inline
232 template<ResourceType RT> [[nodiscard]]
232 233 Result read(typename Resource<RT>::T *p_resource, const char *p_file_path) { Result read(typename Resource<RT>::T *p_resource, const char *p_file_path) {
233 234 uint8_t *f_data; uint8_t *f_data;
234 235 uint64_t fsize; uint64_t fsize;
 
... ... namespace jrf
268 269 } }
269 270 //single path - file path, two paths - zip and file in zip //single path - file path, two paths - zip and file in zip
270 271 template<typename ... PATHS> [[nodiscard]] inline template<typename ... PATHS> [[nodiscard]] inline
271 Result read(ResourceType type, ResourceUnion *p_ru, PATHS ... paths) {
272 Result read(ResourceType type, ResourceHandle rh, PATHS ... paths) {
272 273 switch(type) { switch(type) {
273 274 case ResourceType::IMAGE: case ResourceType::IMAGE:
274 return read<ResourceType::IMAGE> (&p_ru->image, paths...);
275 return read<ResourceType::IMAGE> (rh.p_image, paths...);
275 276 case ResourceType::VERTICES: case ResourceType::VERTICES:
276 return read<ResourceType::VERTICES>(&p_ru->vertices, paths...);
277 return read<ResourceType::VERTICES>(rh.p_vertices, paths...);
277 278 case ResourceType::INDICES: case ResourceType::INDICES:
278 return read<ResourceType::INDICES> (&p_ru->indices, paths...);
279 return read<ResourceType::INDICES> (rh.p_indices, paths...);
279 280 case ResourceType::MESH: case ResourceType::MESH:
280 return read<ResourceType::MESH> (&p_ru->mesh, paths...);
281 return read<ResourceType::MESH> (rh.p_mesh, paths...);
281 282 case ResourceType::MODEL: case ResourceType::MODEL:
282 return read<ResourceType::MODEL> (&p_ru->model, paths...);
283 return read<ResourceType::MODEL> (rh.p_model, paths...);
283 284 case ResourceType::SCENE: case ResourceType::SCENE:
284 return read<ResourceType::SCENE> (&p_ru->scene, paths...);
285 return read<ResourceType::SCENE> (rh.p_scene, paths...);
285 286 default: return Result::UNKNOWN_RESOURCE_TYPE; default: return Result::UNKNOWN_RESOURCE_TYPE;
286 287 } }
287 288 } }
File include/jrf/scene.h changed (mode: 100644) (index 327a81f..b51b3e0)
... ... namespace jrf {
28 28 } }
29 29 struct jrf::SceneEntryOptions { struct jrf::SceneEntryOptions {
30 30 void set_default() { void set_default() {
31 pos = {};
32 shift = {};
31 position = {};
32 offset = {};
33 33 transform = {}; transform = {};
34 34 transform[0] = transform[5] = transform[10] = transform[15] = 1; transform[0] = transform[5] = transform[10] = transform[15] = 1;
35 35 } }
36 jl::array<float, 3> pos; ///< position
37 jl::array<int32_t,3> shift; ///< shift of position
36 jl::array<float, 3> position;
37 jl::array<int32_t,3> offset; ///< offset of position
38 38 jl::array<float, 16> transform; ///< transformation matrix 4x4 jl::array<float, 16> transform; ///< transformation matrix 4x4
39 39 }; };
40 40 struct jrf::SceneEntry { struct jrf::SceneEntry {
 
... ... struct jrf::SceneOptions {
48 48 void set_default() { void set_default() {
49 49 *this = {}; *this = {};
50 50 } }
51 jl::array<int32_t, 3> shift; ///< global shift of scene
52 int32_t shift_po2; ///< Power of two
51 jl::array<int32_t, 3> offset; ///< global offset of scene
52 int32_t offset_shift; ///< Power of two
53 53 }; };
54 54 struct jrf::Scene { struct jrf::Scene {
55 55 void destroy() { void destroy() {
File include/jrf/write.h changed (mode: 100644) (index f667f9e..7555f26)
20 20 #include "jrf.h" #include "jrf.h"
21 21 #include <jlib/io_agent.h> #include <jlib/io_agent.h>
22 22
23 namespace jrf
23 namespace jrf::detail
24 24 { {
25 25 template<typename IO = jl::io_agent> [[nodiscard]] template<typename IO = jl::io_agent> [[nodiscard]]
26 26 Result write(const Image &im, IO *p_mediator) { Result write(const Image &im, IO *p_mediator) {
 
... ... namespace jrf
44 44
45 45 return Result::SUCCESS; return Result::SUCCESS;
46 46 } }
47 template<typename IO = jl::io_agent> [[nodiscard]]
48 Result write(const Vertices &v, IO *p_mediator) {
49 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
50 if (not p_io->write_items(&v.attributes))
51 return Result::MEDIATOR_ERROR;
52 if (not p_io->write_items(&v.vecs_count))
53 return Result::MEDIATOR_ERROR;
54 if (not p_io->write_bytes(v.p_data, v.data_size))
55 return Result::MEDIATOR_ERROR;
56 return Result::SUCCESS;
57 }
58 template<typename IO = jl::io_agent> [[nodiscard]]
59 Result write(const Mesh &m, IO *p_mediator);
60
47 61 template<typename T, typename IO = jl::io_agent> [[nodiscard]] template<typename T, typename IO = jl::io_agent> [[nodiscard]]
48 62 Result write(const Data<T> &d, IO *p_io) { Result write(const Data<T> &d, IO *p_io) {
49 63 if (p_io->write(&d.mode, sizeof(d.mode)) != sizeof(d.mode)) if (p_io->write(&d.mode, sizeof(d.mode)) != sizeof(d.mode))
 
... ... namespace jrf
63 77 } }
64 78 return Result::SUCCESS; return Result::SUCCESS;
65 79 } }
66 template<typename IO = jl::io_agent> [[nodiscard]]
67 Result write(const Vertices &v, IO *p_mediator) {
68 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
69 if (not p_io->write_items(&v.attributes))
70 return Result::MEDIATOR_ERROR;
71 if (not p_io->write_items(&v.vecs_count))
72 return Result::MEDIATOR_ERROR;
73 if (not p_io->write_bytes(v.p_data, v.data_size))
74 return Result::MEDIATOR_ERROR;
75 return Result::SUCCESS;
76 }
77 template<typename IO = jl::io_agent> [[nodiscard]]
80 template<typename IO> [[nodiscard]]
78 81 Result write(const Mesh &m, IO *p_mediator) { Result write(const Mesh &m, IO *p_mediator) {
79 82 Result res = write(m.vert, p_mediator); Result res = write(m.vert, p_mediator);
80 83 if (res != Result::SUCCESS) if (res != Result::SUCCESS)
 
... ... namespace jrf
94 97 != int64_t(s.model_path.size())) != int64_t(s.model_path.size()))
95 98 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
96 99 auto *p_io = jl::io_agent_p_alt_cast(p_mediator); auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
97 if (not p_io->write_items(&s.options.pos))
100 if (not p_io->write_items(&s.options.position))
98 101 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
99 if (not p_io->write_items(&s.options.shift))
102 if (not p_io->write_items(&s.options.offset))
100 103 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
101 104 if (not p_io->write_items(&s.options.transform)) if (not p_io->write_items(&s.options.transform))
102 105 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
 
... ... namespace jrf
105 108 template<typename IO = jl::io_agent> [[nodiscard]] template<typename IO = jl::io_agent> [[nodiscard]]
106 109 Result write(const Scene &s, IO *p_mediator) { Result write(const Scene &s, IO *p_mediator) {
107 110 auto *p_io = jl::io_agent_p_alt_cast(p_mediator); auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
108 if (not p_io->write_items(&s.options.shift))
111 if (not p_io->write_items(&s.options.offset))
109 112 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
110 if (not p_io->write_items(&s.options.shift_po2))
113 if (not p_io->write_items(&s.options.offset_shift))
111 114 return Result::MEDIATOR_ERROR; return Result::MEDIATOR_ERROR;
112 115 size_t entry_count = s.entries.count(); size_t entry_count = s.entries.count();
113 116 if (not p_io->write_items(&entry_count)) if (not p_io->write_items(&entry_count))
 
... ... namespace jrf
119 122 } }
120 123 return Result::SUCCESS; return Result::SUCCESS;
121 124 } }
125 }
126 namespace jrf
127 {
128 template<ResourceType RT, typename Resource, typename IO = jl::io_agent>
129 [[nodiscard]]
130 Result write(IO *p_io, const Resource &resource) {
131 EntryHeader header;
132 header.magic = MAGIC.integer;
133 header.type = RT;
134 if (p_io->write(&header, sizeof (EntryHeader)) != sizeof(EntryHeader))
135 return MEDIATOR_ERROR;
136 return detail::write(resource, p_io);
137 }
122 138 template<typename IO = jl::io_agent> [[nodiscard]] template<typename IO = jl::io_agent> [[nodiscard]]
123 Result write(IO *p_io, ResourceType type, ResourceUnion *p_ru) {
139 Result write(IO *p_io, ResourceType type, const ResourceHandle rh) {
124 140 switch(type) { switch(type) {
125 141 case ResourceType::IMAGE: case ResourceType::IMAGE:
126 return write<ResourceType::IMAGE> (p_io, p_ru->image);
142 return write<ResourceType::IMAGE> (p_io, *rh.p_image);
127 143 case ResourceType::VERTICES: case ResourceType::VERTICES:
128 return write<ResourceType::VERTICES>(p_io, p_ru->vertices);
144 return write<ResourceType::VERTICES>(p_io, *rh.p_vertices);
129 145 case ResourceType::INDICES: case ResourceType::INDICES:
130 return write<ResourceType::INDICES> (p_io, p_ru->indices);
146 return write<ResourceType::INDICES> (p_io, *rh.p_indices);
131 147 case ResourceType::MESH: case ResourceType::MESH:
132 return write<ResourceType::MESH> (p_io, p_ru->mesh);
148 return write<ResourceType::MESH> (p_io, *rh.p_mesh);
133 149 case ResourceType::MODEL: case ResourceType::MODEL:
134 return write<ResourceType::MODEL> (p_io, p_ru->model);
150 return write<ResourceType::MODEL> (p_io, *rh.p_model);
135 151 case ResourceType::SCENE: case ResourceType::SCENE:
136 return write<ResourceType::SCENE> (p_io, p_ru->scene);
152 return write<ResourceType::SCENE> (p_io, *rh.p_scene);
137 153 default: default:
138 154 return Result::UNKNOWN_RESOURCE_TYPE; return Result::UNKNOWN_RESOURCE_TYPE;
139 155 } }
140 156 } }
141 template<ResourceType RT, typename Resource, typename IO = jl::io_agent>
142 [[nodiscard]] Result write(IO *p_io, const Resource &resource) {
143 EntryHeader header;
144 header.magic = MAGIC.integer;
145 header.type = RT;
146 if (p_io->write(&header, sizeof (EntryHeader)) != sizeof(EntryHeader))
147 return MEDIATOR_ERROR;
148 return write(resource, p_io);
149 }
150 157 } }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/Jackalope/jrf

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jrf

Clone this repository using git:
git clone git://git.rocketgit.com/user/Jackalope/jrf

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main