LibGDX AssetManager and black textures & fonts - libgdx

I have a game which does not/cannot use a "Loading Screen". I'm having some trouble using AssetManager to load assets on the fly after an Ad shows, or an IAP process happens - essentially whenever the OpenGL context changes.
I've followed the wiki article on AssetManager, but I'm still seeing black textures whenever I try to load a "new" texture.
I have a Singleton custom GameAssetManager which has some convenience methods which delegate to LibGDX's AssetManager.
For example:
public Texture getTexture(String filename) {
if (assets.isLoaded(filename)) {
return assets.get(filename, Texture.class);
} else {
assets.load(filename, Texture.class);
assets.finishLoadingAsset(filename);
Texture texture = assets.get(filename, Texture.class);
sessionAssets.put(filename, texture);
return texture;
}
}
In my AndroidLauncher, I override the onResume method like so:
#Override
protected void onResume() {
super.onResume();
GameAssetManager.instance.resume();
}
The GameAssetManager.resume() method just does this:
public void resume() {
assets = new AssetManager();
Texture.setAssetManager(assets);
}
I have a StoreItemButton which is a Group and which changes it's layout/ui-components when the item is purchased through Google's IAB library or an Ad shows.
After the Ad shows, or the IAB process completes AndroidLauncher.onResume is called and when the button changes it's UI it or parts of it just turn black.
If I go through and pre-load all possible layouts - up to 4 per button (up to 30 buttons), and then just show/hide them based on the situation, it seems to work, but this is a lot of overhead and error prone for no good reason.
Any help here would be greatly appreciated.

The short explanation is that while your application may see texture references on the JVM heap as valid, the real texture bytes in the GPU may be invalid.
This often happens onPause, because another activity or process may take the OpenGL context to draw itself and everything that your program has put to the GPU may be discarded. When the program resumes after that (onResume), your variables holding the textures may not be destroyed and may still point to valid JVM heap objects (either because you have static refs, or because the Gargabe Collector has not claimed anything), but the textures in the GPU are gone and should be pushed/reloaded there again.
This is the article that can give you a more complete answer, directly by the libgdx "benevolent dictator" :)
http://www.badlogicgames.com/wordpress/?p=1073

Related

How to share tileSets between different tiledMaps?

If I have several .tmx files using the same tileSet, obviously I'd like to load the tileSet texture only once, but if I use the regular way to do it, the texture is loaded twice...
TmxMapLoader loader = new TmxMapLoader();
TiledMap tiledMap1 = loader.load("map-test.tmx");
TiledMap tiledMap2 = loader.load("map-test.tmx");
Texture texture1 = tiledMap1.getTileSets().getTile(1).getTextureRegion().getTexture();
Texture texture2 = tiledMap2.getTileSets().getTile(1).getTextureRegion().getTexture();
// texture1 is different than texture2
So my question is, is there any way to avoid the map loading the same assets several times?
Probably I'll end writing my own TmxLoader because I don't want it to load images from the Image layer but replace them with actual game objects... but I'd like to know the vanilla way...
Edit:
The solution provided by David Saltares was the one I needed, so I'll left here the proper code:
// supossing that both maps use the same tileset image...
TmxMapLoader loader = new TmxMapLoader();
assetManager.setLoader(TiledMap.class, loader);
assetManager.load("map-test1.tmx", TiledMap.class);
assetManager.load("map-test2.tmx", TiledMap.class);
assetManager.finishLoading();
TiledMap tiledMap1 = assetManager.get("map-test1.tmx");
TiledMap tiledMap2 = assetManager.get("map-test2.tmx");
Texture texture1 = tiledMap1.getTileSets().getTile(1).getTextureRegion().getTexture();
Texture texture2 = tiledMap2.getTileSets().getTile(1).getTextureRegion().getTexture();
// now texture1 == texture2 :)
What I'm wondering is, why this is not the default? I mean, assetManager has lots of loaders by default, but not the tmx one...
Use AssetManager, call its setLoader method passing a new instance of TmxMapLoader.
When loading a map via the asset manager, the tmx loader will try to handle it and tell the asset manager all its dependencies. One of these dependencies will be the texture for the tiles. The asset manager will satisfy the dependencies and then the map will actually get loaded.
All assets under the manager are referenced counted, so calling load() on the same handle, won't actually allocate more memory.
This means that, when the second map gets loaded and the manager tries to satisfy its dependencies, it will find the texture is already loaded. It will simply increment its reference count by one.

Libgdx Skin dispose behavior

I've a question about the libgdx Skin behavior.
the game I'm developing has a global AssetsManager (from the libgdx suite) that every class can access.
I load different TextureAtlas inside this assets manage
I know that assetManager.dispose() disposes all the resources loaded inside the assets manager.
Now, I would like also to have a Skin (for the GUI) loaded inside the assets manager.
The skin is gonna use several TextureAtlas...
Here's the question: since I'm gonna use skin.addRegion() and since the online API reference about the skin class says "The atlas will not be automatically disposed when the skin is disposed" is it a good idea to load all the TextureAtlasof the skin in the global assets manager?
I'm fearing about the dispose action. Because when I call the assetManager.dispose() both the TextureAtlas and the Skin will be called on the dispose method...but what if the TextureAtlas are disposed before the skin?
Could actually happen any problem about it?
The skin behavior is not so well-defined, I mean...what does the dispose method do?
Thank in advance,
Luca
skin.dispose() calls dispose on any specific resources that are Disposable. But the TextureAtlas itself is not one of the "resources" so it must be manually disposed of separately from the skin.
The only example of a disposable skin resource I can think of is a BitmapFont that does not use the TextureAtlas that you're using with the Skin.
Note that you should never call dispose on something that you loaded with the AssetManager. Instead, you should call manager.unload() on that resource so the AssetManager can properly manage dependencies.
The nice thing about manager.unload() is that it keeps track of how many other resources are dependent on the object and only disposes it when it's clear of dependencies. So if you also load your Skin with the AssetManager, you only ever need to worry about calling manager.unload("mySkin") and it will correctly determine whether the associated TextureAtlas should also be disposed.
But be sure to only call unload() on a resource once per time you called load() on the same resource. AssetManager's internal dependency counting does rely on all your load() and unload() calls mirroring each other one-to-one.
I didn't want to post an anwser but I wasn't able to post a comment with code -_-.
Ok, so if the situtation is this below:
`
assetManager.load("images/guiTextureAtlas", TextureAtlas.class);
assetsManager.load("skin/uiSkin.json", Skin.class)";
assetsManager.finishLoading();
Skin uiSkin = assetManager.get("skin/uiSkin.json");
uiSkin.addRegion(assetManager.get("images/guiTextureAtlas");
`
Is it all fine if I call assetManager.dispose() for disposing all the resources?

When should I load data in a Windows Phone 8 application?

I've seen a lot of questions here related to the OnNavigatedTo method, but none of them seem to answer the basic question of, "At what point should I load data?" The documentation on MSDN doesn't explicitly answer this question, as far as I can tell.
If I need to load a list of data from the local database, which method is the most appropriate to use? Should I use the OnNavigatedTo method, or the Loaded event?
What I've been using so far is this pattern, which seems to work well:
protected override void OnNavigatedTo(NavigationEventArgs e) {
base.OnNavigatedTo(e);
if (NavigationMode.New == e.NavigationMode) {
var data = LoadData();
this.DataContext = data;
}
}
What this means is that for a new instance of a page, load the data synchronously. This also means that the page will not be rendered until the data has finished loading and the profiler complains that I'm using too much UI thread time.
An alternate approach is this pattern:
protected override async void OnNavigatedTo(NavigationEventArgs e) {
base.OnNavigatedTo(e);
if (NavigationMode.New == e.NavigationMode) {
var data = await LoadData();
this.DataContext = data;
}
}
But with this pattern, it seems to me that navigation, and therefore page rendering may occur before I've loaded the data and set the DataContext, meaning unnecessary re-paints and what-not.
I usualy bind to a ViewModel directly in XAML. Then in OnNavigatedTo I trigger the view model to fetch its data async.
This allows me to show basic values from start (page title etc.). Then when I start fetching the data I can also activate a progressbar directly in the ViewModel and then remove it once the data is fetched.
I recommend you load your data asynchronously. OnNavigatedTo is one place where you can start the loading. If you're talking about a page that the user is almost certainly going to navigate to, then you may be able to start loading earlier.
I have a series of blog posts that look at how async has some friction with traditional OOP. There are a couple of posts that look at data binding in particular, e.g., asynchronous construction (the section on asynchronous initialization) and asynchronous properties (the section on data binding).
Just a few hours ago I announced the first stable release for my AsyncEx library, which includes the NotifyTaskCompletion types that you can use to kick off an asynchronous loading operation and have your view respond automatically (via data binding) when it completes.
But back to the core problem: you do have to show something while the data is loading. I recommend you do not consider this "unnecessary", but rather accept it as an opportunity to provide a better user experience. Think about what you want your app to look like on a slower phone or if there is an error loading the data. Any time there's I/O, design the "Loading..." and "Error" states as well as the "Loaded" state.

ViewModel LifeCycle, when does it get disposed?

In mvvmcross v3 ViewModel
public class TimerViewModel : MvxViewModel
{
System.Timers.Timer timer;
public TimerViewModel()
{
timer = new System.Timers.Timer(500f);
timer.Elapsed += HandleTimerElapsed;
timer.Start();
}
void HandleTimerElapsed (object sender, ElapsedEventArgs e)
{
Debug.Log( "Time Elapsed" );
}
}
As MvxViewModel doesn't implement IDisposable, where should I put the following code ?
timer.Stop();
timer.Elapsed += HandleTimerElapsed;
I find that mvvmcross code have some MvxWeakEventSubscription, is it used to solve my problem ?
There's no easy universal way to know when to dispose the ViewModel - especially once you start mixing and matching ViewModel presentation styles to include navigations, tabs, splitviews, flyouts, fragments, lists, etc. and as you include more and more platforms
As a result of this, a couple of ways I have shut things like timers down in the past are:
1. Sometimes I have used a specialised interface on the ViewModel and I ensure this is called appropriately on each client.
For example, I have done some starting/stopping of 'page' level Views using:
OnPause/OnResume in Android
OnNavigatedTo/OnNavigatingFrom in Windows
ViewDidAppear/ViewWillDisappear in iOS
I have thought about adding this as a generalised pattern to do this (it is logged in https://github.com/slodge/MvvmCross/issues/74) - but so far I've not added this to v3 as I think it would lead to too much misunderstanding among users - it's better to let them to do this in the very few situations where it's needed.
Update: I have blogged about this and published a sample - see http://slodge.blogspot.co.uk/2013/11/n42-is-my-viewmodel-visible-can-i-kill.html
2. Sometimes I've just used Event Aggregation through the MvvmCross Messenger - and I've used it's inherent WeakReference-based messaging to make sure the ViewModel can be garbage collected when the view has finished with it.
An example of this is in the InternetMinute sample - which has a single 'Tick generation service' which ViewModels can connect to via messaging for updates - see:
the service - https://github.com/slodge/MvvmCross-Tutorials/tree/master/InternetMinute/InternetMinute.Core/Services/Tick
a ViewModel that consumes the service - via https://github.com/slodge/MvvmCross-Tutorials/blob/master/InternetMinute/InternetMinute.Core/ViewModels/HomeViewModel.cs
You might consider this slightly inefficient - as the Tick messages will be generated even if the ViewModel isn't present - but it's only a small inefficiency.
3. I've considered using more final events - things like OnNavigatingFrom(BACK) and 'onDestroy' and some 'final' detection on the UINavigationController delegates ... but I've not had a reason to do this 'for real' on any project yet.

how as3 memory management

first defined a class:
class C1 extends Sprite
{
public function C1() { super(); }
}
then write the following codes in Document Class:
setInterval(function(a:Sprite):void {
a.addChild(new C1());
}, 10, this);
setInterval(function(a:Sprite):void {
a.removeChildAt(0);
}, 11, this);
then run it and check the memory ustage, it will get more and more larger...
how could released the memory when remove the child from root?
The Flash VM uses garbage collection to free up memory. GC will be executed at arbitrary times by the player, unless you explicitly call System.gc(), but this method is available in AIR and the debugger version of Flash Player only. Therefore, usage of memory might still continue to increase, even though you have freed up resources in your program, until the GC process is executed.
Also, note that addChild() and removeChild() merely add and remove items to and from the display list. To really free up a resource, you have to explicitly set all references to it retained in your program to null.