2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "signal-manager.h"
22 #include <cstring> // for strcmp
23 #include <dali/public-api/images/resource-image.h>
24 #include <dali/public-api/object/any.h>
25 #include <dali/public-api/events/pan-gesture-detector.h>
26 #include <dali/public-api/object/any.h>
27 #include <dali/public-api/images/image.h>
28 #include <dali/public-api/events/touch-event.h>
29 #include <dali/public-api/events/hover-event.h>
30 #include <dali/public-api/events/wheel-event.h>
31 #include <dali/public-api/events/key-event.h>
32 #include <dali/public-api/events/pan-gesture.h>
33 #include <dali/devel-api/object/weak-handle.h>
37 #include <object/handle-wrapper.h>
38 #include <object/property-value-wrapper.h>
39 #include <actors/actor-wrapper.h>
40 #include <image/image-wrapper.h>
41 #include <animation/animation-wrapper.h>
42 #include <stage/stage-wrapper.h>
43 #include <events/pan-gesture-detector-wrapper.h>
44 #include <toolkit/focus-manager/keyboard-focus-manager-wrapper.h>
45 #include <signals/dali-any-javascript-converter.h>
55 namespace // un-named namespace
57 const char* const SIGNAL_TOUCHED = "touched";
58 const char* const SIGNAL_HOVERED = "hovered";
59 const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
60 const char* const SIGNAL_ON_STAGE = "onStage";
61 const char* const SIGNAL_OFF_STAGE = "offStage";
62 const char* const ANIMATION_SIGNAL_FINISHED = "finished";
63 const char* const SIGNAL_PAN_DETECTED = "panDetected";
65 const char* const STAGE_SIGNAL_KEY_EVENT = "keyEvent";
66 const char* const STAGE_SIGNAL_EVENT_PROCESSING_FINISHED = "eventProcessingFinished";
67 const char* const STAGE_SIGNAL_TOUCHED = "touched";
68 const char* const SIGNAL_IMAGE_LOADING_FINISHED = "imageLoadingFinished";
69 const char* const SIGNAL_IMAGE_UPLOADED = "uploaded";
71 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_PRE_FOCUS_CHANGE = "keyboardPreFocusChange";
72 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_CHANGED = "keyboardFocusChanged";
73 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_GROUP_CHANGED = "keyboardFocusGroupChanged";
74 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUSED_ACTOR_ENTER_KEY = "keyboardFocusedActorEnterKey";
75 const unsigned int MAX_SIGNAL_NAME_LENGTH = 64;
77 } // un-named name space
79 class BaseJavaScriptCallback
83 BaseJavaScriptCallback( v8::Isolate* isolate, const v8::Local<v8::Function>& callback )
84 :mIsolate( isolate ),mEmitInterface( NULL )
86 mCallback.Reset( isolate, callback);
88 ~BaseJavaScriptCallback()
93 bool IsFunction( const v8::Local<v8::Function>& function)
95 v8::HandleScope handleScope( mIsolate );
96 v8::Local<v8::Function> localCallback = v8::Local<v8::Function>::New( mIsolate, mCallback );
97 return ( localCallback == function );
100 void Call( Dali::Any& returnValue, std::vector< Dali::Any >& data )
102 mEmitInterface->CallbackEnter();
104 v8::HandleScope handleScope( mIsolate );
105 v8::TryCatch tryCatch;
107 // create a vector of JavaScript arguments to pass to the JavaScript function
108 std::vector< v8::Local<v8::Value> > arguments;
110 for( unsigned int i = 0; i < data.size(); ++i )
112 // convert each Dali::Any object into a JavaScript object based on it's type
113 arguments.push_back( DaliAnyConverter::ConvertToJavaScriptObject( mIsolate, data[i]));
116 // call the javascript function
117 v8::Local<v8::Function> localCallback = v8::Local<v8::Function>::New( mIsolate, mCallback );
118 v8::Local<v8::Value> javaScriptReturnVal = v8::Local<v8::Value>::Cast( localCallback->Call( localCallback, arguments.size(), &arguments[0] ));
120 // Print errors that happened during execution.
121 if( tryCatch.HasCaught() )
123 V8Utils::ReportException( mIsolate, &tryCatch);
124 DALI_ASSERT_ALWAYS( 0 && "Script error \n");
127 // convert will log an error, if the return type we want isn't found
128 returnValue = DaliAnyConverter::ConvertToDaliAny( mIsolate, javaScriptReturnVal, returnValue );
130 mEmitInterface->CallbackExit();
134 void SetEmitInterface( EmitNotificationInterface* interface)
136 mEmitInterface = interface;
139 v8::Isolate* mIsolate;
140 v8::Persistent<v8::Function> mCallback;
141 EmitNotificationInterface* mEmitInterface;
145 * base class for callback
147 class BaseCallBack : public ConnectionTracker
150 BaseCallBack( v8::Isolate* isolate, const v8::Local<v8::Function>& callback, const std::string& signalName )
151 :mSignalName( signalName ),
152 mJavaFunctor( isolate, callback)
156 void CallJavaScript( Dali::Any& returnValue, std::vector< Dali::Any >& data )
158 mJavaFunctor.Call( returnValue, data);
161 bool IsFunction( const v8::Local<v8::Function>& function)
163 return mJavaFunctor.IsFunction(function);
166 void SetEmitInterface( EmitNotificationInterface* interface)
168 mJavaFunctor.SetEmitInterface( interface );
170 virtual ~BaseCallBack() {}
172 std::string mSignalName;
173 BaseJavaScriptCallback mJavaFunctor;
179 class ActorCallback : public BaseCallBack
183 ActorCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName, Actor actor )
184 : BaseCallBack( isolate, callback, signalName ),
188 bool OnTouch( Actor actor, const TouchEvent& event)
190 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
191 Dali::Any returnValue(false);
192 arguments.push_back( actor );
193 arguments.push_back( event );
194 CallJavaScript( returnValue, arguments );
196 returnValue.Get(ret);
199 bool OnHover( Actor actor, const HoverEvent& event)
201 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
202 Dali::Any returnValue(false);
203 arguments.push_back( actor );
204 arguments.push_back( event );
205 CallJavaScript( returnValue, arguments );
207 returnValue.Get(ret);
210 bool OnWheel( Actor actor, const WheelEvent& event)
212 std::vector< Dali::Any > arguments;
213 Dali::Any returnValue(false);
214 arguments.push_back( actor );
215 arguments.push_back( event );
216 CallJavaScript( returnValue, arguments );
218 returnValue.Get(ret);
221 void OnStage( Actor actor)
223 std::vector< Dali::Any > arguments;
224 Dali::Any returnValue; //no return
225 arguments.push_back( actor );
226 CallJavaScript( returnValue, arguments );
228 void OffStage( Actor actor)
230 std::vector< Dali::Any > arguments;
231 Dali::Any returnValue; //no return
232 arguments.push_back( actor );
233 CallJavaScript( returnValue, arguments );
236 WeakHandle< Actor > mActor;
240 struct ActorGenericCallbackFunctor
242 ActorGenericCallbackFunctor(ActorCallback& callback) : callback(callback) { }
245 std::vector< Dali::Any > arguments;
246 Dali::Any returnValue; //no return
247 arguments.push_back(callback.mActor.GetHandle()); //pass the actor handle as the parameter
248 callback.CallJavaScript( returnValue, arguments );
251 ActorCallback& callback;
255 class AnimationCallback : public BaseCallBack
259 AnimationCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
260 : BaseCallBack( isolate, callback, signalName )
263 void Finished( Animation& animation)
265 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
266 Dali::Any returnValue; //no return
267 arguments.push_back( animation );
268 CallJavaScript( returnValue, arguments );
273 class ImageCallback : public BaseCallBack
277 ImageCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
278 : BaseCallBack( isolate, callback, signalName )
281 void LoadingFinished( ResourceImage image)
283 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
284 Dali::Any returnValue; //no return
285 arguments.push_back( image );
286 CallJavaScript( returnValue, arguments );
289 class StageCallback : public BaseCallBack
293 StageCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
294 : BaseCallBack( isolate, callback, signalName )
298 void KeyEventSignal( const KeyEvent& keyEvent )
300 std::vector< Dali::Any > arguments;
301 Dali::Any returnValue; //no return
302 arguments.push_back( keyEvent );
303 CallJavaScript( returnValue, arguments );
305 void EventProcessingFinishedSignal()
307 std::vector< Dali::Any > arguments;
308 Dali::Any returnValue; //no return
309 CallJavaScript( returnValue, arguments );
311 void TouchedSignal( const TouchEvent& touchEvent)
313 std::vector< Dali::Any > arguments;
314 Dali::Any returnValue; //no return
315 arguments.push_back( touchEvent );
316 CallJavaScript( returnValue, arguments );
320 class KeyboardFocusCallback : public BaseCallBack
324 KeyboardFocusCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
325 : BaseCallBack( isolate, callback, signalName )
329 Actor PreFocusChangeSignal(Actor currentFocusedActor,
330 Actor proposedActorToFocus,
331 Toolkit::Control::KeyboardFocus::Direction direction )
333 std::vector< Dali::Any > arguments;
334 Dali::Any returnValue = Actor(); // we want an actor as a return value
336 arguments.push_back( currentFocusedActor );
337 arguments.push_back( proposedActorToFocus );
339 std::string name = KeyboardFocusManagerWrapper::GetDirectionName( direction );
340 arguments.push_back( name );
342 CallJavaScript( returnValue, arguments );
345 returnValue.Get(ret);
348 void FocusChangedSignal(Actor originalFocusedActor, Actor currentFocusedActor)
350 std::vector< Dali::Any > arguments;
351 Dali::Any returnValue; //no return
352 arguments.push_back( originalFocusedActor );
353 arguments.push_back( currentFocusedActor );
354 CallJavaScript( returnValue, arguments );
356 void FocusGroupSignal( Actor currentFocusedActor, bool forward )
358 std::vector< Dali::Any > arguments;
359 Dali::Any returnValue; //no return
360 arguments.push_back( currentFocusedActor );
361 arguments.push_back( forward );
362 CallJavaScript( returnValue, arguments );
364 void EnterKeyPressedActorSignal( Actor enterKeyPressedActor )
366 std::vector< Dali::Any > arguments;
367 Dali::Any returnValue; //no return
368 arguments.push_back( enterKeyPressedActor );
369 CallJavaScript( returnValue, arguments );
373 class PanGestureDetectorCallback : public BaseCallBack
377 PanGestureDetectorCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
378 : BaseCallBack( isolate, callback, signalName )
381 void OnPan( Actor actor, const PanGesture& panGesture)
383 std::vector< Dali::Any > arguments;
384 Dali::Any returnValue; //no return
385 arguments.push_back( actor );
386 arguments.push_back( panGesture );
387 CallJavaScript( returnValue, arguments );
391 void ActorConnection( v8::Isolate* isolate,
392 v8::Local<v8::Function> javaScriptCallback,
393 ActorWrapper* actorWrapper,
394 const std::string& signalName,
397 bool connected(true);
399 ActorCallback* callback =new ActorCallback( isolate, javaScriptCallback, signalName, actor );
401 if( strcmp( signalName.c_str(), SIGNAL_TOUCHED ) == 0 )
403 actor.TouchedSignal().Connect( callback, &ActorCallback::OnTouch );
405 else if( strcmp( signalName.c_str(), SIGNAL_HOVERED ) == 0 )
407 actor.HoveredSignal().Connect( callback, &ActorCallback::OnHover );
409 else if ( strcmp( signalName.c_str(), SIGNAL_WHEEL_EVENT ) == 0 )
411 actor.WheelEventSignal().Connect( callback, &ActorCallback::OnWheel );
413 else if ( strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) == 0 )
415 actor.OnStageSignal().Connect( callback, &ActorCallback::OnStage);
417 else if ( strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) == 0 )
419 actor.OffStageSignal().Connect( callback, &ActorCallback::OffStage);
423 connected = actor.ConnectSignal( callback, signalName, ActorGenericCallbackFunctor(*callback) );
428 actorWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
436 void AnimationConnection( v8::Isolate* isolate,
437 v8::Local<v8::Function> javaScriptCallback,
438 AnimationWrapper* animWrapper,
439 const std::string& signalName,
442 if( signalName == ANIMATION_SIGNAL_FINISHED)
444 AnimationCallback* callback =new AnimationCallback( isolate, javaScriptCallback, signalName );
445 anim.FinishedSignal().Connect( callback, &AnimationCallback::Finished );
446 animWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
450 void ImageConnection( v8::Isolate* isolate,
451 v8::Local<v8::Function> javaScriptCallback,
452 ImageWrapper* imageWrapper,
453 const std::string& signalName,
456 // Nine patch will downcast to ResourceImage
457 ResourceImage resourceImage( ResourceImage::DownCast( image ) );
460 DALI_SCRIPT_EXCEPTION( isolate, "can only connect to Resource / NinePatch Images");
464 if( strcmp( signalName.c_str(), SIGNAL_IMAGE_LOADING_FINISHED ) == 0 )
466 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
468 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
469 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
471 else if ( strcmp( signalName.c_str() , SIGNAL_IMAGE_UPLOADED ) == 0 )
473 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
474 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
475 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
479 void StageConnection( v8::Isolate* isolate,
480 v8::Local<v8::Function> javaScriptCallback,
481 StageWrapper* stageWrapper,
482 const std::string& signalName,
485 bool connected( true );
486 StageCallback* callback =new StageCallback( isolate, javaScriptCallback, signalName );
488 if( strcmp( signalName.c_str() ,STAGE_SIGNAL_KEY_EVENT) == 0 )
490 stage.KeyEventSignal().Connect( callback, &StageCallback::KeyEventSignal );
492 else if ( strcmp( signalName.c_str(), STAGE_SIGNAL_EVENT_PROCESSING_FINISHED ) == 0)
494 stage.EventProcessingFinishedSignal().Connect( callback, &StageCallback::EventProcessingFinishedSignal );
496 else if (strcmp( signalName.c_str(), STAGE_SIGNAL_TOUCHED ) == 0 )
498 stage.TouchedSignal().Connect( callback, &StageCallback::TouchedSignal );
507 stageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
515 void KeyboardFocusManagerConnection( v8::Isolate* isolate,
516 v8::Local<v8::Function> javaScriptCallback,
517 KeyboardFocusManagerWrapper* keyboardFocusWrapper,
518 const std::string& signalName,
519 Toolkit::KeyboardFocusManager keyboardFocusManager)
521 bool connected( true );
522 KeyboardFocusCallback* callback =new KeyboardFocusCallback( isolate, javaScriptCallback, signalName );
524 if( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_PRE_FOCUS_CHANGE ) == 0 )
526 keyboardFocusManager.PreFocusChangeSignal().Connect( callback, &KeyboardFocusCallback::PreFocusChangeSignal );
528 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_CHANGED ) == 0 )
530 keyboardFocusManager.FocusChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusChangedSignal );
532 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_GROUP_CHANGED ) == 0 )
534 keyboardFocusManager.FocusGroupChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusGroupSignal );
536 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUSED_ACTOR_ENTER_KEY ) == 0 )
538 keyboardFocusManager.FocusedActorEnterKeySignal().Connect( callback, &KeyboardFocusCallback::EnterKeyPressedActorSignal );
547 keyboardFocusWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
555 void PanGestureDetectorConnection( v8::Isolate* isolate,
556 v8::Local<v8::Function> javaScriptCallback,
557 PanGestureDetectorWrapper* panGestureDetectorWrapper,
558 const std::string& signalName,
559 PanGestureDetector panGestureDetector )
561 if( strcmp( signalName.c_str() , SIGNAL_PAN_DETECTED ) == 0 )
563 PanGestureDetectorCallback* callback =new PanGestureDetectorCallback( isolate, javaScriptCallback, signalName );
564 panGestureDetector.DetectedSignal().Connect( callback, &PanGestureDetectorCallback::OnPan );
565 panGestureDetectorWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
569 } // un-named namespace
572 SignalManager::SignalManager()
573 :mInsideCallback(false)
577 SignalManager::~SignalManager()
579 // the object owning the signal manager ( e.g. an actor wrapper ) has been deleted
580 // delete the callbacks objects
581 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
583 BaseCallBack* callback = (*iter);
586 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
588 BaseCallBack* callback = (*iter);
594 void SignalManager::SignalConnect( const v8::FunctionCallbackInfo< v8::Value >& args)
597 // first paramter = signal to connect to
598 // Second parameter = function ( to run )
599 // args.This() = myActor
600 // e.g. myActor.Connect("touched", myJavaScriptActorTouched );
602 // Inside Callback on myJavaScriptActorTouched
603 // myActor.Disconnect("touched", myJavaScriptActorTouched );
605 v8::Isolate* isolate = args.GetIsolate();
606 v8::HandleScope handleScope( isolate );
608 if( !args[1]->IsFunction() )
610 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
615 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
617 // get the handle wrapper
618 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
620 // First paramter = signal name as a string
622 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
625 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
629 if( signal.empty() || ( signal.length() > MAX_SIGNAL_NAME_LENGTH ) )
631 DALI_SCRIPT_EXCEPTION(isolate, "signal name length out of range");
634 // We need to determine what type of function needs to be hooked
635 // see if we're connecting to an Actor
636 switch( baseObject->GetType() )
638 case BaseWrappedObject::ACTOR:
640 ActorWrapper* actorWrapper = static_cast< ActorWrapper*>( baseObject );
641 ActorConnection( isolate, func, actorWrapper, signal, actorWrapper->GetActor() );
644 case BaseWrappedObject::ANIMATION:
646 AnimationWrapper* animWrapper = static_cast< AnimationWrapper*>( baseObject );
647 AnimationConnection( isolate, func, animWrapper, signal, animWrapper->GetAnimation() );
650 case BaseWrappedObject::IMAGE:
652 ImageWrapper* imageWrapper = static_cast< ImageWrapper*>( baseObject );
653 ImageConnection( isolate, func, imageWrapper, signal, imageWrapper->GetImage() );
656 case BaseWrappedObject::STAGE:
658 StageWrapper* stageWrapper = static_cast< StageWrapper*>( baseObject );
659 StageConnection( isolate, func, stageWrapper, signal, stageWrapper->GetStage() );
662 case BaseWrappedObject::KEYBOARD_FOCUS_MANAGER:
664 KeyboardFocusManagerWrapper* keyboardFocusWrapper = static_cast< KeyboardFocusManagerWrapper*>( baseObject );
665 KeyboardFocusManagerConnection( isolate, func, keyboardFocusWrapper, signal, keyboardFocusWrapper->GetKeyboardFocusManager() );
668 case BaseWrappedObject::PAN_GESTURE_DETECTOR:
670 PanGestureDetectorWrapper* panGestureDetectorWrapper = static_cast< PanGestureDetectorWrapper*>( baseObject );
671 PanGestureDetectorConnection( isolate, func, panGestureDetectorWrapper, signal, panGestureDetectorWrapper->GetPanGestureDetector() );
676 DALI_SCRIPT_EXCEPTION( isolate, "object does not support connections");
683 void SignalManager::SignalDisconnect( const v8::FunctionCallbackInfo< v8::Value >& args)
685 // we can get the function name.... use that to disconnect from the object
686 v8::Isolate* isolate = args.GetIsolate();
687 v8::HandleScope handleScope( isolate );
689 if( !args[1]->IsFunction() )
691 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
696 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
698 // get the handle wrapper
699 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
701 // First parameter = signal name as a string
703 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
706 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
710 SignalManager* signalManager = baseObject->GetSignalManager();
713 signalManager->RemoveCallback( isolate, signal, func);
718 void SignalManager::AddCallback( BaseCallBack* callback )
720 // used by the callback to inform signal manager when it is being triggered.
721 callback->SetEmitInterface( this );
723 mCallbacks.PushBack( callback );
725 void SignalManager::RemoveCallback( v8::Isolate* isolate, const std::string& signalName, const v8::Local<v8::Function>& function )
728 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
730 BaseCallBack* callback = (*iter);
731 if( ( callback->mSignalName == signalName ) &&
732 ( callback->IsFunction( function ) ) )
734 mCallbacks.Erase( iter );
736 // if we're inside a callback::Call function, then deleting it will cause a seg fault
737 if( mInsideCallback )
739 callback->DisconnectAll();
740 mDisconnectedCallbacks.PushBack( callback );
751 void SignalManager::CallbackEnter()
753 mInsideCallback = true;
756 void SignalManager::CallbackExit()
758 // this gets called when we've finished calling into JavaScript, e.g. as a result of animation finishing
759 // which is being listened to by a javascript function.
761 // it possible that inside the JavaScript call, it tries to disconnect.
762 // If this happens the callback is added to the mDisconnectedCallbacks list.
763 // We then delay deleting of the callback object until the JavaScript call has finished in this function.
765 mInsideCallback = false;
767 // lets delete any call backs that were disconnect during the JavaScript call
768 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
770 BaseCallBack* callback = (*iter);
773 mDisconnectedCallbacks.Clear();
777 } // namespace V8Plugin