Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.86k stars 822 forks source link

Consider "suspendRendering" functionality? #980

Closed tconkling closed 7 years ago

tconkling commented 7 years ago

Hi Daniel -

Here's my situation: I need to obscure screen updates for my game for several frames while some calculations are made that update gamestate, but that the player should not be able to see.

BORING BACKSTORY, FOR CONTEXT:

My original solution was to create a full-screen RenderTexture, draw the contents of the screen into it, and display that over all other content during this interval. However, occasionally this results in Error #3691: Resource limit for this resource type exceeded. errors.

In theory, unless I'm mistaken, this shouldn't be a big deal - my code was catching these errors immediately upon RenderTexture creation, and disposing the RenderTexture:

private function obscureScreen () :void {
    var screenTex :RenderTexture = null;
    var screenSprite :Sprite = new Sprite();

    try {
        screenTex = new RenderTexture(Flashbang.stageWidth, Flashbang.stageHeight, false);
        screenTex.draw(this.mode.modeSprite);
        screenSprite.addChild(new Image(screenTex));
        this.mode.modeSprite.addChild(screenSprite);

    } catch (e :Error) {
        log.error("Failed to create screen texture", e);

        screenSprite.removeFromParent(true);
        screenSprite.dispose();
        screenTex.dispose();
    }
}

But in practice, hitting this limit and immediately disposing the offending texture results in further error 3691s in the next Starling.render() pass, which then crashes my game.

THE ACTUAL REQUEST:

A much simpler solution is to simply tell Starling to stop rendering for the few frames that I need to pause screen updates: i.e., I set Starling._rendering to false and add an additional check in Starling.nextFrame() for the _rendering flag.

In its current incarnation, Starling doesn't support this - with Starling.stop(), you can stop Starling updates and continue rendering, or stop updates AND rendering, but you can't stop rendering and continue updating, which is what I need.

So: I'm curious if you'd consider adding the ability to suspend rendering only. I realize this may be too niche a use-case to justify the code change, which is totally cool; I can maintain my own Starling subclass in that case.

PrimaryFeather commented 7 years ago

Actually, that's rather simple: even while Starling is stopped, you can call advanceTime() to execute all time-based logic. So all you'd need to do is call this method from a standard ENTER_FRAME event (triggered from the Flash display list's event, of course).

Alternatively, you could subclass Starling and override just the nextFrame method. Then you copy the code from the base class over, except that you make the render call optional (via an additional property like the rendering flag you mentioned).

Would one of those approaches work for you?

tconkling commented 7 years ago

Yep, both of those work fine!

(This is what I'm currently doing:)

public class CustomStarling extends Starling {
    public var suspendRendering :Boolean;

    override public function render () :void {
        if (!this.suspendRendering) {
            super.render();
        }
    }
}
PrimaryFeather commented 7 years ago

Okay, I'm happy to hear you got it working! :smile:

Are you fine with this solution, or do you need anything else? Otherwise, I'd say we can close this issue.

tconkling commented 7 years ago

Nope, this works for me! Thanks!