[problem] Actor is too closely coupled with gesture-detectors.
[cause] GestureData is private within Actor which stores info about gesture detection.
[solution] Move GestureData out of actor-impl.cpp and Actor provides a method to retrieve this.
Change-Id: I534723f5cfb772c88f13d2d90ab97d8c64571f8f
Signed-off-by: Adeel Kazmi <adeel.kazmi@samsung.com>
#include <dali/internal/update/nodes/node-declarations.h>
#include <dali/internal/update/animation/scene-graph-constraint.h>
#include <dali/internal/event/effects/shader-effect-impl.h>
+#include <dali/internal/event/events/actor-gesture-data.h>
#include <dali/internal/common/message.h>
#include <dali/integration-api/debug.h>
#include <dali/internal/event/dynamics/dynamics-world-impl.h>
#endif
-#include <dali/internal/event/events/pan-gesture-detector-impl.h>
-#include <dali/internal/event/events/pinch-gesture-detector-impl.h>
-#include <dali/internal/event/events/long-press-gesture-detector-impl.h>
-#include <dali/internal/event/events/tap-gesture-detector-impl.h>
-
using Dali::Internal::SceneGraph::Node;
using Dali::Internal::SceneGraph::AnimatableProperty;
using Dali::Internal::SceneGraph::PropertyBase;
unsigned int Actor::mActorCounter = 0;
ActorContainer Actor::mNullChildren;
-// Encapsulate actor related gesture information
-struct GestureData
-{
- /**
- * Constructor
- */
- GestureData()
- : gesturesRequired( Gesture::Type( 0 ) ),
- panDetectors( NULL ),
- pinchDetectors( NULL ),
- longPressDetectors( NULL ),
- tapDetectors( NULL )
- {
- }
-
- /**
- * Destructor
- */
- ~GestureData()
- {
- delete panDetectors;
- delete pinchDetectors;
- delete longPressDetectors;
- delete tapDetectors;
- }
-
- /**
- * Checks if the containers in GestureData are empty
- */
- bool Empty() const
- {
- return !panDetectors &&
- !pinchDetectors &&
- !longPressDetectors &&
- !tapDetectors;
- }
-
- /**
- * Template to add a detector to the appropriate container. Dynamically allocates the container
- * only if it is used.
- */
- template< typename DetectorType, typename ContainerType >
- void AddDetector( ContainerType*& containerPtr, GestureDetector* detector )
- {
- if ( NULL == containerPtr )
- {
- containerPtr = new ContainerType;
- }
-
- containerPtr->push_back( static_cast< DetectorType* >( detector ) );
- gesturesRequired = Gesture::Type( gesturesRequired | detector->GetType() );
- }
-
- /**
- * Template to remove a detector from the appropriate container. Deletes the container if it is
- * no longer required.
- */
- template< typename ContainerType >
- void RemoveDetector( ContainerType*& containerPtr, GestureDetector* detector )
- {
- if ( NULL != containerPtr )
- {
- ContainerType& container( *containerPtr );
- typename ContainerType::iterator match( std::remove( container.begin(), container.end(), detector ) );
- DALI_ASSERT_DEBUG( match != container.end() && "Actor does not have the detector" );
- container.erase( match, container.end() );
-
- if ( container.empty() )
- {
- gesturesRequired = Gesture::Type( gesturesRequired & ~detector->GetType() );
- delete containerPtr;
- containerPtr = NULL;
- }
- }
- }
-
- Gesture::Type gesturesRequired;
-
- PanGestureDetectorContainer* panDetectors;
- PinchGestureDetectorContainer* pinchDetectors;
- LongPressGestureDetectorContainer* longPressDetectors;
- TapGestureDetectorContainer* tapDetectors;
-};
-
#ifdef DYNAMICS_SUPPORT
// Encapsulate actor related dynamics data
IsNodeConnected();
}
-void Actor::AddGestureDetector( GestureDetector& detector )
+ActorGestureData& Actor::GetGestureData()
{
+ // Likely scenario is that once gesture-data is created for this actor, the actor will require
+ // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
if ( NULL == mGestureData )
{
- mGestureData = new GestureData;
- }
-
- const Gesture::Type type( detector.GetType() );
- switch ( type )
- {
- case Gesture::Pan:
- {
- mGestureData->AddDetector< PanGestureDetector, PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
- break;
- }
-
- case Gesture::Pinch:
- {
- mGestureData->AddDetector< PinchGestureDetector, PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
- break;
- }
-
- case Gesture::LongPress:
- {
- mGestureData->AddDetector< LongPressGestureDetector, LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
- break;
- }
-
- case Gesture::Tap:
- {
- mGestureData->AddDetector< TapGestureDetector, TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
- break;
- }
- }
-}
-
-void Actor::RemoveGestureDetector( GestureDetector& detector )
-{
- if ( NULL != mGestureData )
- {
- switch ( detector.GetType() )
- {
- case Gesture::Pan:
- {
- mGestureData->RemoveDetector< PanGestureDetectorContainer >( mGestureData->panDetectors, &detector );
- break;
- }
-
- case Gesture::Pinch:
- {
- mGestureData->RemoveDetector< PinchGestureDetectorContainer >( mGestureData->pinchDetectors, &detector );
- break;
- }
-
- case Gesture::LongPress:
- {
- mGestureData->RemoveDetector< LongPressGestureDetectorContainer >( mGestureData->longPressDetectors, &detector );
- break;
- }
-
- case Gesture::Tap:
- {
- mGestureData->RemoveDetector< TapGestureDetectorContainer >( mGestureData->tapDetectors, &detector );
- break;
- }
- }
-
- if ( mGestureData->Empty() )
- {
- delete mGestureData;
- mGestureData = NULL;
- }
+ mGestureData = new ActorGestureData;
}
+ return *mGestureData;
}
bool Actor::IsGestureRequred( Gesture::Type type ) const
{
- bool required( false );
- if ( NULL != mGestureData )
- {
- required = type & mGestureData->gesturesRequired;
- }
- return required;
+ return mGestureData && mGestureData->IsGestureRequred( type );
}
bool Actor::EmitTouchEventSignal(const TouchEvent& event)
{
class Actor;
-class GestureDetector;
+class ActorGestureData;
class RenderTask;
class ShaderEffect;
struct DynamicsData;
-struct GestureData;
typedef IntrusivePtr<Actor> ActorPtr;
typedef IntrusivePtr<ShaderEffect> ShaderEffectPtr;
// Gestures
/**
- * Adds a gesture detector to the actor so that the actor is aware that it requires this type of
- * gesture.
- * @param[in] detector The detector being added.
- * @note A raw pointer to the detector is stored, so the detector MUST remove itself when it is
- * destroyed using RemoveGestureDetector()
+ * Retrieve the gesture data associated with this actor. The first call to this method will
+ * allocate space for the ActorGestureData so this should only be called if an actor really does
+ * require gestures.
+ * @return Reference to the ActorGestureData for this actor.
+ * @note Once the gesture-data is created for an actor it is likely that gestures are required
+ * throughout the actor's lifetime so it will only be deleted when the actor is destroyed.
*/
- void AddGestureDetector( GestureDetector& detector );
-
- /**
- * Removes a previously added gesture detector from the actor. If no more gesture detectors of
- * this type are registered with this actor then the actor will no longer be hit-tested for that
- * gesture.
- * @param[in] detector The detector to remove.
- */
- void RemoveGestureDetector( GestureDetector& detector );
+ ActorGestureData& GetGestureData();
/**
* Queries whether the actor requires the gesture type.
DynamicsData* mDynamicsData; ///< optional physics data
#endif
- GestureData* mGestureData; /// Optional Gesture data. Only created when actor requires gestures
+ ActorGestureData* mGestureData; /// Optional Gesture data. Only created when actor requires gestures
ActorAttachmentPtr mAttachment; ///< Optional referenced attachment
ShaderEffectPtr mShaderEffect; ///< Optional referenced shader effect
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/event/events/actor-gesture-data.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+/**
+ * Template to add a detector to the appropriate container. Dynamically allocates the container only if it is used.
+ */
+template< typename DetectorType, typename ContainerType >
+inline void AddDetector( ContainerType*& containerPtr, GestureDetector* detector, Gesture::Type& gesturesRequired )
+{
+ if ( NULL == containerPtr )
+ {
+ containerPtr = new ContainerType;
+ }
+
+ containerPtr->push_back( static_cast< DetectorType* >( detector ) );
+ gesturesRequired = Gesture::Type( gesturesRequired | detector->GetType() );
+}
+
+/**
+ * Template to remove a detector from the appropriate container. Deletes the container if it is no longer required.
+ */
+template< typename ContainerType >
+inline void RemoveDetector( ContainerType*& containerPtr, GestureDetector* detector, Gesture::Type& gesturesRequired )
+{
+ if ( NULL != containerPtr )
+ {
+ ContainerType& container( *containerPtr );
+ typename ContainerType::iterator match( std::remove( container.begin(), container.end(), detector ) );
+ DALI_ASSERT_DEBUG( match != container.end() && "Actor does not have the detector" );
+ container.erase( match, container.end() );
+
+ if ( container.empty() )
+ {
+ gesturesRequired = Gesture::Type( gesturesRequired & ~detector->GetType() );
+ delete containerPtr;
+ containerPtr = NULL;
+ }
+ }
+}
+
+} // unnamed namespace
+
+ActorGestureData::ActorGestureData()
+: gesturesRequired( Gesture::Type( 0 ) ),
+ panDetectors( NULL ),
+ pinchDetectors( NULL ),
+ longPressDetectors( NULL ),
+ tapDetectors( NULL )
+{
+}
+
+ActorGestureData::~ActorGestureData()
+{
+ delete panDetectors;
+ delete pinchDetectors;
+ delete longPressDetectors;
+ delete tapDetectors;
+}
+
+void ActorGestureData::AddGestureDetector( GestureDetector& detector )
+{
+ const Gesture::Type type( detector.GetType() );
+ switch ( type )
+ {
+ case Gesture::Pan:
+ {
+ AddDetector< PanGestureDetector, PanGestureDetectorContainer >( panDetectors, &detector, gesturesRequired );
+ break;
+ }
+
+ case Gesture::Pinch:
+ {
+ AddDetector< PinchGestureDetector, PinchGestureDetectorContainer >( pinchDetectors, &detector, gesturesRequired );
+ break;
+ }
+
+ case Gesture::LongPress:
+ {
+ AddDetector< LongPressGestureDetector, LongPressGestureDetectorContainer >( longPressDetectors, &detector, gesturesRequired );
+ break;
+ }
+
+ case Gesture::Tap:
+ {
+ AddDetector< TapGestureDetector, TapGestureDetectorContainer >( tapDetectors, &detector, gesturesRequired );
+ break;
+ }
+ }
+}
+
+void ActorGestureData::RemoveGestureDetector( GestureDetector& detector )
+{
+ switch ( detector.GetType() )
+ {
+ case Gesture::Pan:
+ {
+ RemoveDetector< PanGestureDetectorContainer >( panDetectors, &detector, gesturesRequired );
+ break;
+ }
+
+ case Gesture::Pinch:
+ {
+ RemoveDetector< PinchGestureDetectorContainer >( pinchDetectors, &detector, gesturesRequired );
+ break;
+ }
+
+ case Gesture::LongPress:
+ {
+ RemoveDetector< LongPressGestureDetectorContainer >( longPressDetectors, &detector, gesturesRequired );
+ break;
+ }
+
+ case Gesture::Tap:
+ {
+ RemoveDetector< TapGestureDetectorContainer >( tapDetectors, &detector, gesturesRequired );
+ break;
+ }
+ }
+}
+
+} // namespace Internal
+
+} // namespace Dali
+
--- /dev/null
+#ifndef __DALI_INTERNAL_ACTOR_GESTURE_DATA_H__
+#define __DALI_INTERNAL_ACTOR_GESTURE_DATA_H__
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/events/pan-gesture-detector-impl.h>
+#include <dali/internal/event/events/pinch-gesture-detector-impl.h>
+#include <dali/internal/event/events/long-press-gesture-detector-impl.h>
+#include <dali/internal/event/events/tap-gesture-detector-impl.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+/**
+ * Holds gesture specific data for an Actor
+ */
+class ActorGestureData
+{
+public:
+
+ /**
+ * Constructor
+ */
+ ActorGestureData();
+
+ /**
+ * Non-virtual Destructor
+ */
+ ~ActorGestureData();
+
+ /**
+ * Adds a gesture detector to the data so that the owning actor is aware that it requires this
+ * type of gesture.
+ * @param[in] detector The detector being added.
+ * @note A raw pointer to the detector is stored, so the detector MUST remove itself when it is
+ * destroyed using RemoveGestureDetector()
+ */
+ void AddGestureDetector( GestureDetector& detector );
+
+ /**
+ * Removes a previously added gesture detector from the data. If no more gesture detectors of
+ * this type are registered then the actor owning this data will no longer be hit-tested for that
+ * gesture.
+ * @param[in] detector The detector to remove.
+ */
+ void RemoveGestureDetector( GestureDetector& detector );
+
+ /**
+ * Queries whether the actor requires the gesture type.
+ * @param[in] type The gesture type.
+ * @return true if the gesture is required, false otherwise.
+ */
+ inline bool IsGestureRequred( Gesture::Type type ) const
+ {
+ return type & gesturesRequired;
+ }
+
+private:
+
+ Gesture::Type gesturesRequired; ///< Stores which gestures are required
+
+ PanGestureDetectorContainer* panDetectors; ///< Pointer to a container of pan-detectors
+ PinchGestureDetectorContainer* pinchDetectors; ///< Pointer to a container of pinch-detectors
+ LongPressGestureDetectorContainer* longPressDetectors; ///< Pointer to a container of long-press-detectors
+ TapGestureDetectorContainer* tapDetectors; ///< Pointer to a container of tap-detectors
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_ACTOR_GESTURE_DATA_H__
+
// INTERNAL INCLUDES
#include <dali/integration-api/debug.h>
+#include <dali/internal/event/events/actor-gesture-data.h>
#include <dali/internal/event/events/gesture-event-processor.h>
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/event/common/stage-impl.h>
namespace Internal
{
-namespace
-{
-const std::string INVALID_PROPERTY; // Empty string for invalid calls
-}
-
GestureDetector::GestureDetector(Gesture::Type type)
: mType(type),
mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor())
{
Actor* actor( *iter );
actor->RemoveObserver( *this );
- actor->RemoveGestureDetector( *this );
+ actor->GetGestureData().RemoveGestureDetector( *this );
}
mAttachedActors.clear();
actor.AddObserver(*this);
// Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
- actor.AddGestureDetector( *this );
+ actor.GetGestureData().AddGestureDetector( *this );
// Notification for derived classes
OnActorAttach(actor);
// We no longer need to observe the actor's destruction
actor.RemoveObserver(*this);
- // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm)
- actor.RemoveGestureDetector( *this );
+ // Remove detector from actor-gesture-data
+ actor.GetGestureData().RemoveGestureDetector( *this );
mAttachedActors.erase(match);
// We no longer need to observe the actor's destruction
actor->RemoveObserver(*this);
- // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm)
- actor->RemoveGestureDetector( *this );
+ // Remove detector from actor-gesture-data
+ actor->GetGestureData().RemoveGestureDetector( *this );
// Notification for derived classes
OnActorDetach(*actor);
const std::string& GestureDetector::GetDefaultPropertyName( Property::Index index ) const
{
- return INVALID_PROPERTY;
+ return String::EMPTY;
}
Property::Index GestureDetector::GetDefaultPropertyIndex(const std::string& name) const
$(internal_src_dir)/event/common/type-registry-impl.cpp \
$(internal_src_dir)/event/effects/shader-effect-impl.cpp \
$(internal_src_dir)/event/effects/shader-factory.cpp \
+ $(internal_src_dir)/event/events/actor-gesture-data.cpp \
$(internal_src_dir)/event/events/event-processor.cpp \
$(internal_src_dir)/event/events/key-event-processor.cpp \
$(internal_src_dir)/event/events/gesture-detector-impl.cpp \