-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean up asset downloader, preloader and some improvements
- Loading branch information
Showing
20 changed files
with
360 additions
and
350 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
173 changes: 173 additions & 0 deletions
173
backends/backend-teavm/emu/com/badlogic/gdx/assets/AssetLoadingTaskEmu.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package com.badlogic.gdx.assets; | ||
|
||
import com.badlogic.gdx.Files; | ||
import com.badlogic.gdx.Gdx; | ||
import com.badlogic.gdx.assets.loaders.AssetLoader; | ||
import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader; | ||
import com.badlogic.gdx.assets.loaders.SynchronousAssetLoader; | ||
import com.badlogic.gdx.files.FileHandle; | ||
import com.badlogic.gdx.utils.Array; | ||
import com.badlogic.gdx.utils.GdxRuntimeException; | ||
import com.badlogic.gdx.utils.Logger; | ||
import com.badlogic.gdx.utils.TimeUtils; | ||
import com.badlogic.gdx.utils.async.AsyncExecutor; | ||
import com.badlogic.gdx.utils.async.AsyncResult; | ||
import com.badlogic.gdx.utils.async.AsyncTask; | ||
import com.github.xpenatan.gdx.backends.teavm.TeaApplication; | ||
import com.github.xpenatan.gdx.backends.teavm.gen.Emulate; | ||
import com.github.xpenatan.gdx.backends.teavm.preloader.AssetType; | ||
import com.github.xpenatan.gdx.backends.teavm.preloader.Preloader; | ||
|
||
@Emulate(AssetLoadingTask.class) | ||
class AssetLoadingTaskEmu implements AsyncTask<Void> { | ||
AssetManager manager; | ||
final AssetDescriptor assetDesc; | ||
final AssetLoader loader; | ||
final AsyncExecutor executor; | ||
final long startTime; | ||
|
||
volatile boolean asyncDone; | ||
volatile boolean dependenciesLoaded; | ||
volatile Array<AssetDescriptor> dependencies; | ||
volatile AsyncResult<Void> depsFuture; | ||
volatile AsyncResult<Void> loadFuture; | ||
volatile Object asset; | ||
|
||
int ticks = 0; | ||
volatile boolean cancel; | ||
|
||
public AssetLoadingTaskEmu(AssetManager manager, AssetDescriptor assetDesc, AssetLoader loader, AsyncExecutor threadPool) { | ||
this.manager = manager; | ||
this.assetDesc = assetDesc; | ||
this.loader = loader; | ||
this.executor = threadPool; | ||
startTime = manager.log.getLevel() == Logger.DEBUG ? TimeUtils.nanoTime() : 0; | ||
} | ||
|
||
/** | ||
* Loads parts of the asset asynchronously if the loader is an {@link AsynchronousAssetLoader}. | ||
*/ | ||
@Override | ||
public Void call() throws Exception { | ||
if(cancel) return null; | ||
AsynchronousAssetLoader asyncLoader = (AsynchronousAssetLoader)loader; | ||
if(!dependenciesLoaded) { | ||
dependencies = asyncLoader.getDependencies(assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
if(dependencies != null) { | ||
removeDuplicates(dependencies); | ||
manager.injectDependencies(assetDesc.fileName, dependencies); | ||
} | ||
else { | ||
// if we have no dependencies, we load the async part of the task immediately. | ||
asyncLoader.loadAsync(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
asyncDone = true; | ||
} | ||
} | ||
else { | ||
asyncLoader.loadAsync(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
asyncDone = true; | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* Updates the loading of the asset. In case the asset is loaded with an {@link AsynchronousAssetLoader}, the loaders | ||
* {@link AsynchronousAssetLoader#loadAsync(AssetManager, String, FileHandle, AssetLoaderParameters)} method is first called on | ||
* a worker thread. Once this method returns, the rest of the asset is loaded on the rendering thread via | ||
* {@link AsynchronousAssetLoader#loadSync(AssetManager, String, FileHandle, AssetLoaderParameters)}. | ||
* | ||
* @return true in case the asset was fully loaded, false otherwise | ||
* @throws GdxRuntimeException | ||
*/ | ||
public boolean update() { | ||
ticks++; | ||
|
||
// GTW: check if we have a file that was not preloaded and is not done loading yet | ||
Preloader preloader = ((TeaApplication)Gdx.app).getPreloader(); | ||
if(!preloader.isAssetLoaded(Files.FileType.Internal, assetDesc.fileName)) { | ||
preloader.loadAsset(AssetType.Binary, Files.FileType.Internal, assetDesc.fileName); | ||
boolean assetInQueue = preloader.isAssetInQueue(assetDesc.fileName); | ||
// Loader.finishLoading breaks everything | ||
if(!assetInQueue && ticks > 100000) | ||
throw new GdxRuntimeException("File not prefetched, but finishLoading was probably called: " + assetDesc.fileName); | ||
} | ||
else { | ||
if(loader instanceof SynchronousAssetLoader) | ||
handleSyncLoader(); | ||
else | ||
handleAsyncLoader(); | ||
} | ||
return asset != null; | ||
} | ||
|
||
private void handleSyncLoader() { | ||
SynchronousAssetLoader syncLoader = (SynchronousAssetLoader)loader; | ||
if(!dependenciesLoaded) { | ||
dependenciesLoaded = true; | ||
dependencies = syncLoader.getDependencies(assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
if(dependencies == null) { | ||
asset = syncLoader.load(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
return; | ||
} | ||
removeDuplicates(dependencies); | ||
manager.injectDependencies(assetDesc.fileName, dependencies); | ||
} | ||
else | ||
asset = syncLoader.load(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
} | ||
|
||
private void handleAsyncLoader() { | ||
AsynchronousAssetLoader asyncLoader = (AsynchronousAssetLoader)loader; | ||
if(!dependenciesLoaded) { | ||
if(depsFuture == null) | ||
depsFuture = executor.submit(this); | ||
else if(depsFuture.isDone()) { | ||
try { | ||
depsFuture.get(); | ||
} catch(Exception e) { | ||
throw new GdxRuntimeException("Couldn't load dependencies of asset: " + assetDesc.fileName, e); | ||
} | ||
dependenciesLoaded = true; | ||
if(asyncDone) | ||
asset = asyncLoader.loadSync(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
} | ||
} | ||
else if(loadFuture == null && !asyncDone) | ||
loadFuture = executor.submit(this); | ||
else if(asyncDone) | ||
asset = asyncLoader.loadSync(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
else if(loadFuture.isDone()) { | ||
try { | ||
loadFuture.get(); | ||
} catch(Exception e) { | ||
throw new GdxRuntimeException("Couldn't load asset: " + assetDesc.fileName, e); | ||
} | ||
asset = asyncLoader.loadSync(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
} | ||
} | ||
|
||
/** | ||
* Called when this task is the task that is currently being processed and it is unloaded. | ||
*/ | ||
public void unload() { | ||
if(loader instanceof AsynchronousAssetLoader) | ||
((AsynchronousAssetLoader)loader).unloadAsync(manager, assetDesc.fileName, resolve(loader, assetDesc), assetDesc.params); | ||
} | ||
|
||
private FileHandle resolve(AssetLoader loader, AssetDescriptor assetDesc) { | ||
if(assetDesc.file == null) assetDesc.file = loader.resolve(assetDesc.fileName); | ||
return assetDesc.file; | ||
} | ||
|
||
private void removeDuplicates(Array<AssetDescriptor> array) { | ||
boolean ordered = array.ordered; | ||
array.ordered = true; | ||
for(int i = 0; i < array.size; ++i) { | ||
final String fn = array.get(i).fileName; | ||
final Class type = array.get(i).type; | ||
for(int j = array.size - 1; j > i; --j) | ||
if(type == array.get(j).type && fn.equals(array.get(j).fileName)) array.removeIndex(j); | ||
} | ||
array.ordered = ordered; | ||
} | ||
} |
22 changes: 0 additions & 22 deletions
22
backends/backend-teavm/emu/com/badlogic/gdx/assets/loaders/AssetLoaderEmu.java
This file was deleted.
Oops, something went wrong.
21 changes: 0 additions & 21 deletions
21
backends/backend-teavm/emu/com/badlogic/gdx/assets/loaders/AsynchronousAssetLoaderEmu.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.