Why would a Mediator not receive an event from a View?
Hello, I have been working with RobotLegs for a while now, and for the first time I encounter something I cannot understand. In a view, I dispatch an event to which the Mediator listens, however that event seems to only be able to happen once. It's a show / hide menu action depending on what happens in the video player.
The VideoBoard.videoExpandCollapseEventHandler() function gets called properly, then I want to dispatch to the mediator so that the appropriate model can be updated. Every trace within that function work, but in the mediator, it can happen only once, and never after. Is there something that removes the listener from the mediator without me requesting it?
Below is an excerpt of my code. Any help is appreciated!
// VideoBoardMediator.as (the mediator)
override public function onRegister():void
{
// map events
eventMap.mapListener ( eventDispatcher,
StateModelEvent.UPDATED,
stateModelUpdatedHandler,
StateModelEvent
);
eventMap.mapListener ( view,
VideoPlayerEvent.EXPAND_TO_FULLSCREEN,
dispatchExpandVideo,
VideoPlayerEvent
);
eventMap.mapListener ( view,
VideoPlayerEvent.COLLAPSE_FROM_FULLSCREEN,
dispatchCollapseVideo,
VideoPlayerEvent
);
// init view
view.scale = configModel.scale;
view.resize(configModel.width, configModel.height);
view.init();
// add videos
var i:uint;
var numLoops:uint = videoBoardModel.numVideoVOs;
var vo:VideoVO;
for(i = 0; i < numLoops; i++)
{
vo = videoBoardModel.videoVOs[i];
view.addVideo(vo.id, vo.imageURL, vo.vimeoId, vimeoAppService.API_KEY);
}
}
private function stateModelUpdatedHandler(event:StateModelEvent):void
{
if(stateModel.currentState == State.VIDEOS)
{
view.showVideos();
}
else
{
view.hideVideos();
}
}
private function dispatchExpandVideo(event:VideoPlayerEvent):void
{
trace("\n", this, "--- dispatchExpandVideo ---");
dispatch(event);
}
private function dispatchCollapseVideo(event:VideoPlayerEvent):void
{
trace("\n", this, "--- dispatchCollapseVideo ---");
dispatch(event);
}
// VideoBoard.as (the view)
private function videoExpandCollapseEventHandler(event:VideoPlayerEvent):void
{
trace("\n", this, "--- videoExpandCollapseEventHandler ---");
var video:MultiTouchVideoPlayer = event.target as MultiTouchVideoPlayer;
var duration:Number;
var onCompleteFunction:Function;
var params:Object = {};
params.scaleX = 1;
params.scaleY = 1;
params.onCompleteParams = [video];
switch(event.type)
{
case VideoPlayerEvent.EXPAND_TO_FULLSCREEN:
_collapsedVideoX = video.x;
_collapsedVideoY = video.y;
_collapsedVideoRotation = video.rotation;
duration = 0.45;
params.x = _width * 0.5;
params.y = _height * 0.5;
params.width = _width;
params.height = _height;
params.rotation = 0;
params.onComplete = videoExpandComplete;
trace("dispatch expand");
dispatchEvent(new VideoPlayerEvent(VideoPlayerEvent.EXPAND_TO_FULLSCREEN));
break;
case VideoPlayerEvent.COLLAPSE_FROM_FULLSCREEN:
video.removeVimeoPlayer();
duration = 0.33;
params.x = _collapsedVideoX;
params.y = _collapsedVideoY;
params.rotation = _collapsedVideoRotation;
params.onComplete = videoCollapseComplete;
trace("dispatch collapse");
dispatchEvent(new VideoPlayerEvent(VideoPlayerEvent.COLLAPSE_FROM_FULLSCREEN));
break;
}
TweenMax.to(video, duration, params);
}
Comments are currently closed for this discussion. You can start a new one.
Keyboard shortcuts
Generic
? | Show this help |
---|---|
ESC | Blurs the current field |
Comment Form
r | Focus the comment reply box |
---|---|
^ + ↩ | Submit the comment |
You can use Command ⌘
instead of Control ^
on Mac
Support Staff 1 Posted by Shaun Smith on 24 Feb, 2012 06:00 PM
Have you added break points (or traces) to onRemove() to check if the mediator is being removed for some reason?
Support Staff 2 Posted by Ondina D.F. on 24 Feb, 2012 06:02 PM
Could it be that the view gets removed/added from/to stage when you switch between StageDisplayState.NORMAL and StageDisplayState.FULL_SCREEN and its mediator gets removed/added too ?
Can you add an event listener in the view for addedToStage (flash.events.Event.ADDED_TO_STAGE) and removedFromStage (flash.events.Event.REMOVED_FROM_STAGE) to see if this ist the case?
3 Posted by jansensan on 24 Feb, 2012 06:44 PM
@Shaun: I tried after you suggested, to no avail. Since I have no plan on removing the mediator, I overrode the onRemove() and put a breakpoint on super.onRemove(), didnt get anything.
@Ondina: Technically, I am no really going fullscreen, even though I use the terminology. I just expand the MultiTouchVideoPlayer to fit the screen, bring in over the other children, then hide the menu that is over all that. This part works. When I collapse, the video player goes bak to its original size, all the other children are visible and available, but since the mediator does not receive the event, I cannot tell the menu (another view with its own mediator) to go back on screen.
Conceptually, I have been wondering about what's the best way to have views talk to each other. Since no data is to be exchanged, is it ok to simply have the mediator do eventDispatcher.dispatch(SomeEvent.EVENT) and then another mediator listen to the eventDispatcher, or is it better to have a model change state, and then all mediators that need to listen to that change do so? Currently, I tried both options and now am using the latter.
4 Posted by jansensan on 24 Feb, 2012 07:21 PM
Stupid question: could TweenMax affect anything in that flow? Or could the fact that I am using FP 11.2 beta?
Support Staff 5 Posted by Ondina D.F. on 24 Feb, 2012 07:32 PM
I also thought that TweenMax could do that, so I tried it 10 minutes ago:)
It doesn’t add or remove the views.
Are you sure you don’t switch between some states somehow?
Is the view dispatching the events a subview of the mediated view?
How does your custom event class look like? Can you paste it in here?
As for FP 11.2 beta, I have no idea if it can be the cause of the issue.
Support Staff 6 Posted by Ondina D.F. on 24 Feb, 2012 07:47 PM
Try to dispatch another custom event from the view, that is not related to the VideoPlayer stuff, to see if the mediator can hear it.
7 Posted by jansensan on 24 Feb, 2012 07:59 PM
I have tried a couple of things here:
These things did not work. Below is the current event class:
As for switching states, I am trying to achieve that :) I will add more traces along the way. I tried a couple of different breakpoints, but it did not clarify anything.
At first, the mediated view was just redispatching the event a subview was sending, now I create a new one altogether. Hey, maybe I should null the event that the handler receives? I'll try that.
I am loading a Vimeo player in my project, maybe something conflicts with their classes? I'll try to add some ApplicationDomain constraints.
Thanks for your time! This is really confusing me as this is not where I thought I'd hit a wall :P
Support Staff 8 Posted by Ondina D.F. on 24 Feb, 2012 08:19 PM
The custom event looks fine, indeed :)
I don’t think that’s the issue, but just try to set bubbles=true
Can you try to dispatch that event from a really simple view, having just a button inside?
Good look! And please let us know about your findings.
Sorry for not being able to help you. I have to go now. Maybe Shaun or someone else will give you more hints.
Cheers,
Ondina
Support Staff 9 Posted by Shaun Smith on 24 Feb, 2012 09:13 PM
Just a quickie: you're specifying
VideoPlayerEvent
as the concrete event type when mapping with the EventMap, but the event code you posted was forMultiTouchVideoPlayerEvent
. When specifying a concrete event, the EventMap will ignore events that aren't that exact concrete type. Could this be the issue?10 Posted by jansensan on 24 Feb, 2012 09:19 PM
Oh, no that's not it. I posted the most recent version of that class. As I mentioned in my previous reply, I tried renaming the class or constants, in case they were conflicting with who knows what.
11 Posted by jansensan on 24 Feb, 2012 09:20 PM
Is there a way that I could send you my src directory directly? (rather than posting it publicly here?) I mean that may help, that may not either
Support Staff 12 Posted by Ondina D.F. on 24 Feb, 2012 10:13 PM
I’m going to change the discussion to private. You can attach a zip file. After that I’ll delete the attachment and change the discussion to public again. OK?
13 Posted by jansensan on 24 Feb, 2012 10:14 PM
This works with me. Thanks!
14 Posted by jansensan on 24 Feb, 2012 10:42 PM
There is the full project. It has been built with FDT.
15 Posted by jansensan on 24 Feb, 2012 10:44 PM
You may not be able to expand the videos as multitouch is necessary. I'm using TuioPad http://code.google.com/p/tuiopad/ to be able to do so.
Support Staff 16 Posted by Shaun Smith on 24 Feb, 2012 10:50 PM
Cool, could you give some quick instructions for reproducing the bug
Support Staff 17 Posted by Ondina D.F. on 24 Feb, 2012 10:58 PM
There is a library missing. I can’t make it work;)
18 Posted by jansensan on 24 Feb, 2012 11:00 PM
Yes!
If you have TuioPad installed on your phone, makes sur that in the header part, the host says "incoming connection", that's by clicking on the TCP button. Also, there is a message that says "current network adress is...", that adress should be put into deploy/flash-config.xml in the humanInterface ip attribute. You may also set the scale and fps to fit your screen.
A menu is visible on the right when you load the app. Keep your finger down (or mouse) on the video section until the timer fills up. The video thumbnails will slide in. Here you do need multitouch, for you need to reverse pinch the thumbs to expand the video. At that moment, the menu hides automatically. When you pinch once in fullscreen mode, the video reverts to small mode, this is where the collapse event should fire but does not, leaving the menu out of sight.
I hope that is helpful :)
19 Posted by jansensan on 24 Feb, 2012 11:05 PM
Can you tell me what could be missing? All is included. Attached is an image that shows all the libraries that should be there and added to class paths. The closed directories are not used yet.
You're awesome for helping me!
Support Staff 20 Posted by Ondina D.F. on 24 Feb, 2012 11:08 PM
everything under net.jansensan
21 Posted by jansensan on 24 Feb, 2012 11:10 PM
For real? It should be there in the export... odd, anywho, here is the swc that should be in the libs/as3jansensanlib directory
Support Staff 22 Posted by Ondina D.F. on 24 Feb, 2012 11:11 PM
I got it, but I won't be able to use TuioPad though.
Support Staff 23 Posted by Shaun Smith on 24 Feb, 2012 11:12 PM
Where do these things happen in the code?
I don't think I'll be able to get this up and running locally - too many pieces, and I don't have a phone to test on. Nevertheless, I'm sure we can get to the bottom of it.
24 Posted by jansensan on 24 Feb, 2012 11:17 PM
It happens in the com.f4.slideshowss12.view.videoboard package.
VideoBoardMediator is the mediator
VideoBoard is the mediated view
MultiTouchVideoPlayer is a subview of VideoBoard
VimeoPlayer is a subview of MultiTouchVideoPlayer
MultiTouchVideoPlayer.dispatchExpand and MultiTouchVideoPlayer.dispatchCollapse are the functions that initially send the event.
VideoBoard.videoExpandCollapseEventHandler() receives them and redispatches them to its mediator. The mediator dispatches the event further for commands. These are mapped in the com.f4.slideshowss12.controller.InitAppCommand class
This will function only once the video is expanded, the full process works. Then afterwards visually the video can expand, but the events dont travel
Support Staff 25 Posted by Shaun Smith on 24 Feb, 2012 11:19 PM
As a test, everywhere where you have
mediatorMap.mapView(..)
(and where it makes sense to do so), try setting autoRemove to false (the last parameter of mapView), just to be sure that mediators aren't being removed.Just got your last message, will take a look..
26 Posted by jansensan on 24 Feb, 2012 11:30 PM
So I added those parameters, it works a couple of times now, then stops again... I guess it must be something I'm doing wrong?
Support Staff 27 Posted by Shaun Smith on 24 Feb, 2012 11:37 PM
If that's the case, then it sounds like something is being GC'd. Does VideoBoard ever leave the stage?
28 Posted by jansensan on 24 Feb, 2012 11:40 PM
It should not, as I always need it there. And it contains the videos, which are always visible, I do not take it out of the stage myself. I'll try something without the Vimeo stuff at all, see if it interferes. I have put it in it's own application domain, but that may not be enough.
Support Staff 29 Posted by Shaun Smith on 24 Feb, 2012 11:41 PM
In VideoBoardMediator's onRegister(), where you map the EXPAND and COLLAPSE handlers with the EventMap, try setting useWeakReference to false (the final parameter of mapListener). If that solves the issue then you've got GC issues.
Support Staff 30 Posted by Shaun Smith on 24 Feb, 2012 11:43 PM
Also, put a trace in the overridden onRemove() just to be sure that it's not getting called at any point.