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"
23 #include <object/handle-wrapper.h>
24 #include <object/property-value-wrapper.h>
25 #include <actors/actor-wrapper.h>
26 #include <image/image-wrapper.h>
27 #include <animation/animation-wrapper.h>
28 #include <stage/stage-wrapper.h>
29 #include <events/pan-gesture-detector-wrapper.h>
30 #include <toolkit/focus-manager/keyboard-focus-manager-wrapper.h>
31 #include <signals/dali-any-javascript-converter.h>
32 #include <dali/public-api/images/resource-image.h>
33 #include <dali/public-api/object/any.h>
34 #include <dali/public-api/events/pan-gesture-detector.h>
35 #include <dali/public-api/object/any.h>
36 #include <dali/public-api/images/image.h>
37 #include <dali/public-api/events/touch-event.h>
38 #include <dali/public-api/events/hover-event.h>
39 #include <dali/public-api/events/mouse-wheel-event.h>
40 #include <dali/public-api/events/key-event.h>
41 #include <dali/public-api/events/pan-gesture.h>
51 namespace // un-named namespace
53 const char* const SIGNAL_TOUCHED = "touched";
54 const char* const SIGNAL_HOVERED = "hovered";
55 const char* const SIGNAL_MOUSE_WHEEL_EVENT = "mouse-wheel-event";
56 const char* const SIGNAL_ON_STAGE = "on-stage";
57 const char* const SIGNAL_OFF_STAGE = "off-stage";
58 const char* const ANIMATION_SIGNAL_FINISHED = "finished";
59 const char* const SIGNAL_PAN_DETECTED = "pan-detected";
61 const char* const STAGE_SIGNAL_KEY_EVENT = "key-event";
62 const char* const STAGE_SIGNAL_EVENT_PROCESSING_FINISHED = "event-processing-finished";
63 const char* const STAGE_SIGNAL_TOUCHED = "touched";
64 const char* const SIGNAL_IMAGE_LOADING_FINISHED = "image-loading-finished";
65 const char* const SIGNAL_IMAGE_UPLOADED = "uploaded";
67 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_PRE_FOCUS_CHANGE = "keyboard-pre-focus-change";
68 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_CHANGED = "keyboard-focus-changed";
69 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_GROUP_CHANGED = "keyboard-focus-group-changed";
70 const char* const KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUSED_ACTOR_ACTIVATED = "keyboard-focused-actor-activated";
71 const unsigned int MAX_SIGNAL_NAME_LENGTH = 64;
73 } // un-named name space
75 class BaseJavaScriptCallback
79 BaseJavaScriptCallback( v8::Isolate* isolate, const v8::Local<v8::Function>& callback )
80 :mIsolate( isolate ),mEmitInterface( NULL )
82 mCallback.Reset( isolate, callback);
84 ~BaseJavaScriptCallback()
89 bool IsFunction( const v8::Local<v8::Function>& function)
91 v8::HandleScope handleScope( mIsolate );
92 v8::Local<v8::Function> localCallback = v8::Local<v8::Function>::New( mIsolate, mCallback );
93 return ( localCallback == function );
96 void Call( Dali::Any& returnValue, std::vector< Dali::Any >& data )
98 mEmitInterface->CallbackEnter();
100 v8::HandleScope handleScope( mIsolate );
101 v8::TryCatch tryCatch;
103 // create a vector of JavaScript arguments to pass to the JavaScript function
104 std::vector< v8::Local<v8::Value> > arguments;
106 for( unsigned int i = 0; i < data.size(); ++i )
108 // convert each Dali::Any object into a JavaScript object based on it's type
109 arguments.push_back( DaliAnyConverter::ConvertToJavaScriptObject( mIsolate, data[i]));
112 // call the javascript function
113 v8::Local<v8::Function> localCallback = v8::Local<v8::Function>::New( mIsolate, mCallback );
114 v8::Local<v8::Value> javaScriptReturnVal = v8::Local<v8::Value>::Cast( localCallback->Call( localCallback, arguments.size(), &arguments[0] ));
116 // Print errors that happened during execution.
117 if( tryCatch.HasCaught() )
119 V8Utils::ReportException( mIsolate, &tryCatch);
120 DALI_ASSERT_ALWAYS( 0 && "Script error \n");
123 // convert will log an error, if the return type we want isn't found
124 returnValue = DaliAnyConverter::ConvertToDaliAny( mIsolate, javaScriptReturnVal, returnValue );
126 mEmitInterface->CallbackExit();
130 void SetEmitInterface( EmitNotificationInterface* interface)
132 mEmitInterface = interface;
135 v8::Isolate* mIsolate;
136 v8::Persistent<v8::Function> mCallback;
137 EmitNotificationInterface* mEmitInterface;
141 * base class for callback
143 class BaseCallBack : public ConnectionTracker
146 BaseCallBack( v8::Isolate* isolate, const v8::Local<v8::Function>& callback, const std::string& signalName )
147 :mSignalName( signalName ),
148 mJavaFunctor( isolate, callback)
152 void CallJavaScript( Dali::Any& returnValue, std::vector< Dali::Any >& data )
154 mJavaFunctor.Call( returnValue, data);
157 bool IsFunction( const v8::Local<v8::Function>& function)
159 return mJavaFunctor.IsFunction(function);
162 void SetEmitInterface( EmitNotificationInterface* interface)
164 mJavaFunctor.SetEmitInterface( interface );
166 virtual ~BaseCallBack() {}
168 std::string mSignalName;
169 BaseJavaScriptCallback mJavaFunctor;
175 class ActorCallback : public BaseCallBack
179 ActorCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
180 : BaseCallBack( isolate, callback, signalName )
183 bool OnTouch( Actor actor, const TouchEvent& event)
185 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
186 Dali::Any returnValue(false);
187 arguments.push_back( actor );
188 arguments.push_back( event );
189 CallJavaScript( returnValue, arguments );
191 returnValue.Get(ret);
194 bool OnHover( Actor actor, const HoverEvent& event)
196 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
197 Dali::Any returnValue(false);
198 arguments.push_back( actor );
199 arguments.push_back( event );
200 CallJavaScript( returnValue, arguments );
202 returnValue.Get(ret);
205 bool OnMouseWheel( Actor actor, const MouseWheelEvent& event)
207 std::vector< Dali::Any > arguments;
208 Dali::Any returnValue(false);
209 arguments.push_back( actor );
210 arguments.push_back( event );
211 CallJavaScript( returnValue, arguments );
213 returnValue.Get(ret);
216 void OnStage( Actor actor)
218 std::vector< Dali::Any > arguments;
219 Dali::Any returnValue; //no return
220 arguments.push_back( actor );
221 CallJavaScript( returnValue, arguments );
223 void OffStage( Actor actor)
225 std::vector< Dali::Any > arguments;
226 Dali::Any returnValue; //no return
227 arguments.push_back( actor );
228 CallJavaScript( returnValue, arguments );
236 class AnimationCallback : public BaseCallBack
240 AnimationCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
241 : BaseCallBack( isolate, callback, signalName )
244 void Finished( Animation& animation)
246 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
247 Dali::Any returnValue; //no return
248 arguments.push_back( animation );
249 CallJavaScript( returnValue, arguments );
254 class ImageCallback : public BaseCallBack
258 ImageCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
259 : BaseCallBack( isolate, callback, signalName )
262 void LoadingFinished( ResourceImage image)
264 std::vector< Dali::Any > arguments; // Dali::Vector considers Dali::Any to be a non trivial type so won't compile
265 Dali::Any returnValue; //no return
266 arguments.push_back( image );
267 CallJavaScript( returnValue, arguments );
270 class StageCallback : public BaseCallBack
274 StageCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
275 : BaseCallBack( isolate, callback, signalName )
279 void KeyEventSignal( const KeyEvent& keyEvent )
281 std::vector< Dali::Any > arguments;
282 Dali::Any returnValue; //no return
283 arguments.push_back( keyEvent );
284 CallJavaScript( returnValue, arguments );
286 void EventProcessingFinishedSignal()
288 std::vector< Dali::Any > arguments;
289 Dali::Any returnValue; //no return
290 CallJavaScript( returnValue, arguments );
292 void TouchedSignal( const TouchEvent& touchEvent)
294 std::vector< Dali::Any > arguments;
295 Dali::Any returnValue; //no return
296 arguments.push_back( touchEvent );
297 CallJavaScript( returnValue, arguments );
301 class KeyboardFocusCallback : public BaseCallBack
305 KeyboardFocusCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
306 : BaseCallBack( isolate, callback, signalName )
310 Actor PreFocusChangeSignal(Actor currentFocusedActor,
311 Actor proposedActorToFocus,
312 Toolkit::Control::KeyboardFocusNavigationDirection direction )
314 std::vector< Dali::Any > arguments;
315 Dali::Any returnValue = Actor(); // we want an actor as a return value
317 arguments.push_back( currentFocusedActor );
318 arguments.push_back( proposedActorToFocus );
320 std::string name = KeyboardFocusManagerWrapper::GetDirectionName( direction );
321 arguments.push_back( name );
323 CallJavaScript( returnValue, arguments );
326 returnValue.Get(ret);
329 void FocusChangedSignal(Actor originalFocusedActor, Actor currentFocusedActor)
331 std::vector< Dali::Any > arguments;
332 Dali::Any returnValue; //no return
333 arguments.push_back( originalFocusedActor );
334 arguments.push_back( currentFocusedActor );
335 CallJavaScript( returnValue, arguments );
337 void FocusGroupSignal( Actor currentFocusedActor, bool forward )
339 std::vector< Dali::Any > arguments;
340 Dali::Any returnValue; //no return
341 arguments.push_back( currentFocusedActor );
342 arguments.push_back( forward );
343 CallJavaScript( returnValue, arguments );
345 void FocusedActorSignal( Actor activatedActor )
347 std::vector< Dali::Any > arguments;
348 Dali::Any returnValue; //no return
349 arguments.push_back( activatedActor );
350 CallJavaScript( returnValue, arguments );
354 class PanGestureDetectorCallback : public BaseCallBack
358 PanGestureDetectorCallback(v8::Isolate* isolate, const v8::Local<v8::Function>& callback ,const std::string& signalName )
359 : BaseCallBack( isolate, callback, signalName )
362 void OnPan( Actor actor, const PanGesture& panGesture)
364 std::vector< Dali::Any > arguments;
365 Dali::Any returnValue; //no return
366 arguments.push_back( actor );
367 arguments.push_back( panGesture );
368 CallJavaScript( returnValue, arguments );
372 void ActorConnection( v8::Isolate* isolate,
373 v8::Local<v8::Function> javaScriptCallback,
374 ActorWrapper* actorWrapper,
375 const std::string& signalName,
378 bool connected(true);
380 ActorCallback* callback =new ActorCallback( isolate, javaScriptCallback, signalName );
382 if( strcmp( signalName.c_str(), SIGNAL_TOUCHED ) == 0 )
384 actor.TouchedSignal().Connect( callback, &ActorCallback::OnTouch );
386 else if( strcmp( signalName.c_str(), SIGNAL_HOVERED ) == 0 )
388 actor.HoveredSignal().Connect( callback, &ActorCallback::OnHover );
390 else if ( strcmp( signalName.c_str(), SIGNAL_MOUSE_WHEEL_EVENT ) == 0 )
392 actor.MouseWheelEventSignal().Connect( callback, &ActorCallback::OnMouseWheel );
394 else if ( strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) == 0 )
396 actor.OnStageSignal().Connect( callback, &ActorCallback::OnStage);
398 else if ( strcmp( signalName.c_str(), SIGNAL_OFF_STAGE ) == 0 )
400 actor.OffStageSignal().Connect( callback, &ActorCallback::OffStage);
409 actorWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
417 void AnimationConnection( v8::Isolate* isolate,
418 v8::Local<v8::Function> javaScriptCallback,
419 AnimationWrapper* animWrapper,
420 const std::string& signalName,
423 if( signalName == ANIMATION_SIGNAL_FINISHED)
425 AnimationCallback* callback =new AnimationCallback( isolate, javaScriptCallback, signalName );
426 anim.FinishedSignal().Connect( callback, &AnimationCallback::Finished );
427 animWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
431 void ImageConnection( v8::Isolate* isolate,
432 v8::Local<v8::Function> javaScriptCallback,
433 ImageWrapper* imageWrapper,
434 const std::string& signalName,
437 // Nine patch will downcast to ResourceImage
438 ResourceImage resourceImage( ResourceImage::DownCast( image ) );
441 DALI_SCRIPT_EXCEPTION( isolate, "can only connect to Resource / NinePatch Images");
445 if( strcmp( signalName.c_str(), SIGNAL_IMAGE_LOADING_FINISHED ) == 0 )
447 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
449 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
450 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
452 else if ( strcmp( signalName.c_str() , SIGNAL_IMAGE_UPLOADED ) == 0 )
454 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
455 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
456 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
460 void StageConnection( v8::Isolate* isolate,
461 v8::Local<v8::Function> javaScriptCallback,
462 StageWrapper* stageWrapper,
463 const std::string& signalName,
466 bool connected( true );
467 StageCallback* callback =new StageCallback( isolate, javaScriptCallback, signalName );
469 if( strcmp( signalName.c_str() ,STAGE_SIGNAL_KEY_EVENT) == 0 )
471 stage.KeyEventSignal().Connect( callback, &StageCallback::KeyEventSignal );
473 else if ( strcmp( signalName.c_str(), STAGE_SIGNAL_EVENT_PROCESSING_FINISHED ) == 0)
475 stage.EventProcessingFinishedSignal().Connect( callback, &StageCallback::EventProcessingFinishedSignal );
477 else if (strcmp( signalName.c_str(), STAGE_SIGNAL_TOUCHED ) == 0 )
479 stage.TouchedSignal().Connect( callback, &StageCallback::TouchedSignal );
488 stageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
496 void KeyboardFocusManagerConnection( v8::Isolate* isolate,
497 v8::Local<v8::Function> javaScriptCallback,
498 KeyboardFocusManagerWrapper* keyboardFocusWrapper,
499 const std::string& signalName,
500 Toolkit::KeyboardFocusManager keyboardFocusManager)
502 bool connected( true );
503 KeyboardFocusCallback* callback =new KeyboardFocusCallback( isolate, javaScriptCallback, signalName );
505 if( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_PRE_FOCUS_CHANGE ) == 0 )
507 keyboardFocusManager.PreFocusChangeSignal().Connect( callback, &KeyboardFocusCallback::PreFocusChangeSignal );
509 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_CHANGED ) == 0 )
511 keyboardFocusManager.FocusChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusChangedSignal );
513 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_GROUP_CHANGED ) == 0 )
515 keyboardFocusManager.FocusGroupChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusGroupSignal );
517 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUSED_ACTOR_ACTIVATED ) == 0 )
519 keyboardFocusManager.FocusedActorActivatedSignal().Connect( callback, &KeyboardFocusCallback::FocusedActorSignal );
528 keyboardFocusWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
536 void PanGestureDetectorConnection( v8::Isolate* isolate,
537 v8::Local<v8::Function> javaScriptCallback,
538 PanGestureDetectorWrapper* panGestureDetectorWrapper,
539 const std::string& signalName,
540 PanGestureDetector panGestureDetector )
542 if( strcmp( signalName.c_str() , SIGNAL_PAN_DETECTED ) == 0 )
544 PanGestureDetectorCallback* callback =new PanGestureDetectorCallback( isolate, javaScriptCallback, signalName );
545 panGestureDetector.DetectedSignal().Connect( callback, &PanGestureDetectorCallback::OnPan );
546 panGestureDetectorWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
550 } // un-named namespace
553 SignalManager::SignalManager()
554 :mInsideCallback(false)
558 SignalManager::~SignalManager()
560 // the object owning the signal manager ( e.g. an actor wrapper ) has been deleted
561 // delete the callbacks objects
562 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
564 BaseCallBack* callback = (*iter);
567 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
569 BaseCallBack* callback = (*iter);
575 void SignalManager::SignalConnect( const v8::FunctionCallbackInfo< v8::Value >& args)
578 // first paramter = signal to connect to
579 // Second parameter = function ( to run )
580 // args.This() = myActor
581 // e.g. myActor.Connect("touched", myJavaScriptActorTouched );
583 // Inside Callback on myJavaScriptActorTouched
584 // myActor.Disconnect("touched", myJavaScriptActorTouched );
586 v8::Isolate* isolate = args.GetIsolate();
587 v8::HandleScope handleScope( isolate );
589 if( !args[1]->IsFunction() )
591 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
596 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
598 // get the handle wrapper
599 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
601 // First paramter = signal name as a string
603 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
606 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
610 if( signal.empty() || ( signal.length() > MAX_SIGNAL_NAME_LENGTH ) )
612 DALI_SCRIPT_EXCEPTION(isolate, "signal name length out of range");
615 // We need to determine what type of function needs to be hooked
616 // see if we're connecting to an Actor
617 switch( baseObject->GetType() )
619 case BaseWrappedObject::ACTOR:
621 ActorWrapper* actorWrapper = static_cast< ActorWrapper*>( baseObject );
622 ActorConnection( isolate, func, actorWrapper, signal, actorWrapper->GetActor() );
625 case BaseWrappedObject::ANIMATION:
627 AnimationWrapper* animWrapper = static_cast< AnimationWrapper*>( baseObject );
628 AnimationConnection( isolate, func, animWrapper, signal, animWrapper->GetAnimation() );
631 case BaseWrappedObject::IMAGE:
633 ImageWrapper* imageWrapper = static_cast< ImageWrapper*>( baseObject );
634 ImageConnection( isolate, func, imageWrapper, signal, imageWrapper->GetImage() );
637 case BaseWrappedObject::STAGE:
639 StageWrapper* stageWrapper = static_cast< StageWrapper*>( baseObject );
640 StageConnection( isolate, func, stageWrapper, signal, stageWrapper->GetStage() );
643 case BaseWrappedObject::KEYBOARD_FOCUS_MANAGER:
645 KeyboardFocusManagerWrapper* keyboardFocusWrapper = static_cast< KeyboardFocusManagerWrapper*>( baseObject );
646 KeyboardFocusManagerConnection( isolate, func, keyboardFocusWrapper, signal, keyboardFocusWrapper->GetKeyboardFocusManager() );
649 case BaseWrappedObject::PAN_GESTURE_DETECTOR:
651 PanGestureDetectorWrapper* panGestureDetectorWrapper = static_cast< PanGestureDetectorWrapper*>( baseObject );
652 PanGestureDetectorConnection( isolate, func, panGestureDetectorWrapper, signal, panGestureDetectorWrapper->GetPanGestureDetector() );
657 DALI_SCRIPT_EXCEPTION( isolate, "object does not support connections");
664 void SignalManager::SignalDisconnect( const v8::FunctionCallbackInfo< v8::Value >& args)
666 // we can get the function name.... use that to disconnect from the object
667 v8::Isolate* isolate = args.GetIsolate();
668 v8::HandleScope handleScope( isolate );
670 if( !args[1]->IsFunction() )
672 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
677 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
679 // get the handle wrapper
680 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
682 // First parameter = signal name as a string
684 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
687 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
691 SignalManager* signalManager = baseObject->GetSignalManager();
694 signalManager->RemoveCallback( isolate, signal, func);
699 void SignalManager::AddCallback( BaseCallBack* callback )
701 // used by the callback to inform signal manager when it is being triggered.
702 callback->SetEmitInterface( this );
704 mCallbacks.PushBack( callback );
706 void SignalManager::RemoveCallback( v8::Isolate* isolate, const std::string& signalName, const v8::Local<v8::Function>& function )
709 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
711 BaseCallBack* callback = (*iter);
712 if( ( callback->mSignalName == signalName ) &&
713 ( callback->IsFunction( function ) ) )
715 mCallbacks.Erase( iter );
717 // if we're inside a callback::Call function, then deleting it will cause a seg fault
718 if( mInsideCallback )
720 callback->DisconnectAll();
721 mDisconnectedCallbacks.PushBack( callback );
732 void SignalManager::CallbackEnter()
734 mInsideCallback = true;
737 void SignalManager::CallbackExit()
739 // this gets called when we've finished calling into JavaScript, e.g. as a result of animation finishing
740 // which is being listened to by a javascript function.
742 // it possible that inside the JavaScript call, it tries to disconnect.
743 // If this happens the callback is added to the mDisconnectedCallbacks list.
744 // We then delay deleting of the callback object until the JavaScript call has finished in this function.
746 mInsideCallback = false;
748 // lets delete any call backs that were disconnect during the JavaScript call
749 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
751 BaseCallBack* callback = (*iter);
754 mDisconnectedCallbacks.Clear();
758 } // namespace V8Plugin