11package no.njoh.pulseengine.core.asset
22
3+ import kotlinx.coroutines.Dispatchers
34import kotlinx.coroutines.launch
45import kotlinx.coroutines.runBlocking
56import no.njoh.pulseengine.core.asset.types.*
67import no.njoh.pulseengine.core.shared.utils.Logger
78import no.njoh.pulseengine.core.shared.utils.Extensions.forEachFast
8- import no.njoh.pulseengine.core.shared.utils.Extensions.forEachFiltered
99import no.njoh.pulseengine.core.shared.utils.Extensions.loadFileNames
10+ import no.njoh.pulseengine.core.shared.utils.Extensions.toNowFormatted
1011import kotlin.reflect.KClass
12+ import kotlin.reflect.safeCast
1113
1214open class AssetManagerImpl : AssetManagerInternal ()
1315{
@@ -17,15 +19,11 @@ open class AssetManagerImpl : AssetManagerInternal()
1719 private var onAssetRemovedCallbacks = mutableListOf< (Asset ) -> Unit > ()
1820
1921 @Suppress(" UNCHECKED_CAST" )
20- override fun <T : Asset > get (assetName : String ): T =
21- assets[assetName]?.let { it as T } ? : throw IllegalArgumentException ( " No asset loaded with name: $assetName " )
22+ override fun <T : Asset > getOrNull (assetName : String , type : KClass < T > ): T ? =
23+ assets[assetName]?.let { type.safeCast(it) }
2224
23- @Suppress(" UNCHECKED_CAST" )
24- override fun <T : Asset > getSafe (assetName : String , type : KClass <T >): T ? =
25- assets[assetName]?.takeIf { it::class == type }?.let { it as T }
26-
27- override fun <T : Asset > getAll (type : Class <T >): List <T > =
28- assets.values.filterIsInstance(type)
25+ override fun <T : Asset > getAllOfType (type : KClass <T >): List <T > =
26+ assets.values.filterIsInstance(type.java)
2927
3028 override fun loadTexture (fileName : String , assetName : String ): Texture =
3129 Texture (fileName, assetName).also { add(it) }
@@ -51,16 +49,18 @@ open class AssetManagerImpl : AssetManagerInternal()
5149 override fun loadAllTextures (directory : String ) =
5250 directory
5351 .loadFileNames()
54- .forEachFiltered(
55- { fileName -> Texture .SUPPORTED_FORMATS .any { fileName.endsWith(it) } },
56- { fileName -> loadTexture(fileName, fileName.substringAfterLast(" /" ).substringBeforeLast(" ." )) }
57- )
52+ .filter { fileName -> Texture .SUPPORTED_FORMATS .any { fileName.endsWith(it) } }
53+ .forEachFast { fileName ->
54+ val assetName = fileName.substringAfterLast(" /" ).substringBeforeLast(" ." )
55+ if (assets.none { it.value.name == assetName })
56+ loadTexture(fileName, assetName)
57+ }
5858
5959 override fun loadInitialAssets ()
6060 {
6161 val startTime = System .nanoTime()
6262 add(Font .DEFAULT )
63- runBlocking()
63+ runBlocking(Dispatchers . IO )
6464 {
6565 assets.values.forEach()
6666 {
@@ -69,23 +69,33 @@ open class AssetManagerImpl : AssetManagerInternal()
6969 }
7070 assets.values.forEach { asset -> onAssetLoadedCallbacks.forEachFast { it.invoke(asset) } }
7171 initialAssetsLoaded = true
72- Logger .debug(" Loaded ${assets.size} assets in ${( System .nanoTime() - startTime) / 1_000_000 } ms . [${assets.values.joinToString { it.name }} ]" )
72+ Logger .debug(" Loaded ${assets.size} assets in ${startTime.toNowFormatted()} . [${assets.values.joinToString { it.name }} ]" )
7373 }
7474
7575 override fun <T : Asset > add (asset : T ): T
7676 {
77- if (assets.containsKey(asset.name))
78- Logger .warn(" Asset with name: ${asset.name} already exists and will be overridden" )
77+ val existingAsset = assets[asset.name]
78+ if (existingAsset != null )
79+ {
80+ Logger .warn(" Asset with name: ${existingAsset.name} already exists and will be deleted and overridden" )
81+ existingAsset.delete()
82+ }
7983
80- assets[asset.name] = asset
8184 if (initialAssetsLoaded)
8285 {
8386 asset.load()
8487 onAssetLoadedCallbacks.forEachFast { it.invoke(asset) }
8588 }
89+
90+ assets[asset.name] = asset
8691 return asset
8792 }
8893
94+ override fun delete (assetName : String )
95+ {
96+ assets.remove(assetName)?.delete()
97+ }
98+
8999 override fun setOnAssetLoaded (callback : (Asset ) -> Unit )
90100 {
91101 onAssetLoadedCallbacks.add(callback)
0 commit comments