Skip to content

Commit

Permalink
Change System.init to return a promise in order to work with platform…
Browse files Browse the repository at this point in the history
… initialization that may be asynchronous.

FlashPlatform's initialization is actually asynchronous, in that we must wait for Stage3DRenderer to acquire a Context3D before we're ready to roll. Since the Flash platform requires a Context3D before textures can be loaded, quickly loading textures after calling System.init was causing undesirable behavior, due a Context3D not yet being available. With this change, we can wait for a platform to become ready before continuing with other work.
  • Loading branch information
purplepwny committed Jun 24, 2014
1 parent 21d6ae3 commit d29c102
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 5 deletions.
8 changes: 7 additions & 1 deletion src/flambe/System.hx
Expand Up @@ -121,15 +121,21 @@ class System
*/
public static var volume (default, null) :AnimatedFloat = new AnimatedFloat(1);

/**
* Used to indicate whether asynchronous platform initialization has finished
*/
public static var promise (default, null) :Promise<Bool>;

/**
* Starts up Flambe, this should usually be the first thing a game does.
*/
public static function init ()
{
if (!_calledInit) {
_platform.init();
promise = _platform.init();
_calledInit = true;
}
return promise;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/flambe/platform/Platform.hx
Expand Up @@ -13,7 +13,7 @@ import flambe.util.Promise;

interface Platform
{
function init () :Void;
function init () :Promise<Bool>;

function getExternal () :ExternalSystem;
function getKeyboard () :KeyboardSystem;
Expand Down
13 changes: 11 additions & 2 deletions src/flambe/platform/flash/FlashPlatform.hx
Expand Up @@ -37,6 +37,10 @@ class FlashPlatform
public function init ()
{
var stage = Lib.current.stage;
var promise = new Promise<Bool>();
promise.success.connect(function (result) {
Log.info("Initialized Flash platform", ["renderer", _renderer.type]);
});

_stage = new FlashStage(stage);
_pointer = new BasicPointer();
Expand All @@ -47,7 +51,12 @@ class FlashPlatform
_touch = new DummyTouch();
#end

_renderer = new Stage3DRenderer();
var stage3DRenderer = new Stage3DRenderer();
_renderer = stage3DRenderer;
stage3DRenderer.promise.success.connect(function (result) {
// Stage3DRenderer's initialization is the only asynchronous part of FlashPlatform's init
promise.result = result;
});
mainLoop = new MainLoop();

stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
Expand Down Expand Up @@ -96,7 +105,7 @@ class FlashPlatform
new DebugLogic(this);
_catapult = FlashCatapultClient.canUse() ? new FlashCatapultClient() : null;
#end
Log.info("Initialized Flash platform", ["renderer", _renderer.type]);
return promise;
}

public function loadAssetPack (manifest :Manifest) :Promise<AssetPack>
Expand Down
13 changes: 13 additions & 0 deletions src/flambe/platform/flash/Stage3DRenderer.hx
Expand Up @@ -18,6 +18,7 @@ import flambe.display.Graphics;
import flambe.display.Texture;
import flambe.subsystem.RendererSystem;
import flambe.util.Assert;
import flambe.util.Promise;
import flambe.util.Value;

class Stage3DRenderer
Expand All @@ -31,9 +32,15 @@ class Stage3DRenderer

public var batcher (default, null) :Stage3DBatcher;

/**
* Used to indicate whether a Context3D has been created yet, as this is the only asynchronous point of Flash init
*/
public var promise : Promise<Bool>;

public function new ()
{
_hasGPU = new Value<Bool>(false);
promise = new Promise<Bool>();

// Use the first available Stage3D
var stage = Lib.current.stage;
Expand Down Expand Up @@ -144,6 +151,12 @@ class Stage3DRenderer
// Signal that the GPU context was (re)created
hasGPU._ = false;
hasGPU._ = true;

// initialization of the Renderer has completed if a Context3D has been created
if (!promise.hasResult)
{
promise.result = true;
}
}

private function onError (event :ErrorEvent)
Expand Down
7 changes: 6 additions & 1 deletion src/flambe/platform/html/HtmlPlatform.hx
Expand Up @@ -266,7 +266,12 @@ class HtmlPlatform
_catapult = HtmlCatapultClient.canUse() ? new HtmlCatapultClient() : null;
#end
#end
Log.info("Initialized HTML platform", ["renderer", _renderer.type]);
var promise = new Promise<Bool>();
promise.success.connect(function (result) {
Log.info("Initialized HTML platform", ["renderer", _renderer.type]);
});
promise.result = true;
return promise;
}

public function loadAssetPack (manifest :Manifest) :Promise<AssetPack>
Expand Down

0 comments on commit d29c102

Please sign in to comment.