| 1162 | } |
| 1163 | |
| 1164 | s32 flatten_unit(UnitCompiler &c, Unit *unit, u32 parent_unit_index, CompileOptions &opts) |
| 1165 | { |
| 1166 | CE_UNUSED(parent_unit_index); |
| 1167 | |
| 1168 | const u32 unit_index = unit->_index; |
| 1169 | bool unit_has_transform = false; |
| 1170 | |
| 1171 | // Compile component data for each component type found |
| 1172 | // in the tree of units. |
| 1173 | for (u32 cc = 0; cc < array::size(unit->_merged_components); ++cc) { |
| 1174 | const char *component_json = unit->_merged_components[cc]; |
| 1175 | |
| 1176 | TempAllocator512 ta; |
| 1177 | JsonObject component(ta); |
| 1178 | RETURN_IF_ERROR(sjson::parse(component, component_json)); |
| 1179 | |
| 1180 | StringId32 comp_type; |
| 1181 | if (!json_object::has(component, "_type")) { |
| 1182 | comp_type = RETURN_IF_ERROR(sjson::parse_string_id(component["type"])); |
| 1183 | logw(UNIT_COMPILER, "'type' property is deprecated: replace with equivalent '_type'"); |
| 1184 | } else { |
| 1185 | comp_type = RETURN_IF_ERROR(sjson::parse_string_id(component["_type"])); |
| 1186 | } |
| 1187 | |
| 1188 | if (comp_type == STRING_ID_32("transform", UINT32_C(0xad9b5315))) |
| 1189 | unit_has_transform = true; |
| 1190 | |
| 1191 | // Append data to the component data for the specified type. |
| 1192 | ComponentTypeData ctd_deffault(default_allocator()); |
| 1193 | ComponentTypeData &ctd = const_cast<ComponentTypeData &>(hash_map::get(c._component_data, comp_type, ctd_deffault)); |
| 1194 | RETURN_IF_FALSE(UNIT_COMPILER, &ctd != &ctd_deffault, opts, "Unknown component type"); |
| 1195 | |
| 1196 | // Compile component. |
| 1197 | Buffer comp_data(default_allocator()); |
| 1198 | c._current_unit_index = unit_index; |
| 1199 | s32 err = ctd._compiler(comp_data, c, unit->_flattened_components[cc], opts); |
| 1200 | ENSURE_OR_RETURN(UNIT_COMPILER, err == 0, opts); |
| 1201 | |
| 1202 | // One component per unit max. |
| 1203 | auto cur = array::begin(ctd._unit_index); |
| 1204 | auto end = array::end(ctd._unit_index); |
| 1205 | if (std::find(cur, end, unit_index) != end) { |
| 1206 | char buf[STRING_ID32_BUF_LEN]; |
| 1207 | RETURN_IF_FALSE(UNIT_COMPILER, false |
| 1208 | , opts |
| 1209 | , "Unit already has a component of type: %s" |
| 1210 | , comp_type.to_string(buf, sizeof(buf)) |
| 1211 | ); |
| 1212 | } |
| 1213 | |
| 1214 | array::push(ctd._data, array::begin(comp_data), array::size(comp_data)); |
| 1215 | array::push_back(ctd._unit_index, unit_index); |
| 1216 | ++ctd._num; |
| 1217 | } |
| 1218 | |
| 1219 | // Flatten children tree. |
| 1220 | auto cur = hash_map::begin(unit->_children); |
| 1221 | auto end = hash_map::end(unit->_children); |