2 * Copyright (c) 2017 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-data.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/public-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_TOUCH = "touch";
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_TOUCH = "touch";
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 TouchData& touch )
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( touch );
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 TouchSignal( const TouchData& touch )
313 std::vector< Dali::Any > arguments;
314 Dali::Any returnValue; //no return
315 arguments.push_back( touch );
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_TOUCH ) == 0 )
403 actor.TouchSignal().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) );
433 DALI_SCRIPT_EXCEPTION( isolate, "the signal is not available in this object.");
437 void AnimationConnection( v8::Isolate* isolate,
438 v8::Local<v8::Function> javaScriptCallback,
439 AnimationWrapper* animWrapper,
440 const std::string& signalName,
443 if( signalName == ANIMATION_SIGNAL_FINISHED)
445 AnimationCallback* callback =new AnimationCallback( isolate, javaScriptCallback, signalName );
446 anim.FinishedSignal().Connect( callback, &AnimationCallback::Finished );
447 animWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
451 void ImageConnection( v8::Isolate* isolate,
452 v8::Local<v8::Function> javaScriptCallback,
453 ImageWrapper* imageWrapper,
454 const std::string& signalName,
457 // Nine patch will downcast to ResourceImage
458 ResourceImage resourceImage( ResourceImage::DownCast( image ) );
461 DALI_SCRIPT_EXCEPTION( isolate, "can only connect to Resource / NinePatch Images");
465 if( strcmp( signalName.c_str(), SIGNAL_IMAGE_LOADING_FINISHED ) == 0 )
467 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
469 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
470 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
472 else if ( strcmp( signalName.c_str() , SIGNAL_IMAGE_UPLOADED ) == 0 )
474 ImageCallback* callback =new ImageCallback( isolate, javaScriptCallback, signalName );
475 resourceImage.LoadingFinishedSignal().Connect( callback, &ImageCallback::LoadingFinished );
476 imageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
480 void StageConnection( v8::Isolate* isolate,
481 v8::Local<v8::Function> javaScriptCallback,
482 StageWrapper* stageWrapper,
483 const std::string& signalName,
486 bool connected( true );
487 StageCallback* callback =new StageCallback( isolate, javaScriptCallback, signalName );
489 if( strcmp( signalName.c_str() ,STAGE_SIGNAL_KEY_EVENT) == 0 )
491 stage.KeyEventSignal().Connect( callback, &StageCallback::KeyEventSignal );
493 else if ( strcmp( signalName.c_str(), STAGE_SIGNAL_EVENT_PROCESSING_FINISHED ) == 0)
495 stage.EventProcessingFinishedSignal().Connect( callback, &StageCallback::EventProcessingFinishedSignal );
497 else if (strcmp( signalName.c_str(), STAGE_SIGNAL_TOUCH ) == 0 )
499 stage.TouchSignal().Connect( callback, &StageCallback::TouchSignal );
508 stageWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
516 void KeyboardFocusManagerConnection( v8::Isolate* isolate,
517 v8::Local<v8::Function> javaScriptCallback,
518 KeyboardFocusManagerWrapper* keyboardFocusWrapper,
519 const std::string& signalName,
520 Toolkit::KeyboardFocusManager keyboardFocusManager)
522 bool connected( true );
523 KeyboardFocusCallback* callback =new KeyboardFocusCallback( isolate, javaScriptCallback, signalName );
525 if( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_PRE_FOCUS_CHANGE ) == 0 )
527 keyboardFocusManager.PreFocusChangeSignal().Connect( callback, &KeyboardFocusCallback::PreFocusChangeSignal );
529 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_CHANGED ) == 0 )
531 keyboardFocusManager.FocusChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusChangedSignal );
533 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUS_GROUP_CHANGED ) == 0 )
535 keyboardFocusManager.FocusGroupChangedSignal().Connect( callback, &KeyboardFocusCallback::FocusGroupSignal );
537 else if ( strcmp( signalName.c_str(), KEYBOARD_FOCUS_MANAGER_SIGNAL_FOCUSED_ACTOR_ENTER_KEY ) == 0 )
539 keyboardFocusManager.FocusedActorEnterKeySignal().Connect( callback, &KeyboardFocusCallback::EnterKeyPressedActorSignal );
548 keyboardFocusWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
556 void PanGestureDetectorConnection( v8::Isolate* isolate,
557 v8::Local<v8::Function> javaScriptCallback,
558 PanGestureDetectorWrapper* panGestureDetectorWrapper,
559 const std::string& signalName,
560 PanGestureDetector panGestureDetector )
562 if( strcmp( signalName.c_str() , SIGNAL_PAN_DETECTED ) == 0 )
564 PanGestureDetectorCallback* callback =new PanGestureDetectorCallback( isolate, javaScriptCallback, signalName );
565 panGestureDetector.DetectedSignal().Connect( callback, &PanGestureDetectorCallback::OnPan );
566 panGestureDetectorWrapper->GetSignalManager()->AddCallback( static_cast<BaseCallBack*>(callback) );
570 } // un-named namespace
573 SignalManager::SignalManager()
574 :mInsideCallback(false)
578 SignalManager::~SignalManager()
580 // the object owning the signal manager ( e.g. an actor wrapper ) has been deleted
581 // delete the callbacks objects
582 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
584 BaseCallBack* callback = (*iter);
587 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
589 BaseCallBack* callback = (*iter);
595 void SignalManager::SignalConnect( const v8::FunctionCallbackInfo< v8::Value >& args)
598 // first paramter = signal to connect to
599 // Second parameter = function ( to run )
600 // args.This() = myActor
601 // e.g. myActor.Connect("touch", myJavaScriptActorTouched );
603 // Inside Callback on myJavaScriptActorTouched
604 // myActor.Disconnect("touch", myJavaScriptActorTouched );
606 v8::Isolate* isolate = args.GetIsolate();
607 v8::HandleScope handleScope( isolate );
609 if( !args[1]->IsFunction() )
611 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
616 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
618 // get the handle wrapper
619 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
621 // First paramter = signal name as a string
623 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
626 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
630 if( signal.empty() || ( signal.length() > MAX_SIGNAL_NAME_LENGTH ) )
632 DALI_SCRIPT_EXCEPTION(isolate, "signal name length out of range");
635 // We need to determine what type of function needs to be hooked
636 // see if we're connecting to an Actor
637 switch( baseObject->GetType() )
639 case BaseWrappedObject::ACTOR:
641 ActorWrapper* actorWrapper = static_cast< ActorWrapper*>( baseObject );
642 ActorConnection( isolate, func, actorWrapper, signal, actorWrapper->GetActor() );
645 case BaseWrappedObject::ANIMATION:
647 AnimationWrapper* animWrapper = static_cast< AnimationWrapper*>( baseObject );
648 AnimationConnection( isolate, func, animWrapper, signal, animWrapper->GetAnimation() );
651 case BaseWrappedObject::IMAGE:
653 ImageWrapper* imageWrapper = static_cast< ImageWrapper*>( baseObject );
654 ImageConnection( isolate, func, imageWrapper, signal, imageWrapper->GetImage() );
657 case BaseWrappedObject::STAGE:
659 StageWrapper* stageWrapper = static_cast< StageWrapper*>( baseObject );
660 StageConnection( isolate, func, stageWrapper, signal, stageWrapper->GetStage() );
663 case BaseWrappedObject::KEYBOARD_FOCUS_MANAGER:
665 KeyboardFocusManagerWrapper* keyboardFocusWrapper = static_cast< KeyboardFocusManagerWrapper*>( baseObject );
666 KeyboardFocusManagerConnection( isolate, func, keyboardFocusWrapper, signal, keyboardFocusWrapper->GetKeyboardFocusManager() );
669 case BaseWrappedObject::PAN_GESTURE_DETECTOR:
671 PanGestureDetectorWrapper* panGestureDetectorWrapper = static_cast< PanGestureDetectorWrapper*>( baseObject );
672 PanGestureDetectorConnection( isolate, func, panGestureDetectorWrapper, signal, panGestureDetectorWrapper->GetPanGestureDetector() );
677 DALI_SCRIPT_EXCEPTION( isolate, "object does not support connections");
684 void SignalManager::SignalDisconnect( const v8::FunctionCallbackInfo< v8::Value >& args)
686 // we can get the function name.... use that to disconnect from the object
687 v8::Isolate* isolate = args.GetIsolate();
688 v8::HandleScope handleScope( isolate );
690 if( !args[1]->IsFunction() )
692 DALI_SCRIPT_EXCEPTION(isolate, "function parameter not found ");
697 v8::Local<v8::Function> func =v8::Handle<v8::Function>::Cast(args[1]);
699 // get the handle wrapper
700 BaseWrappedObject* baseObject = BaseWrappedObject::UnWrap( isolate, args.This() );
702 // First parameter = signal name as a string
704 std::string signal = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
707 DALI_SCRIPT_EXCEPTION(isolate, "signal name parameter not found ");
711 SignalManager* signalManager = baseObject->GetSignalManager();
714 signalManager->RemoveCallback( isolate, signal, func);
719 void SignalManager::AddCallback( BaseCallBack* callback )
721 // used by the callback to inform signal manager when it is being triggered.
722 callback->SetEmitInterface( this );
724 mCallbacks.PushBack( callback );
726 void SignalManager::RemoveCallback( v8::Isolate* isolate, const std::string& signalName, const v8::Local<v8::Function>& function )
729 for( CallBackContainer::Iterator iter = mCallbacks.Begin(); iter != mCallbacks.End(); ++iter )
731 BaseCallBack* callback = (*iter);
732 if( ( callback->mSignalName == signalName ) &&
733 ( callback->IsFunction( function ) ) )
735 mCallbacks.Erase( iter );
737 // if we're inside a callback::Call function, then deleting it will cause a seg fault
738 if( mInsideCallback )
740 callback->DisconnectAll();
741 mDisconnectedCallbacks.PushBack( callback );
752 void SignalManager::CallbackEnter()
754 mInsideCallback = true;
757 void SignalManager::CallbackExit()
759 // this gets called when we've finished calling into JavaScript, e.g. as a result of animation finishing
760 // which is being listened to by a javascript function.
762 // it possible that inside the JavaScript call, it tries to disconnect.
763 // If this happens the callback is added to the mDisconnectedCallbacks list.
764 // We then delay deleting of the callback object until the JavaScript call has finished in this function.
766 mInsideCallback = false;
768 // lets delete any call backs that were disconnect during the JavaScript call
769 for( CallBackContainer::Iterator iter = mDisconnectedCallbacks.Begin(); iter != mDisconnectedCallbacks.End(); ++iter )
771 BaseCallBack* callback = (*iter);
774 mDisconnectedCallbacks.Clear();
778 } // namespace V8Plugin