Switch statement works on Flash but not HTML5...?



  • I must be missing something simple, but I can't spot it. Can you help?

    trace(_ui.currMode);
    			switch (_ui.currMode) {
    				case "optional_village":
    // (snip--code in here should be irrelevant, right?)
    				case "fairy_destination":
    trace(_ui.currMode); // this is never reached on html5, but reached just fine on flash.  why/how?
    

    The first trace gives this:

    State_Play.hx:557: fairy_destination

    And the second trace never runs. On flash, it runs fine. HTML5, no.

    Seems fairly straightforward that the switch statement ought to reach the second trace, given the output..._ui.currMode (a string, no casting happening) is "fairy_destination" and that's what my case statement says...and yeah, it works in flash.

    haxe 3.2.1, haxeflixel 4.1, openfl 3.6.1 (legacy), lime 2.9.1, flixel-ui 2.1



  • This continues to baffle me.

    I can't reproduce it in isolation. Here's code that works:

    package;
    import flixel.FlxState;
    class PlayState extends FlxState
    {
    	override public function create():Void 
    	{
    		var currMode = "fairy_destination";
    		trace("starting out");
    		switch (currMode) {
    			case "optional_village":
    				if (false) {
    					trace("this never happens");
    				}
    			case "fairy_destination":
    				trace("we should get here");
    			default:	
    		}
    	}
    }
    

    I run that in html5 and get the we should get here just fine.

    And here is the literal code from my game, with absolutely nothing edited out:

    trace("starting out", _ui.currMode, _ui.currMode == "fairy_destination");
    			switch (_ui.currMode) {
    				case "optional_village":
    					if (Std.is(itemClicked, Village)) {
    						var village = cast(itemClicked, Village);
    						if (village.side == ISLANDER) {
    							villageIndex = villages.indexOf(village);
    							setMode("fairy_destination");
    						}
    					}
    				case "fairy_destination":
    trace("we should get here", _ui.currMode, _ui.currMode == "fairy_destination");
    					if (tileMap.getTile(clickedX, clickedY) != BigMap.colourMap.indexOf(FlxColor.BLUE)) {
    						destX = clickedX;
    						destY = clickedY;
    						setMode("plant_types");
    					}
    				default:	
    			}
    

    In html5 (debug or release) I can run this function all I want (it happens in response to a mouse click), and it will produce State_Play.hx:556: starting out,fairy_destination,true in the javascript console every time, but never the we should get here trace, on Firefox 48.0 and the latest Google Chrome, on win7sp1x64.



  • Another test:

    trace("starting out", _ui.currMode, _ui.currMode == "fairy_destination");
    			switch (_ui.currMode) {
    				case "optional_village":
    trace("not here");
    					if (Std.is(itemClicked, Village)) {
    						var village = cast(itemClicked, Village);
    						if (village.side == ISLANDER) {
    							villageIndex = villages.indexOf(village);
    							setMode("fairy_destination");
    						}
    					}
    				case "fairy_destination":
    trace("we should get here");
    					if (tileMap.getTile(clickedX, clickedY) != BigMap.colourMap.indexOf(FlxColor.BLUE)) {
    						destX = clickedX;
    						destY = clickedY;
    						setMode("plant_types");
    					}
    				default:
    trace("default");
    			}
    trace("done the switch statement");
    

    Yields:

    State_Play.hx:556: starting out,fairy_destination,true
    State_Play.hx:575: default
    

    ...but no "done switch statement"! What on earth is going on? The execution just stops after trace("default")...but only in my game. Again, in isolation, things work as expected:

    package;
    import flixel.FlxState;
    class PlayState extends FlxState
    {
    	override public function create():Void 
    	{
    		var currMode = "fairy_destination";
    		trace("starting out");
    		switch (currMode) {
    			case "optional_village":
    				if (false) {
    					trace("this never happens");
    				}
    			case "fairy_destination":
    				trace("we should get here");
    			default:
    				trace("default");
    		}
    		trace("donnnnnnnnnnnnnnnnnnnnnnnnnne");
    	}
    }
    

    gives:

    PlayState.hx:8: starting out
    PlayState.hx:15: we should get here
    PlayState.hx:19: donnnnnnnnnnnnnnnnnnnnnnnnnne
    


  • If I replace this with an if/else-if combination, everything works fine, even in my game.

    But why should I not be able to rely on a switch statement, exactly?



  • Don't know how this applies to HF, but console output from your program can be buffered, so when exiting some unflushed output can be lost.
    If it is the case here, you don't see traces because the text is lost on the way to the screen, and not because switch is broken.



  • @starry-abyss Thanks for your insight! You're right, I guess it's a bit off-topic here. Since I didn't know quite the nature of what's wrong and my game is HaxeFlixel-based I thought I would ask for in-context help here...

    I didn't know output could be buffered even in an html5 context. I think you're absolutely right here, because when I found a bug that would occur a bit later in the code, it was one that caused an error and therefore an exit. The part I still don't understand is how having a switch statement meant:

    a) the error it hits doesn't show
    b) some buffered trace statements are also lost
    c) the program keeps running

    Whereas with if/else, none of those were true. I get all the trace output, a proper error, and the program doesn't do anything further.



  • The plot gets weirder. After figuring out the the crashing bug and fixing it, I put the switch statement back.

    Again my game doesn't react right, but also doesn't give an error. Now, however, the "done the switch statement" is logged to the console (after starting out and default.)

    I'm really curious how switch vs if/else makes such a big difference to the functionality. That "default" should definitely not be the one being hit, if you look at the other traces--it should instead hit the line that traces "we should get here".



  • Haxeflixel's HTML5 target seems to have quite a number of odd bugs (I posted in another thread about the EZPlatformer project not initially displaying the map on load), most likely due to the libraries themselves along with Lime and OpenFL. For now all we could probably do is either report about this as an issue on Github or wait?



  • @rknonchalance That's the problem, I can't reproduce it in isolation. Without that, it's difficult for anyone to do much about it, and usually the issue just gets closed. That's why I went forums + stackoverflow first....


Log in to reply