bp74 / StageXL

A fast and universal 2D rendering engine for HTML5 and Dart.
http://www.stagexl.org
Other
880 stars 82 forks source link

Modifying Sprite click handler event type sometimes throws an error #323

Open mayorbyrne opened 5 years ago

mayorbyrne commented 5 years ago

The following code throws an error after clicking the sprite when it goes to add the second event listener.

_test = new Sprite()
  ..graphics.rect(0, 0, 400, 400)
  ..graphics.fillColor(Color.Blue)
  ..addEventListener(MouseEvent.CLICK, _handleMouse)
  ..addTo(this);

  void _handleMouse(Event event)
  {
    _test.removeEventListener(MouseEvent.CLICK, _handleMouse);
    _test.addEventListener(MouseEvent.CLICK, _handleMouse2);
  }

  void _handleMouse2(InputEvent event)
  {
    _test.removeEventListener(MouseEvent.CLICK, _handleMouse2);
  }

Uncaught Error: Type 'EventStream<Event>' should be 'EventStream<InputEvent>' to implement expected type 'EventStream<InputEvent>'.

Both click handler methods standalone seem to work fine.

In this issue, it seems like it's hanging onto the original event handler type.

If I reverse the order (handle with InputEvent first, then on second click handle with Event), it seems to work fine.

Wondering if this is a StageXL bug, or if I'm just coding improperly (entirely possible).

MegaMattMiller commented 5 years ago

void _handleMouse(Event event) should really be void _handleMouse(InputEvent event)

mayorbyrne commented 5 years ago

Yes, that is the best way to write it, but the fact it works in one direction and not the other is a bit confusing

audioMirror commented 5 years ago

This is a bug caused by Dart's strong typing. On the first addEventListener, an EventStream is created. That same object will then be used for all CLICK events. If the function is an InputEvent, then Dart throws an exception.

The lesson is -- make sure your callbacks for the same event name are all the same Event type.

We fixed this in our version of EventDispatcher at the expense of making multiple EventStream based on type.

bp74 commented 5 years ago

I will take a look at it! Thanks for reporting this issue

mayorbyrne commented 4 years ago

Found another issue that might be related.

Consider the following code:

void main()
{
  GlassPlate plate = new GlassPlate(200, 200);
    // ..addEventListener(MouseEvent.MOUSE_DOWN, _handleMouseDown);

  plate.removeEventListeners(MouseEvent.MOUSE_DOWN);
  plate.removeEventListener(MouseEvent.MOUSE_DOWN, _handleMouseDown);
}

void _handleMouseDown(InputEvent event)
{
  print('handling mouse down');
}

Running as is tosses a Error: Type 'EventStream<Event>' should be 'EventStream<InputEvent>' to implement expected type 'EventStream<InputEvent>'. Uncommenting line 4 results in no error being thrown, as does commenting the line with removeEventListeners.