Antkeeper  0.0.1
ant-gene-loader.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_GAME_ANT_GENE_LOADER_HPP
21 #define ANTKEEPER_GAME_ANT_GENE_LOADER_HPP
22 
27 
38 template <class T>
40 {
41  // Read file format identifier
42  std::uint32_t format_identifier{0};
43  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&format_identifier), 1);
44 
45  // Validate file format identifier (U+1F9EC = DNA double helix)
46  if (format_identifier != 0xaca79ff0)
47  {
48  throw deserialize_error("Invalid ant gene file");
49  }
50 
51  // Read file format version
52  std::uint16_t format_version{0};
53  ctx.read16<std::endian::little>(reinterpret_cast<std::byte*>(&format_version), 1);
54 
55  // Validate file format version
56  if (format_version != 1)
57  {
58  throw deserialize_error("Unsupported ant gene format");
59  }
60 
61  // Read gene type
62  ant_gene_type gene_type{0};
63  ctx.read8(reinterpret_cast<std::byte*>(&gene_type), 1);
64 
65  // Validate gene type
66  if (gene_type != gene.type())
67  {
68  throw deserialize_error("Mismatched ant gene type");
69  }
70 
71  // Read gene name
72  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&gene.name), 1);
73 
74  // Read phene count
75  std::uint8_t phene_count{0};
76  ctx.read8(reinterpret_cast<std::byte*>(&phene_count), 1);
77 
78  // Allocate phenes
79  gene.phenes.resize(phene_count);
80 
81  // Load phenes
82  for (auto& phene: gene.phenes)
83  {
84  // Read phene caste flags
85  std::uint8_t caste_flags{0};
86  ctx.read8(reinterpret_cast<std::byte*>(&caste_flags), 1);
87 
88  // Load phene
89  load_phene(phene, resource_manager, ctx);
90 
91  // Map flagged castes to phene
92  int caste_count = std::popcount(caste_flags);
93  if (caste_count == 1)
94  {
95  gene.phene_map[static_cast<ant_caste_type>(caste_flags)] = &phene;
96  }
97  else
98  {
99  for (std::uint8_t i = 0; i < 8; ++i)
100  {
101  const std::uint8_t caste_mask = 1 << i;
102  if (caste_flags & caste_mask)
103  {
104  gene.phene_map[static_cast<ant_caste_type>(caste_mask)] = &phene;
105  if (--caste_count; !caste_count)
106  {
107  break;
108  }
109  }
110  }
111  }
112  }
113 }
114 
115 #endif // ANTKEEPER_GAME_ANT_GENE_LOADER_HPP
ant_caste_type
Ant caste types.
void load_ant_gene(ant_gene< T > &gene, resource_manager &resource_manager, deserialize_context &ctx, void(*load_phene)(T &, ::resource_manager &, deserialize_context &))
Loads an ant gene.
ant_gene_type
Ant gene types.
An exception of this type is thrown when an error occurs during deserialization.
Manages the loading, caching, and saving of resources.
hash::fnv1a32_t name
32-bit FNV-1a hash of gene name.
Definition: ant-gene.hpp:38
Ant gene with caste-specific phenes.
Definition: ant-gene.hpp:50
std::vector< T > phenes
Phene definitions.
Definition: ant-gene.hpp:54
constexpr ant_gene_type type() const noexcept override
Returns the ant gene type.
std::unordered_map< ant_caste_type, T * > phene_map
Map of ant caste types to phenes.
Definition: ant-gene.hpp:57
Provides access to a deserialization state.
std::size_t read16(std::byte *data, std::size_t count) noexcept(false)
Reads 16-bit (word) data.
std::size_t read32(std::byte *data, std::size_t count) noexcept(false)
Reads 32-bit (double word) data.
virtual std::size_t read8(std::byte *data, std::size_t count) noexcept(false)=0
Reads 8-bit (byte) data.