DEADSOFTWARE

73da0c2cf9ba63ef0540f5af7def55dfe5c73ba4
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / GameItemsHolder.kt
1 package ru.deadsoftware.cavedroid.game
3 import com.badlogic.gdx.Gdx
4 import kotlinx.serialization.json.Json
5 import ru.deadsoftware.cavedroid.game.model.block.Block
6 import ru.deadsoftware.cavedroid.game.model.dto.BlockDto
7 import ru.deadsoftware.cavedroid.game.model.dto.GameItemsDto
8 import ru.deadsoftware.cavedroid.game.model.dto.ItemDto
9 import ru.deadsoftware.cavedroid.game.model.item.Item
10 import ru.deadsoftware.cavedroid.game.model.mapper.BlockMapper
11 import ru.deadsoftware.cavedroid.game.model.mapper.ItemMapper
12 import ru.deadsoftware.cavedroid.misc.utils.AssetLoader
13 import javax.inject.Inject
15 @GameScope
16 class GameItemsHolder @Inject constructor(
17 private val blockMapper: BlockMapper,
18 private val itemMapper: ItemMapper,
19 ) {
21 private var _initialized: Boolean = false
23 private val blocksMap = LinkedHashMap<String, Block>()
24 private val itemsMap = LinkedHashMap<String, Item>()
26 private lateinit var fallbackBlock: Block
27 private lateinit var fallbackItem: Item
31 private fun loadBlocks(dtoMap: Map<String, BlockDto>) {
32 dtoMap.forEach { (key, dto) ->
33 blocksMap[key] = blockMapper.map(key, dto)
34 }
36 fallbackBlock = blocksMap[FALLBACK_BLOCK_KEY]
37 ?: throw IllegalArgumentException("Fallback block key '$FALLBACK_BLOCK_KEY' not found")
38 }
40 private fun loadItems(dtoMap: Map<String, ItemDto>) {
41 if (dtoMap.isNotEmpty() && blocksMap.isEmpty()) {
42 throw IllegalStateException("items should be loaded after blocks")
43 }
45 dtoMap.forEach { (key, dto) ->
46 itemsMap[key] = itemMapper.map(key, dto, blocksMap[key])
47 }
49 fallbackItem = itemsMap[FALLBACK_ITEM_KEY]
50 ?: throw IllegalArgumentException("Fallback item key '$FALLBACK_ITEM_KEY' not found")
51 }
53 fun initialize(assetLoader: AssetLoader) {
54 if (_initialized) {
55 Gdx.app.debug(TAG, "Attempted to init when already initialized")
56 return
57 }
59 val jsonString = assetLoader.getAssetHandle("json/game_items.json").readString()
60 val gameItemsDto = JsonFormat.decodeFromString(GameItemsDto.GameItemsDtoJsonSerializer, jsonString)
62 loadBlocks(gameItemsDto.blocks)
63 loadItems(gameItemsDto.items)
65 _initialized = true
66 }
68 private fun <T> Map<String, T>.getOrFallback(key: String, fallback: T, lazyErrorMessage: () -> String): T {
69 val t = this[key] ?: run {
70 Gdx.app.error(TAG, lazyErrorMessage.invoke())
71 return fallback
72 }
73 return t
74 }
76 fun getBlock(key: String): Block {
77 return blocksMap.getOrFallback(key, fallbackBlock) {
78 "No block with key '$key' found. Returning $FALLBACK_BLOCK_KEY"
79 }
80 }
82 fun getItem(key: String): Item {
83 return itemsMap.getOrFallback(key, fallbackItem) {
84 "No item with key '$key' found. Returning $FALLBACK_BLOCK_KEY"
85 }
86 }
88 companion object {
89 private const val TAG = "GameItemsHolder"
91 private val JsonFormat = Json { ignoreUnknownKeys = true }
93 const val FALLBACK_BLOCK_KEY = "none"
94 const val FALLBACK_ITEM_KEY = "none"
95 }
96 }