1 //
2 // Saved game helper.
3 //
4
5
6 #ifndef OJK_SAVED_GAME_HELPER_INCLUDED
7 #define OJK_SAVED_GAME_HELPER_INCLUDED
8
9
10 #include <cstdint>
11 #include <type_traits>
12 #include "ojk_saved_game_helper_fwd.h"
13 #include "ojk_scope_guard.h"
14 #include "ojk_saved_game_class_archivers.h"
15
16
17 namespace ojk
18 {
19
20
21 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
22 // Class stuff
23
SavedGameHelper(ISavedGame * saved_game)24 inline SavedGameHelper::SavedGameHelper(
25 ISavedGame* saved_game) :
26 saved_game_(saved_game)
27 {
28 }
29
30 // Class stuff
31 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
32
33
34 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
35 // Public methods
36
read_chunk(const uint32_t chunk_id)37 inline void SavedGameHelper::read_chunk(
38 const uint32_t chunk_id)
39 {
40 if (!saved_game_->read_chunk(
41 chunk_id))
42 {
43 saved_game_->throw_error();
44 }
45 }
46
write_chunk(const uint32_t chunk_id)47 inline void SavedGameHelper::write_chunk(
48 const uint32_t chunk_id)
49 {
50 if (!saved_game_->write_chunk(
51 chunk_id))
52 {
53 saved_game_->throw_error();
54 }
55 }
56
skip(int count)57 inline void SavedGameHelper::skip(
58 int count)
59 {
60 if (!saved_game_->skip(
61 count))
62 {
63 saved_game_->throw_error();
64 }
65 }
66
get_buffer_data()67 inline const void* SavedGameHelper::get_buffer_data()
68 {
69 return saved_game_->get_buffer_data();
70 }
71
get_buffer_size()72 inline int SavedGameHelper::get_buffer_size() const
73 {
74 return saved_game_->get_buffer_size();
75 }
76
reset_buffer()77 inline void SavedGameHelper::reset_buffer()
78 {
79 saved_game_->reset_buffer();
80 }
81
reset_buffer_offset()82 inline void SavedGameHelper::reset_buffer_offset()
83 {
84 saved_game_->reset_buffer_offset();
85 }
86
ensure_all_data_read()87 inline void SavedGameHelper::ensure_all_data_read()
88 {
89 saved_game_->ensure_all_data_read();
90 }
91
is_failed()92 inline bool SavedGameHelper::is_failed() const
93 {
94 return saved_game_->is_failed();
95 }
96
97 // Public methods
98 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
99
100
101 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
102 // try_read_chunk
103
try_read_chunk(const uint32_t chunk_id)104 inline bool SavedGameHelper::try_read_chunk(
105 const uint32_t chunk_id)
106 {
107 return saved_game_->read_chunk(
108 chunk_id);
109 }
110
111 template<typename TSrc, typename TDst>
try_read_chunk(const uint32_t chunk_id,TDst & dst_value)112 bool SavedGameHelper::try_read_chunk(
113 const uint32_t chunk_id,
114 TDst& dst_value)
115 {
116 if (!saved_game_->read_chunk(
117 chunk_id))
118 {
119 return false;
120 }
121
122 if (!try_read<TSrc>(
123 dst_value))
124 {
125 return false;
126 }
127
128 return saved_game_->is_all_data_read();
129 }
130
131 template<typename TSrc, typename TDst>
try_read_chunk(const uint32_t chunk_id,TDst * dst_values,int dst_count)132 bool SavedGameHelper::try_read_chunk(
133 const uint32_t chunk_id,
134 TDst* dst_values,
135 int dst_count)
136 {
137 if (!saved_game_->read_chunk(
138 chunk_id))
139 {
140 return false;
141 }
142
143 if (!try_read<TSrc>(
144 dst_values,
145 dst_count))
146 {
147 return false;
148 }
149
150 return saved_game_->is_all_data_read();
151 }
152
153 // try_read_chunk
154 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
155
156
157 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
158 // read_chunk
159
160 template<typename TSrc, typename TDst>
read_chunk(const uint32_t chunk_id,TDst & dst_value)161 void SavedGameHelper::read_chunk(
162 const uint32_t chunk_id,
163 TDst& dst_value)
164 {
165 if (!try_read_chunk<TSrc>(
166 chunk_id,
167 dst_value))
168 {
169 saved_game_->throw_error();
170 }
171 }
172
173 template<typename TSrc, typename TDst>
read_chunk(const uint32_t chunk_id,TDst * dst_values,int dst_count)174 void SavedGameHelper::read_chunk(
175 const uint32_t chunk_id,
176 TDst* dst_values,
177 int dst_count)
178 {
179 if (!try_read_chunk<TSrc>(
180 chunk_id,
181 dst_values,
182 dst_count))
183 {
184 saved_game_->throw_error();
185 }
186 }
187
188 // read_chunk
189 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
190
191
192 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
193 // write_chunk
194
195 template<typename TSize>
write_chunk_and_size(const uint32_t size_chunk_id,const uint32_t data_chunk_id)196 void SavedGameHelper::write_chunk_and_size(
197 const uint32_t size_chunk_id,
198 const uint32_t data_chunk_id)
199 {
200 saved_game_->save_buffer();
201
202 const int data_size = saved_game_->get_buffer_size();
203
204 saved_game_->reset_buffer();
205
206 write_chunk<TSize>(
207 size_chunk_id,
208 data_size);
209
210 saved_game_->load_buffer();
211
212 saved_game_->write_chunk(
213 data_chunk_id);
214 }
215
216 template<typename TDst, typename TSrc>
write_chunk(const uint32_t chunk_id,const TSrc & src_value)217 void SavedGameHelper::write_chunk(
218 const uint32_t chunk_id,
219 const TSrc& src_value)
220 {
221 saved_game_->reset_buffer();
222
223 write<TDst>(
224 src_value);
225
226 saved_game_->write_chunk(
227 chunk_id);
228 }
229
230 template<typename TDst, typename TSrc>
write_chunk(const uint32_t chunk_id,const TSrc * src_values,int src_count)231 void SavedGameHelper::write_chunk(
232 const uint32_t chunk_id,
233 const TSrc* src_values,
234 int src_count)
235 {
236 saved_game_->reset_buffer();
237
238 write<TDst>(
239 src_values,
240 src_count);
241
242 saved_game_->write_chunk(
243 chunk_id);
244 }
245
246 // write_chunk
247 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
248
249
250 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
251 // try_read
252
253 template<typename TSrc, typename TDst>
try_read(TDst & dst_value)254 bool SavedGameHelper::try_read(
255 TDst& dst_value)
256 {
257 using Tag = typename std::conditional <
258 std::is_same<TDst, bool>::value,
259 BooleanTag,
260 typename std::conditional<
261 std::is_arithmetic<TDst>::value || std::is_enum<TDst>::value,
262 NumericTag,
263 typename std::conditional<
264 std::is_pointer<TDst>::value,
265 PointerTag,
266 typename std::conditional<
267 std::is_class<TDst>::value,
268 ClassTag,
269 typename std::conditional<
270 std::rank<TDst>::value == 1,
271 Array1dTag,
272 typename std::conditional<
273 std::rank<TDst>::value == 2,
274 Array2dTag,
275 void
276 >::type
277 >::type
278 >::type
279 >::type
280 >::type
281 > ::type;
282
283 static_assert(
284 !std::is_same<Tag, void>::value,
285 "Unsupported type.");
286
287 return try_read<TSrc>(
288 dst_value,
289 Tag());
290 }
291
292 // try_read
293 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
294
295
296 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
297 // read
298
299 template<typename TSrc, typename TDst>
read(TDst & dst_value)300 void SavedGameHelper::read(
301 TDst& dst_value)
302 {
303 if (!try_read<TSrc>(
304 dst_value))
305 {
306 saved_game_->throw_error();
307 }
308 }
309
310 template<typename TSrc, typename TDst>
try_read(TDst & dst_value,BooleanTag)311 bool SavedGameHelper::try_read(
312 TDst& dst_value,
313 BooleanTag)
314 {
315 TSrc src_value;
316
317 if (!saved_game_->read(
318 &src_value,
319 static_cast<int>(sizeof(TSrc))))
320 {
321 return false;
322 }
323
324 // FIXME Byte order
325 //
326
327 dst_value = (src_value != 0);
328
329 return true;
330 }
331
332 template<typename TSrc, typename TDst>
try_read(TDst & dst_value,NumericTag)333 bool SavedGameHelper::try_read(
334 TDst& dst_value,
335 NumericTag)
336 {
337 const int src_size = static_cast<int>(sizeof(TSrc));
338
339 TSrc src_value;
340
341 if (!saved_game_->read(
342 &src_value,
343 src_size))
344 {
345 return false;
346 }
347
348 // FIXME Byte order
349 //
350
351 dst_value = static_cast<TDst>(src_value);
352
353 return true;
354 }
355
356 template<typename TSrc, typename TDst>
try_read(TDst * & dst_value,PointerTag)357 bool SavedGameHelper::try_read(
358 TDst*& dst_value,
359 PointerTag)
360 {
361 static_assert(
362 std::is_arithmetic<TSrc>::value &&
363 !std::is_same<TSrc, bool>::value,
364 "Unsupported types.");
365
366 using DstNumeric = typename std::conditional<
367 std::is_signed<TSrc>::value,
368 std::intptr_t,
369 std::uintptr_t
370 >::type;
371
372 DstNumeric dst_number;
373
374 if (!try_read<TSrc>(
375 dst_number,
376 NumericTag()))
377 {
378 return false;
379 }
380
381 dst_value = reinterpret_cast<TDst*>(dst_number);
382
383 return true;
384 }
385
386 template<typename TSrc, typename TDst>
try_read(TDst & dst_value,ClassTag)387 bool SavedGameHelper::try_read(
388 TDst& dst_value,
389 ClassTag)
390 {
391 static_assert(
392 std::is_same<TSrc, void>::value,
393 "Unsupported types.");
394
395 using Tag = typename std::conditional<
396 SavedGameClassArchiver<TDst>::is_implemented,
397 ExternalTag,
398 InternalTag
399 >::type;
400
401 return try_read<TSrc>(
402 dst_value,
403 ClassTag(),
404 Tag());
405 }
406
407 template<typename TSrc, typename TDst>
try_read(TDst & dst_value,ClassTag,InternalTag)408 bool SavedGameHelper::try_read(
409 TDst& dst_value,
410 ClassTag,
411 InternalTag)
412 {
413 dst_value.sg_import(
414 *this);
415
416 return !saved_game_->is_failed();
417 }
418
419 template<typename TSrc, typename TDst>
try_read(TDst & dst_value,ClassTag,ExternalTag)420 bool SavedGameHelper::try_read(
421 TDst& dst_value,
422 ClassTag,
423 ExternalTag)
424 {
425 SavedGameClassArchiver<TDst>::sg_import(
426 *this,
427 dst_value);
428
429 return !saved_game_->is_failed();
430 }
431
432 template<typename TSrc, typename TDst, int TCount>
try_read(TDst (& dst_values)[TCount],Array1dTag)433 bool SavedGameHelper::try_read(
434 TDst(&dst_values)[TCount],
435 Array1dTag)
436 {
437 return try_read<TSrc>(
438 &dst_values[0],
439 TCount);
440 }
441
442 template<typename TSrc, typename TDst, int TCount1, int TCount2>
try_read(TDst (& dst_values)[TCount1][TCount2],Array2dTag)443 bool SavedGameHelper::try_read(
444 TDst(&dst_values)[TCount1][TCount2],
445 Array2dTag)
446 {
447 return try_read<TSrc>(
448 &dst_values[0][0],
449 TCount1 * TCount2);
450 }
451
452 // read
453 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
454
455
456 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
457 // try_read (C-array)
458
459 template<typename TSrc, typename TDst>
try_read(TDst * dst_values,int dst_count)460 bool SavedGameHelper::try_read(
461 TDst* dst_values,
462 int dst_count)
463 {
464 static_assert(
465 std::is_arithmetic<TDst>::value ||
466 std::is_enum<TDst>::value ||
467 std::is_pointer<TDst>::value ||
468 std::is_class<TDst>::value,
469 "Unsupported types.");
470
471 using Src = typename std::conditional<
472 std::is_same<TSrc, void>::value,
473 TDst,
474 TSrc
475 >::type;
476
477 const bool is_src_pure_numeric =
478 std::is_arithmetic<Src>::value &&
479 (!std::is_same<Src, bool>::value) &&
480 (!std::is_enum<Src>::value);
481
482 const bool is_dst_pure_numeric =
483 std::is_arithmetic<TDst>::value &&
484 (!std::is_same<TDst, bool>::value) &&
485 (!std::is_enum<TDst>::value);
486
487 const bool is_src_float_point =
488 std::is_floating_point<Src>::value;
489
490 const bool is_dst_float_point =
491 std::is_floating_point<TDst>::value;
492
493 const bool has_same_size =
494 (sizeof(Src) == sizeof(TDst));
495
496 const bool use_inplace =
497 is_src_pure_numeric &&
498 is_dst_pure_numeric &&
499 ((!is_src_float_point && !is_dst_float_point) ||
500 (is_src_float_point && is_dst_float_point)) &&
501 has_same_size;
502
503 using Tag = typename std::conditional<
504 use_inplace,
505 InplaceTag,
506 CastTag
507 >::type;
508
509 return try_read<TSrc>(
510 dst_values,
511 dst_count,
512 Tag());
513 }
514
515 // try_read (C-array)
516 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
517
518
519 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
520 // read (C-array)
521
522 template<typename TSrc, typename TDst>
read(TDst * dst_values,int dst_count)523 void SavedGameHelper::read(
524 TDst* dst_values,
525 int dst_count)
526 {
527 if (!try_read<TSrc>(
528 dst_values,
529 dst_count))
530 {
531 saved_game_->throw_error();
532 }
533 }
534
535 template<typename TSrc, typename TDst>
try_read(TDst * dst_values,int dst_count,InplaceTag)536 bool SavedGameHelper::try_read(
537 TDst* dst_values,
538 int dst_count,
539 InplaceTag)
540 {
541 const int dst_size = dst_count * static_cast<int>(sizeof(TDst));
542
543 if (!saved_game_->read(
544 dst_values,
545 dst_size))
546 {
547 return false;
548 }
549
550 // FIXME Byte order
551 //
552
553 return true;
554 }
555
556 template<typename TSrc, typename TDst>
try_read(TDst * dst_values,int dst_count,CastTag)557 bool SavedGameHelper::try_read(
558 TDst* dst_values,
559 int dst_count,
560 CastTag)
561 {
562 using Tag = typename std::conditional<
563 std::is_arithmetic<TDst>::value ||
564 std::is_enum<TDst>::value,
565 NumericTag,
566 typename std::conditional<
567 std::is_pointer<TDst>::value,
568 PointerTag,
569 typename std::conditional<
570 std::is_class<TDst>::value,
571 ClassTag,
572 void
573 >::type
574 >::type
575 >::type;
576
577 for (int i = 0; i < dst_count; ++i)
578 {
579 if (!try_read<TSrc>(
580 dst_values[i],
581 Tag()))
582 {
583 return false;
584 }
585 }
586
587 return true;
588 }
589
590 // read (C-array)
591 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
592
593
594 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
595 // write
596
597 template<typename TDst, typename TSrc>
write(const TSrc & src_value)598 void SavedGameHelper::write(
599 const TSrc& src_value)
600 {
601 using Tag = typename std::conditional<
602 std::is_arithmetic<TSrc>::value || std::is_enum<TSrc>::value,
603 NumericTag,
604 typename std::conditional<
605 std::is_pointer<TSrc>::value,
606 PointerTag,
607 typename std::conditional<
608 std::is_class<TSrc>::value,
609 ClassTag,
610 typename std::conditional<
611 std::rank<TSrc>::value == 1,
612 Array1dTag,
613 typename std::conditional<
614 std::rank<TSrc>::value == 2,
615 Array2dTag,
616 void
617 >::type
618 >::type
619 >::type
620 >::type
621 >::type;
622
623 static_assert(
624 !std::is_same<Tag, void>::value,
625 "Unsupported type.");
626
627 write<TDst>(
628 src_value,
629 Tag());
630 }
631
632 template<typename TDst, typename TSrc>
write(const TSrc & src_value,NumericTag)633 void SavedGameHelper::write(
634 const TSrc& src_value,
635 NumericTag)
636 {
637 const int dst_size = static_cast<int>(sizeof(TDst));
638
639 const TDst dst_value = static_cast<TDst>(src_value);
640
641 // FIXME Byte order
642 //
643
644 saved_game_->write(
645 &dst_value,
646 dst_size);
647 }
648
649 template<typename TDst, typename TSrc>
write(const TSrc * src_value,PointerTag)650 void SavedGameHelper::write(
651 const TSrc* src_value,
652 PointerTag)
653 {
654 using DstNumeric = typename std::conditional<
655 std::is_signed<TSrc>::value,
656 std::intptr_t,
657 std::uintptr_t
658 >::type;
659
660 const DstNumeric dst_number = reinterpret_cast<DstNumeric>(src_value);
661
662 write<TDst>(
663 dst_number,
664 NumericTag());
665 }
666
667 template<typename TDst, typename TSrc>
write(const TSrc & src_value,ClassTag)668 void SavedGameHelper::write(
669 const TSrc& src_value,
670 ClassTag)
671 {
672 static_assert(
673 std::is_same<TDst, void>::value,
674 "Unsupported types.");
675
676 using Tag = typename std::conditional<
677 SavedGameClassArchiver<TSrc>::is_implemented,
678 ExternalTag,
679 InternalTag
680 >::type;
681
682 write<TDst>(
683 src_value,
684 ClassTag(),
685 Tag());
686 }
687
688 template<typename TDst, typename TSrc>
write(const TSrc & src_value,ClassTag,InternalTag)689 void SavedGameHelper::write(
690 const TSrc& src_value,
691 ClassTag,
692 InternalTag)
693 {
694 src_value.sg_export(
695 *this);
696 }
697
698 template<typename TDst, typename TSrc>
write(const TSrc & src_value,ClassTag,ExternalTag)699 void SavedGameHelper::write(
700 const TSrc& src_value,
701 ClassTag,
702 ExternalTag)
703 {
704 SavedGameClassArchiver<TSrc>::sg_export(
705 *this,
706 src_value);
707 }
708
709 template<typename TDst, typename TSrc, int TCount>
write(const TSrc (& src_values)[TCount],Array1dTag)710 void SavedGameHelper::write(
711 const TSrc(&src_values)[TCount],
712 Array1dTag)
713 {
714 write<TDst>(
715 &src_values[0],
716 TCount);
717 }
718
719 template<typename TDst, typename TSrc, int TCount1, int TCount2>
write(const TSrc (& src_values)[TCount1][TCount2],Array2dTag)720 void SavedGameHelper::write(
721 const TSrc(&src_values)[TCount1][TCount2],
722 Array2dTag)
723 {
724 write<TDst>(
725 &src_values[0][0],
726 TCount1 * TCount2);
727 }
728
729 // write
730 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
731
732
733 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
734 // write (C-array)
735
736 template<typename TDst, typename TSrc>
write(const TSrc * src_values,int src_count)737 void SavedGameHelper::write(
738 const TSrc* src_values,
739 int src_count)
740 {
741 static_assert(
742 std::is_arithmetic<TSrc>::value ||
743 std::is_enum<TSrc>::value ||
744 std::is_pointer<TSrc>::value ||
745 std::is_class<TSrc>::value,
746 "Unsupported types.");
747
748 using Dst = typename std::conditional<
749 std::is_same<TDst, void>::value,
750 TSrc,
751 TDst>::type;
752
753 const bool is_src_pure_numeric =
754 std::is_arithmetic<TSrc>::value &&
755 (!std::is_same<TSrc, bool>::value) &&
756 (!std::is_enum<TSrc>::value);
757
758 const bool is_dst_pure_numeric =
759 std::is_arithmetic<Dst>::value &&
760 (!std::is_same<Dst, bool>::value) &&
761 (!std::is_enum<Dst>::value);
762
763 const bool is_src_float_point =
764 std::is_floating_point<TSrc>::value;
765
766 const bool is_dst_float_point =
767 std::is_floating_point<Dst>::value;
768
769 const bool has_same_size =
770 (sizeof(TSrc) == sizeof(Dst));
771
772 const bool use_inplace =
773 is_src_pure_numeric &&
774 is_dst_pure_numeric &&
775 ((!is_src_float_point && !is_dst_float_point) ||
776 (is_src_float_point && is_dst_float_point)) &&
777 has_same_size;
778
779 using Tag = typename std::conditional<
780 use_inplace,
781 InplaceTag,
782 CastTag
783 >::type;
784
785 write<TDst>(
786 src_values,
787 src_count,
788 Tag());
789 }
790
791 template<typename TDst, typename TSrc>
write(const TSrc * src_values,int src_count,InplaceTag)792 void SavedGameHelper::write(
793 const TSrc* src_values,
794 int src_count,
795 InplaceTag)
796 {
797 const int src_size = src_count * static_cast<int>(sizeof(TSrc));
798
799 saved_game_->write(
800 src_values,
801 src_size);
802
803 // FIXME Byte order
804 //
805 }
806
807 template<typename TDst, typename TSrc>
write(const TSrc * src_values,int src_count,CastTag)808 void SavedGameHelper::write(
809 const TSrc* src_values,
810 int src_count,
811 CastTag)
812 {
813 using Tag = typename std::conditional<
814 std::is_arithmetic<TSrc>::value ||
815 std::is_enum<TSrc>::value,
816 NumericTag,
817 typename std::conditional<
818 std::is_pointer<TSrc>::value,
819 PointerTag,
820 typename std::conditional<
821 std::is_class<TSrc>::value,
822 ClassTag,
823 void
824 >::type
825 >::type
826 >::type;
827
828 for (int i = 0; i < src_count; ++i)
829 {
830 write<TDst>(
831 src_values[i],
832 Tag());
833 }
834 }
835
836 // write (C-array)
837 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
838
839
840 } // ojk
841
842
843 #endif // OJK_SAVED_GAME_HELPER_INCLUDED
844