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>
36 #include <object/handle-wrapper.h>
37 #include <object/property-value-wrapper.h>
38 #include <actors/actor-wrapper.h>
39 #include <image/image-wrapper.h>
40 #include <animation/animation-wrapper.h>
41 #include <stage/stage-wrapper.h>
42 #include <events/pan-gesture-detector-wrapper.h>
43 #include <toolkit/focus-manager/keyboard-focus-manager-wrapper.h>
44 #include <signals/dali-any-javascript-converter.h>
54 namespace // un-named namespace
56 const char* const SIGNAL_TOUCHED = "touched";
57 const char* const SIGNAL_HOVERED = "hovered";
58 const char* const SIGNAL_WHEEL_EVENT = "wheel-event";
59 const char* const SIGNAL_ON_STAGE = "on-stage";
60 const char* const SIGNAL_OFF_STAGE = "off-stage";
61 const char* const ANIMATION_SIGNAL_FINISHED = "finished";
62 const char* const SIGNAL_PAN_DETECTED = "pan-detected";
64 const char* const STAGE_SIGNAL_KEY_EVENT = "key-event";
65 const char* const STAGE_SIGNAL_EVENT_PROCESSING_FINISHED = "event-processing-finished";
66 const char* const STAGE_SIGNAL_TOUCHED = "touched";
67 const char* const SIGNAL_IMAGE_LOADING_FINISHED = "image-loading-finished";
68 const char* const SIGNAL_IMAGE_UPLOADED = "uploaded";
70 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_PRE_FOCUS_CHANGE = "keyboard-pre-focus-change";
71 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_CHANGED = "keyboard-focus-changed";
72 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_GROUP_CHANGED = "keyboard-focus-group-changed";
73 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUSED_ACTOR_ACTIVATED = "keyboard-focused-actor-activated";
74 const unsigned int MAX_SIGNAL_NAME_LENGTH = 64;
76 } // un-named name space
78 class BaseJavaScriptCallback
82 BaseJavaScriptCallback( v8::Isolate* isolate, const v8::Local<v8::Function>& callback )
83 :mIsolate( isolate ),mEmitInterface( NULL )
85 mCallback.Reset( isolate, callback);
87 ~BaseJavaScriptCallback()
92 bool IsFunction( const v8::Local<v8::Function>& function)
94 v8::HandleScope handleScope( mIsolate );
95 v8::Local<v8::Function> localCallback = v8::Local<v8::Function>::New( mIsolate, mCallback );
96 return ( localCallback == function );
99 void Call( Dali::Any& returnValue, std::vector< Dali::Any >& data )
101 mEmitInterface->CallbackEnter();
103 v8::HandleScope handleScope( mIsolate );
104 v8::TryCatch tryCatch;
106 // create a vector of JavaScript arguments to pass to the JavaScript function
107 std::vector< v8::Local<v8::Value> > arguments;
109 for( unsigned int i = 0; i < data.size(); ++i )
111 // convert each Dali::Any object into a JavaScript object based on it's type
112 arguments.push_back( DaliAnyConverter::ConvertToJavaScriptObject( mIsolate, data[i]));
115 // call the javascript function
116 v8::Local<v8::Function> localCallback = v8::Local<v8::Function>::New( mIsolate, mCallback );
117 v8::Local<v8::Value> javaScriptReturnVal = v8::Local<v8::Value>::Cast( localCallback->Call( localCallback, arguments.size(), &arguments[0] ));
119 // Print errors that happened during execution.
120 if( tryCatch.HasCaught() )
122 V8Utils::ReportException( mIsolate, &tryCatch);
123 DALI_ASSERT_ALWAYS( 0 && "Script error \n");
126 // convert will log an error, if the return type we want isn't found
127 returnValue = DaliAnyConverter::ConvertToDaliAny( mIsolate, javaScriptReturnVal, returnValue );
129 mEmitInterface->CallbackExit();
133 void SetEmitInterface( EmitNotificationInterface* interface)
135 mEmitInterface = interface;
138 v8::Isolate* mIsolate;
139 v8::Persistent<v8::Function> mCallback;
140 EmitNotificationInterface* mEmitInterface;
144 * base class for callback
146 class BaseCallBack : public ConnectionTracker
149 BaseCallBack( v8::Isolate* isolate, const v8::Local<v8::Function>& callback, const std::string& signalName )
150 :mSignalName( signalName ),
151 mJavaFunctor( isolate, callback)
155 void CallJavaScript( Dali::Any& returnValue, std::vector< Dali::Any >& data )
157 mJavaFunctor.Call( returnValue, data);
160 bool IsFunction( const v8::Local<v8::Function>& function)
162 return mJavaFunctor.IsFunction(function);
165 void SetEmitInterface( EmitNotificationInterface* interface)
167 mJavaFunctor.SetEmitInterface( interface );
169 virtual ~BaseCallBack() {}
171 std::string mSignalName;
172 BaseJavaScriptCallback mJavaFunctor;
178 class ActorCallback : public BaseCallBack
182 ActorCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
183 : BaseCallBack( isolate, callback, signalName )
186 bool OnTouch( Actor actor, const TouchEvent& event)
188 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
189 Dali::Any returnValue(false);
190 arguments.push_back( actor );
191 arguments.push_back( event );
192 CallJavaScript( returnValue, arguments );
194 returnValue.Get(ret);
197 bool OnHover( Actor actor, const HoverEvent& event)
199 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
200 Dali::Any returnValue(false);
201 arguments.push_back( actor );
202 arguments.push_back( event );
203 CallJavaScript( returnValue, arguments );
205 returnValue.Get(ret);
208 bool OnWheel( Actor actor, const WheelEvent& event)
210 std::vector< Dali::Any > arguments;
211 Dali::Any returnValue(false);
212 arguments.push_back( actor );
213 arguments.push_back( event );
214 CallJavaScript( returnValue, arguments );
216 returnValue.Get(ret);
219 void OnStage( Actor actor)
221 std::vector< Dali::Any > arguments;
222 Dali::Any returnValue; //no return
223 arguments.push_back( actor );
224 CallJavaScript( returnValue, arguments );
226 void OffStage( Actor actor)
228 std::vector< Dali::Any > arguments;
229 Dali::Any returnValue; //no return
230 arguments.push_back( actor );
231 CallJavaScript( returnValue, arguments );
239 class AnimationCallback : public BaseCallBack
243 AnimationCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
244 : BaseCallBack( isolate, callback, signalName )
247 void Finished( Animation& animation)
249 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
250 Dali::Any returnValue; //no return
251 arguments.push_back( animation );
252 CallJavaScript( returnValue, arguments );
257 class ImageCallback : public BaseCallBack
261 ImageCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
262 : BaseCallBack( isolate, callback, signalName )
265 void LoadingFinished( ResourceImage image)
267 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
268 Dali::Any returnValue; //no return
269 arguments.push_back( image );
270 CallJavaScript( returnValue, arguments );
273 class StageCallback : public BaseCallBack
277 StageCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
278 : BaseCallBack( isolate, callback, signalName )
282 void KeyEventSignal( const KeyEvent& keyEvent )
284 std::vector< Dali::Any > arguments;
285 Dali::Any returnValue; //no return
286 arguments.push_back( keyEvent );
287 CallJavaScript( returnValue, arguments );
289 void EventProcessingFinishedSignal()
291 std::vector< Dali::Any > arguments;
292 Dali::Any returnValue; //no return
293 CallJavaScript( returnValue, arguments );
295 void TouchedSignal( const TouchEvent& touchEvent)
297 std::vector< Dali::Any > arguments;
298 Dali::Any returnValue; //no return
299 arguments.push_back( touchEvent );
300 CallJavaScript( returnValue, arguments );
304 class KeyboardFocusCallback : public BaseCallBack
308 KeyboardFocusCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
309 : BaseCallBack( isolate, callback, signalName )
313 Actor PreFocusChangeSignal(Actor currentFocusedActor,
314 Actor proposedActorToFocus,
315 Toolkit::Control::KeyboardFocus::Direction direction )
317 std::vector< Dali::Any > arguments;
318 Dali::Any returnValue = Actor(); // we want an actor as a return value
320 arguments.push_back( currentFocusedActor );
321 arguments.push_back( proposedActorToFocus );
323 std::string name = KeyboardFocusManagerWrapper::GetDirectionName( direction );
324 arguments.push_back( name );
326 CallJavaScript( returnValue, arguments );
329 returnValue.Get(ret);
332 void FocusChangedSignal(Actor originalFocusedActor, Actor currentFocusedActor)
334 std::vector< Dali::Any > arguments;
335 Dali::Any returnValue; //no return
336 arguments.push_back( originalFocusedActor );
337 arguments.push_back( currentFocusedActor );
338 CallJavaScript( returnValue, arguments );
340 void FocusGroupSignal( Actor currentFocusedActor, bool forward )
342 std::vector< Dali::Any > arguments;
343 Dali::Any returnValue; //no return
344 arguments.push_back( currentFocusedActor );
345 arguments.push_back( forward );
346 CallJavaScript( returnValue, arguments );
348 void FocusedActorSignal( Actor activatedActor )
350 std::vector< Dali::Any > arguments;
351 Dali::Any returnValue; //no return
352 arguments.push_back( activatedActor );
353 CallJavaScript( returnValue, arguments );
357 class PanGestureDetectorCallback : public BaseCallBack
361 PanGestureDetectorCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
362 : BaseCallBack( isolate, callback, signalName )
365 void OnPan( Actor actor, const PanGesture& panGesture)
367 std::vector< Dali::Any > arguments;
368 Dali::Any returnValue; //no return
369 arguments.push_back( actor );
370 arguments.push_back( panGesture );
371 CallJavaScript( returnValue, arguments );
375 void ActorConnection( v8::Isolate* isolate,
376 v8::Local<v8::Function> javaScriptCallback,
377 ActorWrapper* actorWrapper,
378 const std::string& signalName,
381 bool connected(true);
383 ActorCallback* callback =new ActorCallback( isolate, javaScriptCallback, signalName );
385 if( strcmp( signalName.c_str(), SIGNAL_TOUCHED ) == 0 )
387 actor.TouchedSignal().Connect( callback, &ActorCallback::OnTouch );
389 else if( strcmp( signalName.c_str(), SIGNAL_HOVERED ) == 0 )
391 actor.HoveredSignal().Connect( callback, &ActorCallback::OnHover );
393 else if ( strcmp( signalName.c_str(), SIGNAL_WHEEL_EVENT ) == 0 )
395 actor.WheelEventSignal().Connect( callback, &ActorCallback::OnWheel );
397 else if ( strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) == 0 )
399 actor.OnStageSignal().Connect( callback, &ActorCallback::OnStage);
401 else if ( strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) == 0 )
403 actor.OffStageSignal().Connect( callback, &ActorCallback::OffStage);
412 actorWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
420 void AnimationConnection( v8::Isolate* isolate,
421 v8::Local<v8::Function> javaScriptCallback,
422 AnimationWrapper* animWrapper,
423 const std::string& signalName,
426 if( signalName == ANIMATION_SIGNAL_FINISHED)
428 AnimationCallback* callback =new AnimationCallback( isolate, javaScriptCallback, signalName );
429 anim.FinishedSignal().Connect( callback, &AnimationCallback::Finished );
430 animWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
434 void ImageConnection( v8::Isolate* isolate,
435 v8::Local<v8::Function> javaScriptCallback,
436 ImageWrapper* imageWrapper,
437 const std::string& signalName,
440 // Nine patch will downcast to ResourceImage
441 ResourceImage resourceImage( ResourceImage::DownCast( image ) );
444 DALI_SCRIPT_EXCEPTION( isolate, "can only connect to Resource / NinePatch Images");
448 if( strcmp( signalName.c_str(), SIGNAL_IMAGE_LOADING_FINISHED ) == 0 )
450 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
452 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
453 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
455 else if ( strcmp( signalName.c_str() , SIGNAL_IMAGE_UPLOADED ) == 0 )
457 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
458 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
459 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
463 void StageConnection( v8::Isolate* isolate,
464 v8::Local<v8::Function> javaScriptCallback,
465 StageWrapper* stageWrapper,
466 const std::string& signalName,
469 bool connected( true );
470 StageCallback* callback =new StageCallback( isolate, javaScriptCallback, signalName );
472 if( strcmp( signalName.c_str() ,STAGE_SIGNAL_KEY_EVENT) == 0 )
474 stage.KeyEventSignal().Connect( callback, &StageCallback::KeyEventSignal );
476 else if ( strcmp( signalName.c_str(), STAGE_SIGNAL_EVENT_PROCESSING_FINISHED ) == 0)
478 stage.EventProcessingFinishedSignal().Connect( callback, &StageCallback::EventProcessingFinishedSignal );
480 else if (strcmp( signalName.c_str(), STAGE_SIGNAL_TOUCHED ) == 0 )
482 stage.TouchedSignal().Connect( callback, &StageCallback::TouchedSignal );
491 stageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
499 void KeyboardFocusManagerConnection( v8::Isolate* isolate,
500 v8::Local<v8::Function> javaScriptCallback,
501 KeyboardFocusManagerWrapper* keyboardFocusWrapper,
502 const std::string& signalName,
503 Toolkit::KeyboardFocusManager keyboardFocusManager)
505 bool connected( true );
506 KeyboardFocusCallback* callback =new KeyboardFocusCallback( isolate, javaScriptCallback, signalName );
508 if( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_PRE_FOCUS_CHANGE ) == 0 )
510 keyboardFocusManager.PreFocusChangeSignal().Connect( callback, &KeyboardFocusCallback::PreFocusChangeSignal );
512 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_CHANGED ) == 0 )
514 keyboardFocusManager.FocusChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusChangedSignal );
516 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_GROUP_CHANGED ) == 0 )
518 keyboardFocusManager.FocusGroupChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusGroupSignal );
520 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUSED_ACTOR_ACTIVATED ) == 0 )
522 keyboardFocusManager.FocusedActorActivatedSignal().Connect( callback, &KeyboardFocusCallback::FocusedActorSignal );
531 keyboardFocusWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
539 void PanGestureDetectorConnection( v8::Isolate* isolate,
540 v8::Local<v8::Function> javaScriptCallback,
541 PanGestureDetectorWrapper* panGestureDetectorWrapper,
542 const std::string& signalName,
543 PanGestureDetector panGestureDetector )
545 if( strcmp( signalName.c_str() , SIGNAL_PAN_DETECTED ) == 0 )
547 PanGestureDetectorCallback* callback =new PanGestureDetectorCallback( isolate, javaScriptCallback, signalName );
548 panGestureDetector.DetectedSignal().Connect( callback, &PanGestureDetectorCallback::OnPan );
549 panGestureDetectorWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
553 } // un-named namespace
556 SignalManager::SignalManager()
557 :mInsideCallback(false)
561 SignalManager::~SignalManager()
563 // the object owning the signal manager ( e.g. an actor wrapper ) has been deleted
564 // delete the callbacks objects
565 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
567 BaseCallBack* callback = (*iter);
570 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
572 BaseCallBack* callback = (*iter);
578 void SignalManager::SignalConnect( const v8::FunctionCallbackInfo< v8::Value >& args)
581 // first paramter = signal to connect to
582 // Second parameter = function ( to run )
583 // args.This() = myActor
584 // e.g. myActor.Connect("touched", myJavaScriptActorTouched );
586 // Inside Callback on myJavaScriptActorTouched
587 // myActor.Disconnect("touched", myJavaScriptActorTouched );
589 v8::Isolate* isolate = args.GetIsolate();
590 v8::HandleScope handleScope( isolate );
592 if( !args[1]->IsFunction() )
594 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
599 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
601 // get the handle wrapper
602 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
604 // First paramter = signal name as a string
606 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
609 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
613 if( signal.empty() || ( signal.length() > MAX_SIGNAL_NAME_LENGTH ) )
615 DALI_SCRIPT_EXCEPTION(isolate, "signal name length out of range");
618 // We need to determine what type of function needs to be hooked
619 // see if we're connecting to an Actor
620 switch( baseObject->GetType() )
622 case BaseWrappedObject::ACTOR:
624 ActorWrapper* actorWrapper = static_cast< ActorWrapper*>( baseObject );
625 ActorConnection( isolate, func, actorWrapper, signal, actorWrapper->GetActor() );
628 case BaseWrappedObject::ANIMATION:
630 AnimationWrapper* animWrapper = static_cast< AnimationWrapper*>( baseObject );
631 AnimationConnection( isolate, func, animWrapper, signal, animWrapper->GetAnimation() );
634 case BaseWrappedObject::IMAGE:
636 ImageWrapper* imageWrapper = static_cast< ImageWrapper*>( baseObject );
637 ImageConnection( isolate, func, imageWrapper, signal, imageWrapper->GetImage() );
640 case BaseWrappedObject::STAGE:
642 StageWrapper* stageWrapper = static_cast< StageWrapper*>( baseObject );
643 StageConnection( isolate, func, stageWrapper, signal, stageWrapper->GetStage() );
646 case BaseWrappedObject::KEYBOARD_FOCUS_MANAGER:
648 KeyboardFocusManagerWrapper* keyboardFocusWrapper = static_cast< KeyboardFocusManagerWrapper*>( baseObject );
649 KeyboardFocusManagerConnection( isolate, func, keyboardFocusWrapper, signal, keyboardFocusWrapper->GetKeyboardFocusManager() );
652 case BaseWrappedObject::PAN_GESTURE_DETECTOR:
654 PanGestureDetectorWrapper* panGestureDetectorWrapper = static_cast< PanGestureDetectorWrapper*>( baseObject );
655 PanGestureDetectorConnection( isolate, func, panGestureDetectorWrapper, signal, panGestureDetectorWrapper->GetPanGestureDetector() );
660 DALI_SCRIPT_EXCEPTION( isolate, "object does not support connections");
667 void SignalManager::SignalDisconnect( const v8::FunctionCallbackInfo< v8::Value >& args)
669 // we can get the function name.... use that to disconnect from the object
670 v8::Isolate* isolate = args.GetIsolate();
671 v8::HandleScope handleScope( isolate );
673 if( !args[1]->IsFunction() )
675 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
680 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
682 // get the handle wrapper
683 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
685 // First parameter = signal name as a string
687 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
690 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
694 SignalManager* signalManager = baseObject->GetSignalManager();
697 signalManager->RemoveCallback( isolate, signal, func);
702 void SignalManager::AddCallback( BaseCallBack* callback )
704 // used by the callback to inform signal manager when it is being triggered.
705 callback->SetEmitInterface( this );
707 mCallbacks.PushBack( callback );
709 void SignalManager::RemoveCallback( v8::Isolate* isolate, const std::string& signalName, const v8::Local<v8::Function>& function )
712 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
714 BaseCallBack* callback = (*iter);
715 if( ( callback->mSignalName == signalName ) &&
716 ( callback->IsFunction( function ) ) )
718 mCallbacks.Erase( iter );
720 // if we're inside a callback::Call function, then deleting it will cause a seg fault
721 if( mInsideCallback )
723 callback->DisconnectAll();
724 mDisconnectedCallbacks.PushBack( callback );
735 void SignalManager::CallbackEnter()
737 mInsideCallback = true;
740 void SignalManager::CallbackExit()
742 // this gets called when we've finished calling into JavaScript, e.g. as a result of animation finishing
743 // which is being listened to by a javascript function.
745 // it possible that inside the JavaScript call, it tries to disconnect.
746 // If this happens the callback is added to the mDisconnectedCallbacks list.
747 // We then delay deleting of the callback object until the JavaScript call has finished in this function.
749 mInsideCallback = false;
751 // lets delete any call backs that were disconnect during the JavaScript call
752 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
754 BaseCallBack* callback = (*iter);
757 mDisconnectedCallbacks.Clear();
761 } // namespace V8Plugin