Tissue Forge C++ 0.2.1
Interactive, particle-based physics, chemistry and biology modeling and simulation environment
Loading...
Searching...
No Matches
tf_io.h
1/*******************************************************************************
2 * This file is part of Tissue Forge.
3 * Copyright (c) 2022-2024 T.J. Sego
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 ******************************************************************************/
19
20#ifndef _SOURCE_IO_TF_IO_H_
21#define _SOURCE_IO_TF_IO_H_
22
23#include <tf_port.h>
24#include <tf_config.h>
25#include <types/tf_types.h>
26
27#include <map>
28#include <unordered_map>
29#include <set>
30#include <unordered_set>
31#include <string>
32#include <memory>
33
34
35#define TF_IOTOEASY(fileElement, metaData, key, member) {\
36 ::TissueForge::io::IOElement _fe = ::TissueForge::io::IOElement::create(); \
37 if(::TissueForge::io::toFile(member, metaData, _fe) != S_OK) \
38 return E_FAIL; \
39 fileElement.addChild(_fe, key);}
40
41#define TF_IOFROMEASY(fileElement, metaData, key, member_p) {\
42 ::TissueForge::io::IOChildMap _children = ::TissueForge::io::IOElement::children(fileElement); \
43 ::TissueForge::io::IOChildMap::const_iterator _feItr = _children.find(key); \
44 if(_feItr == _children.end() || ::TissueForge::io::fromFile(_feItr->second, metaData, member_p) != S_OK) \
45 return E_FAIL; \
46 }
47
48
49namespace TissueForge::io {
50
51
57 template <typename T>
58 struct _IOElementT {
59 std::string type;
60 std::string value;
61 T parent;
62 std::unordered_map<std::string, T> children;
63 };
65 using IOChildMap = std::unordered_map<std::string, struct IOElement>;
66
71 struct IOElement {
72 std::weak_ptr<_IOElement> el;
73
74 IOElement() {}
75 IOElement(const IOElement &other) {
76 el = other.el;
77 }
78
79 static IOElement create() {
80 IOElement result;
81 result._init();
82 return result;
83 }
84
85 IOElement clone() {
86 IOElement result = IOElement::create();
87 result._el = this->_el;
88 result.el = this->_el;
89 return result;
90 }
91
92 std::shared_ptr<_IOElement> get() {
93 if(el.expired())
94 _init();
95 return el.lock();
96 }
97
98 void addChild(IOElement &child, const std::string &key) {
99 get()->children[key] = child.clone();
100 child.get()->parent = IOElement(*this);
101 }
102
103 void reset() {
104 _init();
105 }
106
107 bool isEmpty() { return get()->type.size() == 0; }
108
109 static std::string type(const IOElement &_e) { return const_cast<IOElement&>(_e).get()->type; };
110 static std::string value(const IOElement &_e) { return const_cast<IOElement&>(_e).get()->value; };
111 static IOElement parent(const IOElement &_e) { return const_cast<IOElement&>(_e).get()->parent; };
112 static std::unordered_map<std::string, IOElement> children(const IOElement &_e) { return const_cast<IOElement&>(_e).get()->children; };
113
114 private:
115
116 void _init() {
117 _el = std::make_shared<_IOElement>();
118 el = _el;
119 }
120
121 std::shared_ptr<_IOElement> _el;
122
123 };
124
131 struct MetaData {
132 unsigned int versionMajor = TF_VERSION_MAJOR;
133 unsigned int versionMinor = TF_VERSION_MINOR;
134 unsigned int versionPatch = TF_VERSION_PATCH;
135 };
136
146 template <typename T>
147 HRESULT toFile(const T &dataElement, const MetaData &metaData, IOElement &fileElement);
148
158 template <typename T>
159 HRESULT toFile(T *dataElement, const MetaData &metaData, IOElement &fileElement);
160
170 template <typename T>
171 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, T *dataElement);
172
173
174 // Tissue Forge types
175
176
177 // MetaData
178
179 template <>
180 HRESULT toFile(const MetaData &dataElement, const MetaData &metaData, IOElement &fileElement);
181
182 template <>
183 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, MetaData *dataElement);
184
185 // TissueForge::types::TVector2<T>
186
187 template <typename T>
188 HRESULT toFile(const TissueForge::types::TVector2<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
189
190 fileElement.get()->type = "Vector2";
191 TF_IOTOEASY(fileElement, metaData, "x", dataElement.x());
192 TF_IOTOEASY(fileElement, metaData, "y", dataElement.y());
193
194 return S_OK;
195 }
196
197 template <typename T>
198 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, TissueForge::types::TVector2<T> *dataElement) {
199
200 T de;
201
202 TF_IOFROMEASY(fileElement, metaData, "x", &de);
203 (*dataElement)[0] = de;
204
205 TF_IOFROMEASY(fileElement, metaData, "y", &de);
206 (*dataElement)[1] = de;
207
208 return S_OK;
209 }
210
211 // TissueForge::types::TVector3<T>
212
213 template <typename T>
214 HRESULT toFile(const TissueForge::types::TVector3<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
215
216 fileElement.get()->type = "Vector3";
217 TF_IOTOEASY(fileElement, metaData, "x", dataElement.x());
218 TF_IOTOEASY(fileElement, metaData, "y", dataElement.y());
219 TF_IOTOEASY(fileElement, metaData, "z", dataElement.z());
220
221 return S_OK;
222 }
223
224 template <typename T>
225 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, TissueForge::types::TVector3<T> *dataElement) {
226
227 T de;
228
229 TF_IOFROMEASY(fileElement, metaData, "x", &de);
230 (*dataElement)[0] = de;
231
232 TF_IOFROMEASY(fileElement, metaData, "y", &de);
233 (*dataElement)[1] = de;
234
235 TF_IOFROMEASY(fileElement, metaData, "z", &de);
236 (*dataElement)[2] = de;
237
238 return S_OK;
239 }
240
241 // TissueForge::types::TVector4<T>
242
243 template <typename T>
244 HRESULT toFile(const TissueForge::types::TVector4<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
245
246 fileElement.get()->type = "Vector4";
247 TF_IOTOEASY(fileElement, metaData, "x", dataElement.x());
248 TF_IOTOEASY(fileElement, metaData, "y", dataElement.y());
249 TF_IOTOEASY(fileElement, metaData, "z", dataElement.z());
250 TF_IOTOEASY(fileElement, metaData, "w", dataElement.w());
251
252 return S_OK;
253 }
254
255 template <typename T>
256 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, TissueForge::types::TVector4<T> *dataElement) {
257
258 T de;
259
260 TF_IOFROMEASY(fileElement, metaData, "x", &de);
261 (*dataElement)[0] = de;
262
263 TF_IOFROMEASY(fileElement, metaData, "y", &de);
264 (*dataElement)[1] = de;
265
266 TF_IOFROMEASY(fileElement, metaData, "z", &de);
267 (*dataElement)[2] = de;
268
269 TF_IOFROMEASY(fileElement, metaData, "w", &de);
270 (*dataElement)[3] = de;
271
272 return S_OK;
273 }
274
275 // TissueForge::types::TMatrix3<T>
276
277 template <typename T>
278 HRESULT toFile(const TissueForge::types::TMatrix3<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
279
280 fileElement.get()->type = "Matrix3";
281
282 for(unsigned int i = 0; i < 3; i++) {
283 for (unsigned int j = 0; j < 3; j++) {
284 std::string key = std::to_string(i) + std::to_string(j);
285 TF_IOTOEASY(fileElement, metaData, key, dataElement[i][j]);
286 }
287 }
288
289 return S_OK;
290 }
291
292 template <typename T>
293 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, TissueForge::types::TMatrix3<T> *dataElement) {
294
295 T de;
296
297 for(unsigned int i = 0; i < 3; i++) {
298 for(unsigned int j = 0; j < 3; j++) {
299 std::string key = std::to_string(i) + std::to_string(j);
300 TF_IOFROMEASY(fileElement, metaData, key, &de);
301 (*dataElement)[i][j] = de;
302 }
303 }
304
305 return S_OK;
306 }
307
308 // TissueForge::types::TMatrix4<T>
309
310 template <typename T>
311 HRESULT toFile(const TissueForge::types::TMatrix4<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
312
313 fileElement.get()->type = "Matrix4";
314
315 for(unsigned int i = 0; i < 4; i++) {
316 for (unsigned int j = 0; j < 4; j++) {
317 std::string key = std::to_string(i) + std::to_string(j);
318 TF_IOTOEASY(fileElement, metaData, key, dataElement[i][j]);
319 }
320 }
321
322 return S_OK;
323 }
324
325 template <typename T>
326 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, TissueForge::types::TMatrix4<T> *dataElement) {
327
328 T de;
329
330 for(unsigned int i = 0; i < 4; i++) {
331 for(unsigned int j = 0; j < 4; j++) {
332 std::string key = std::to_string(i) + std::to_string(j);
333 TF_IOFROMEASY(fileElement, metaData, key, &de);
334 (*dataElement)[i][j] = de;
335 }
336 }
337
338 return S_OK;
339 }
340
341 // TissueForge::types::TQuaternion<T>
342
343 template <typename T>
344 HRESULT toFile(const TissueForge::types::TQuaternion<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
345
346 fileElement.get()->type = "Quaternion";
347 TF_IOTOEASY(fileElement, metaData, "vector", dataElement.vector());
348 TF_IOTOEASY(fileElement, metaData, "scalar", dataElement.scalar());
349
350 return S_OK;
351 }
352
353 template <typename T>
354 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, TissueForge::types::TQuaternion<T> *dataElement) {
355
356 TF_IOFROMEASY(fileElement, metaData, "vector", &dataElement->vector());
357 TF_IOFROMEASY(fileElement, metaData, "scalar", &dataElement->scalar());
358
359 return S_OK;
360 }
361
362
363 // Built-in implementations
364
365
366 // char
367
368 template <>
369 HRESULT toFile(const char &dataElement, const MetaData &metaData, IOElement &fileElement);
370
371 template <>
372 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, char *dataElement);
373
374 // signed char
375
376 template <>
377 HRESULT toFile(const signed char &dataElement, const MetaData &metaData, IOElement &fileElement);
378
379 template <>
380 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, signed char *dataElement);
381
382 // unsigned char
383
384 template <>
385 HRESULT toFile(const unsigned char &dataElement, const MetaData &metaData, IOElement &fileElement);
386
387 template <>
388 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, unsigned char *dataElement);
389
390 // short
391
392 template <>
393 HRESULT toFile(const short &dataElement, const MetaData &metaData, IOElement &fileElement);
394
395 template <>
396 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, short *dataElement);
397
398 // unsigned short
399
400 template <>
401 HRESULT toFile(const unsigned short &dataElement, const MetaData &metaData, IOElement &fileElement);
402
403 template <>
404 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, unsigned short *dataElement);
405
406 // int
407
408 template <>
409 HRESULT toFile(const int &dataElement, const MetaData &metaData, IOElement &fileElement);
410
411 template <>
412 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, int *dataElement);
413
414 // unsigned int
415
416 template <>
417 HRESULT toFile(const unsigned int &dataElement, const MetaData &metaData, IOElement &fileElement);
418
419 template <>
420 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, unsigned int *dataElement);
421
422 // bool
423
424 template <>
425 HRESULT toFile(const bool &dataElement, const MetaData &metaData, IOElement &fileElement);
426
427 template <>
428 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, bool *dataElement);
429
430 // long
431
432 template <>
433 HRESULT toFile(const long &dataElement, const MetaData &metaData, IOElement &fileElement);
434
435 template <>
436 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, long *dataElement);
437
438 // unsigned long
439
440 template <>
441 HRESULT toFile(const unsigned long &dataElement, const MetaData &metaData, IOElement &fileElement);
442
443 template <>
444 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, unsigned long *dataElement);
445
446 // long long
447
448 template <>
449 HRESULT toFile(const long long &dataElement, const MetaData &metaData, IOElement &fileElement);
450
451 template <>
452 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, long long *dataElement);
453
454 // unsigned long long
455
456 template <>
457 HRESULT toFile(const unsigned long long &dataElement, const MetaData &metaData, IOElement &fileElement);
458
459 template <>
460 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, unsigned long long *dataElement);
461
462 // float
463
464 template <>
465 HRESULT toFile(const float &dataElement, const MetaData &metaData, IOElement &fileElement);
466
467 template <>
468 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, float *dataElement);
469
470 // double
471
472 template <>
473 HRESULT toFile(const double &dataElement, const MetaData &metaData, IOElement &fileElement);
474
475 template <>
476 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, double *dataElement);
477
478 // string
479
480 template <>
481 HRESULT toFile(const std::string &dataElement, const MetaData &metaData, IOElement &fileElement);
482
483 template <>
484 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, std::string *dataElement);
485
486 // Containers
487
488 // set
489
490 template <typename T>
491 HRESULT toFile(const std::set<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
492 fileElement.get()->type = "set";
493 fileElement.get()->children.reserve(dataElement.size());
494 unsigned int i = 0;
495 for(auto de : dataElement) {
496 TF_IOTOEASY(fileElement, metaData, std::to_string(i), de);
497 i++;
498 }
499 return S_OK;
500 }
501
502 template <typename T>
503 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, std::set<T> *dataElement) {
504 unsigned int numEls = IOElement::children(fileElement).size();
505 for(unsigned int i = 0; i < numEls; i++) {
506 T de;
507 TF_IOFROMEASY(fileElement, metaData, std::to_string(i), &de);
508 dataElement->insert(de);
509 }
510 return S_OK;
511 }
512
513 // unordered_set
514
515 template <typename T>
516 HRESULT toFile(const std::unordered_set<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
517 fileElement.get()->type = "unordered_set";
518 fileElement.get()->children.reserve(dataElement.size());
519 unsigned int i = 0;
520 for(auto de : dataElement) {
521 TF_IOTOEASY(fileElement, metaData, std::to_string(i), de);
522 i++;
523 }
524 return S_OK;
525 }
526
527 template <typename T>
528 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, std::unordered_set<T> *dataElement) {
529 unsigned int numEls = IOElement::children(fileElement).size();
530 for(unsigned int i = 0; i < numEls; i++) {
531 T de;
532 TF_IOFROMEASY(fileElement, metaData, std::to_string(i), &de);
533 dataElement->insert(de);
534 }
535 return S_OK;
536 }
537
538 // vector
539
540 template <typename T>
541 HRESULT toFile(const std::vector<T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
542 fileElement.get()->type = "vector";
543 fileElement.get()->children.reserve(dataElement.size());
544 for(unsigned int i = 0; i < dataElement.size(); i++) {
545 TF_IOTOEASY(fileElement, metaData, std::to_string(i), dataElement[i]);
546 }
547 return S_OK;
548 }
549
550 template <typename T>
551 HRESULT toFile(std::vector<T*> dataElement, const MetaData &metaData, IOElement &fileElement) {
552 fileElement.get()->type = "vector";
553 fileElement.get()->children.reserve(dataElement.size());
554 for(unsigned int i = 0; i < dataElement.size(); i++) {
555 TF_IOTOEASY(fileElement, metaData, std::to_string(i), dataElement[i]);
556 }
557 return S_OK;
558 }
559
560 template <typename T>
561 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, std::vector<T> *dataElement) {
562 unsigned int numEls = IOElement::children(fileElement).size();
563 dataElement->reserve(numEls);
564 for(unsigned int i = 0; i < numEls; i++) {
565 T de;
566 TF_IOFROMEASY(fileElement, metaData, std::to_string(i), &de);
567 dataElement->push_back(de);
568 }
569 return S_OK;
570 }
571
572 // map
573
574 template <typename S, typename T>
575 HRESULT toFile(const std::map<S, T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
576 fileElement.get()->type = "map";
577
578 std::vector<S> keysde;
579 std::vector<T> valsde;
580
581 for(typename std::map<S, T>::iterator de = dataElement.begin(); de != dataElement.end(); de++) {
582 keysde.push_back(de->first);
583 valsde.push_back(de->second);
584 }
585
586 TF_IOTOEASY(fileElement, metaData, "keys", keysde);
587 TF_IOTOEASY(fileElement, metaData, "vals", valsde);
588
589 return S_OK;
590 }
591
592 template <typename S, typename T>
593 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, std::map<S, T> *dataElement) {
594
595 std::vector<S> keysde;
596 std::vector<T> valsde;
597
598 TF_IOFROMEASY(fileElement, metaData, "keys", &keysde);
599 TF_IOFROMEASY(fileElement, metaData, "vals", &valsde);
600
601 for(unsigned int i = 0; i < keysde.size(); i++) {
602 (*dataElement)[keysde[i]] = valsde[i];
603 }
604
605 return S_OK;
606 }
607
608 // unordered_map
609
610 template <typename S, typename T>
611 HRESULT toFile(const std::unordered_map<S, T> &dataElement, const MetaData &metaData, IOElement &fileElement) {
612 fileElement.get()->type = "unordered_map";
613
614 std::vector<S> keysde;
615 std::vector<T> valsde;
616
617 for(auto de = dataElement.begin(); de != dataElement.end(); de++) {
618 keysde.push_back(de->first);
619 valsde.push_back(de->second);
620 }
621
622 TF_IOTOEASY(fileElement, metaData, "keys", keysde);
623 TF_IOTOEASY(fileElement, metaData, "vals", valsde);
624
625 return S_OK;
626 }
627
628 template <typename S, typename T>
629 HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, std::unordered_map<S, T> *dataElement) {
630
631 std::vector<S> keysde;
632 std::vector<T> valsde;
633
634 TF_IOFROMEASY(fileElement, metaData, "keys", &keysde);
635 TF_IOFROMEASY(fileElement, metaData, "vals", &valsde);
636
637 for(unsigned int i = 0; i < keysde.size(); i++) {
638 (*dataElement)[keysde[i]] = valsde[i];
639 }
640
641 return S_OK;
642 }
643
644};
645
646#endif // _SOURCE_IO_TF_IO_H_
Definition tfMatrix3.h:35
Definition tfMatrix4.h:35
Definition tfQuaternion.h:35
TVector3< T > & vector()
Definition tfQuaternion.h:73
T & scalar()
Definition tfQuaternion.h:76
Definition tfVector2.h:35
T & y()
Definition tfVector2.h:61
T & x()
Definition tfVector2.h:58
Definition tfVector3.h:35
T & x()
Definition tfVector3.h:60
T & z()
Definition tfVector3.h:66
T & y()
Definition tfVector3.h:63
Definition tfVector4.h:33
T & x()
Definition tfVector4.h:68
T & w()
Definition tfVector4.h:77
T & z()
Definition tfVector4.h:74
T & y()
Definition tfVector4.h:71
Tissue Forge I/O.
Definition tfThreeDFAngleMeshGenerator.h:28
HRESULT toFile(const T &dataElement, const MetaData &metaData, IOElement &fileElement)
Convert an object to an intermediate I/O object.
HRESULT fromFile(const IOElement &fileElement, const MetaData &metaData, T *dataElement)
Instantiate an object from an intermediate I/O object.
Intermediate I/O class for reading/writing Tissue Forge objects to/from file/string.
Definition tf_io.h:58
Container for _IOElement.
Definition tf_io.h:71
Tissue Forge meta data.
Definition tf_io.h:131
int32_t HRESULT
Definition tf_port.h:255