Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Error #3694 is thrown if a Texture is created when context is lost #627

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

stepan-beresnev
Copy link

Texture.empty and Texture.fromAtfData methods threw "Error #3694: The object was disposed by an earlier call of dispose() on it" if context was lost.

@PrimaryFeather
Copy link
Contributor

Thanks a lot for the pull request!

May I ask in which way you could make this error happen? Because my solution to this problem was actually that I'm checking for a context loss each time before user code is executed. So e.g. the "ENTER_FRAME" event is not dispatched while the context is lost, neither are touch events, and the "render" methods are not called, either. That way, user code (game code) should not be executed at all while there is no valid context.

The advantage: I don't have to check for the context / provide a workaround for a lost context each time I access it. Because that happens not only with texture creation, but at several other places.

The downside: if you execute code via "setTimeout", "setInterval", a Flash "Timer", or any other way that circumvents the Starling render loop, it won't help.

Was this something you did, too, to run into this problem?

[BTW, sorry for the late reply!]

@stepan-beresnev
Copy link
Author

Yes, it can happen in "setTimeout", "setInterval" and in different complete handlers for "Timer", loaders, sockets, javascript callbacks, which trigger some new UI creation.
And it's quite difficult to reproduce it as context should be lost at the moment of some special event. I personally wasn't able to see it in some real app, though we have constant error rate from our users.
And yes, there are some other places, like RenderTexture, just wanted to do separate pull requests.

@PrimaryFeather
Copy link
Contributor

Since there are so many places where we'd need to add workarounds — and I don't even know if a workaround is feasible for all those places — I'd actually prefer a different approach, that would solve all of those issues at once.

Whenever you're working with a context from within a non-secure callback (i.e. one of the callbacks you describe in your last posts), you could wrap it in a method like this:

Starling.current.executeWhenContextIsValid(function():void
{
    var texture:Texture = Texture.fromXYZ(...);
});

This method would be executed right away if there's a valid context; if there isn't, it would wait for the context to be restored and execute it then (analog to the method SystemUtil.executeWhenApplicationIsActive()).

What do you think of that?

@stepan-beresnev
Copy link
Author

Unfortunately it’s really difficult for us to use this method, I’d even say not possible. Let me describe why. We are doing slot machine games for Facebook (web and mobile, but let’s consider web). Usually we receive these games from different providers and do lobby, Facebook integration, bonuses, different social stuff. Lobby is done using Starling, but provided games are usually done inside of native layer (conventional display list), and we can’t change it as we are not creating these games. It means that these games receive user input not through Starling (usual mouse or keyboard events). Usually there are tens of communication points for each provider and hundreds for all of them. Also lobby is communicating with Facebook javascript to show different FB popups and handle “ok” or “cancel” callbacks, it also communicates with some other javascript callbacks in our page (I think, there are about hundred places for javascript too). Lobby also communicates with our server through web sockets (Faye) to receive pushes from server for different jackpots winnings, promotions, bonuses, etc. (hundreds of places again). We are also using different third party SDKs, like Teak for Open Graph Facebook posts, they are using loaders and provide different events based on load results. For assets loading we are not using Starling’s assets manager now as it’s not supporting parallel loading in 1.5. Also some third party ads providers. Actually I’m not even aware of all possible cases. And each of them can trigger some new animation, popup, change lobby state, etc.
So I think, we can’t really use this method. There are too many places, which require it to be used, it's much easier to have several changes inside of Starling. Though, I think, it’s good for some rare low level stage 3d operations. But frequent tasks like textures creation should be handled by framework itself imho. Actually we are getting such errors for Textures and RenderTextures mostly.
And what is even worse having this method only without workarounds means, that Starling users have to have deeper understanding of the framework internals, not just set handleLostContext property, but also understand/know, that some parts of the framework don’t handle it.
So at the bottom line, I think, that method is useful, but not for textures creation.

@stepan-beresnev
Copy link
Author

I just thought, that it would be good to mention somewhere in AS docs or Starling wiki a list of classes and methods, which should be considered as “low level” and shouldn’t be used outside of this method, overridden “render” method or Starling’s event handlers. Like all native context 3D related classes, RenderSupport, Texture’s base property, something else. But don’t think, that Texture.fromXYZ or RenderTexture’s draw methods should be included into such list, they are used too often and at the same time they can’t be executed too often, so additional checks won’t damage performance in any way, like they probably could in some RenderSupport’s methods. This way you won’t need to add workarounds everywhere, but will support most frequent cases and add ability to support rare cases manually.

@PrimaryFeather
Copy link
Contributor

Thanks a lot for the detailed description about your use-case! Okay, I totally understand what you mean. If you've got such a huge number of entry points, my proposed solution is indeed not feasible.

I'll look into it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants