mImpl->ProcessEvents();
}
-void Core::UpdateTouchData(const TouchData& touch)
-{
- mImpl->UpdateTouchData(touch);
-}
-
unsigned int Core::GetMaximumUpdateCount() const
{
return mImpl->GetMaximumUpdateCount();
void ProcessEvents();
/**
- * Update external raw touch data in core.
- * The core will use the touch data to generate Dali Touch/Gesture events for applications to use
- * in the update thread.
- * @param[in] touch The raw touch data.
- * @note This can be called from either the event thread OR a dedicated touch thread.
- */
- void UpdateTouchData(const TouchData& touch);
-
- /**
* The Core::Update() method prepares a frame for rendering. This method determines how many frames
* may be prepared, ahead of the rendering.
* For example if the maximum update count is 2, then Core::Update() for frame N+1 may be processed
+++ /dev/null
-#ifndef __DALI_INTEGRATION_TOUCH_DATA_H__
-#define __DALI_INTEGRATION_TOUCH_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.
- *
- */
-#include <dali/public-api/common/vector-wrapper.h>
-
-namespace Dali
-{
-
-namespace Integration
-{
-
-struct TouchData;
-
-typedef std::vector<TouchData> TouchDataContainer;
-typedef TouchDataContainer::iterator TouchDataIter;
-
-/**
- * TouchData structure
- * represents the raw touch information from touch-screen for
- * a single touch event e.g.
- *
- * "First finger touching down at pixel 123,456 on the screen (relative
- * to top left corner of phone in portrait mode). at timestamp 125ms (from a reference
- * timestamp e.g. phone boot being 0secs)."
- * TouchData(Down, 125, 0, 123, 456)
- *
- * "Above finger moving to pixel 133,457, at timestamp 150ms"
- * TouchData(Motion, 150, 0, 133, 457)
- *
- * "Additional finger touching down at pixel 50, 75, at timestamp 175ms"
- * TouchData(Down, 175, 1, 50, 75)
- *
- * "First finger removing at pixel 143, 458, at timestamp 200ms"
- * TouchData(Up, 200, 0, 143, 458)
- *
- * "Additional finger removing at pixel 51, 77, at timestamp 225ms"
- * TouchData(Up, 225, 1, 51, 77)
- *
- * Note: Multiple incidents of touch data can be present at the same timestamp.
- */
-struct TouchData
-{
-
- /**
- * The Touch Type for this data.
- */
- enum TouchType
- {
- Down, // Touch started
- Up, // Touch ended
- Motion // Touch is continuing
- };
-
- TouchData()
- : type(Motion),
- timestamp(0u),
- index(0u),
- x(0),
- y(0)
- {
-
- }
-
- TouchData(TouchType type,
- unsigned int timestamp,
- unsigned int index,
- int x,
- int y)
- : type(type),
- timestamp(timestamp),
- index(index),
- x(x),
- y(y)
- {
- }
-
- TouchType type;
- unsigned int timestamp;
- unsigned int index;
- int x;
- int y;
-
-};
-
-} // namespace Integration
-
-} // namespace Dali
-
-#endif // __DALI_INTEGRATION_TOUCH_DATA_H__
$(platform_abstraction_src_dir)/events/pan-gesture-event.h \
$(platform_abstraction_src_dir)/events/pinch-gesture-event.h \
$(platform_abstraction_src_dir)/events/tap-gesture-event.h \
- $(platform_abstraction_src_dir)/events/touch-data.h \
$(platform_abstraction_src_dir)/events/touch-event-combiner.h \
$(platform_abstraction_src_dir)/events/touch-event-integ.h
#include <dali/internal/update/common/texture-cache-dispatcher.h>
#include <dali/internal/update/manager/update-manager.h>
#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/update/touch/touch-resampler.h>
#include <dali/internal/render/common/performance-monitor.h>
#include <dali/internal/render/common/render-manager.h>
*mDiscardQueue,
renderQueue );
- mTouchResampler = TouchResampler::New();
-
mUpdateManager = new UpdateManager( *mNotificationManager,
*mAnimationPlaylist,
*mPropertyNotificationManager,
renderController,
*mRenderManager,
renderQueue,
- *mTextureCacheDispatcher,
- *mTouchResampler );
+ *mTextureCacheDispatcher );
mRenderManager->SetShaderSaver( *mUpdateManager );
delete mDiscardQueue;
delete mTextureCacheDispatcher;
delete mUpdateManager;
- delete mTouchResampler;
delete mRenderManager;
delete mTextureUploadedQueue;
}
const bool messagesToProcess = mUpdateManager->FlushQueue();
// Check if the touch or gestures require updates.
- const bool touchNeedsUpdate = mTouchResampler->NeedsUpdate();
const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
- if( messagesToProcess || touchNeedsUpdate || gestureNeedsUpdate )
+ if( messagesToProcess || gestureNeedsUpdate )
{
// tell the render controller to keep update thread running
mRenderController.RequestUpdate();
mProcessingEvent = false;
}
-void Core::UpdateTouchData(const Integration::TouchData& touch)
-{
- mTouchResampler->SendTouchData( touch );
-}
-
unsigned int Core::GetMaximumUpdateCount() const
{
return MAXIMUM_UPDATE_COUNT;
void ProcessEvents();
/**
- * @copydoc Dali::Integration::Core::UpdateTouchData(const Integration::TouchData&)
- */
- void UpdateTouchData(const Integration::TouchData& touch);
-
- /**
* @copydoc Dali::Integration::Core::GetMaximumUpdateCount()
*/
unsigned int GetMaximumUpdateCount() const;
ShaderFactory* mShaderFactory; ///< Shader resource factory
ResourceClient* mResourceClient; ///< Asynchronous Resource Loading
ResourceManager* mResourceManager; ///< Asynchronous Resource Loading
- TouchResampler* mTouchResampler; ///< Resamples touches to correct frame rate.
IntrusivePtr< RelayoutController > mRelayoutController; ///< Size negotiation relayout controller
bool mIsActive : 1; ///< Whether Core is active or suspended
$(internal_src_dir)/update/gestures/pan-gesture-profiling.cpp \
$(internal_src_dir)/update/gestures/scene-graph-pan-gesture.cpp \
$(internal_src_dir)/update/queue/update-message-queue.cpp \
- $(internal_src_dir)/update/touch/touch-resampler.cpp \
$(internal_src_dir)/update/manager/prepare-render-instructions.cpp \
$(internal_src_dir)/update/manager/process-render-tasks.cpp \
$(internal_src_dir)/update/manager/transform-manager.cpp \
#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
#include <dali/internal/update/rendering/scene-graph-texture-set.h>
#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/update/touch/touch-resampler.h>
#include <dali/internal/render/common/render-instruction-container.h>
#include <dali/internal/render/common/render-manager.h>
RenderController& renderController,
RenderManager& renderManager,
RenderQueue& renderQueue,
- TouchResampler& touchResampler,
SceneGraphBuffers& sceneGraphBuffers )
: renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
notificationManager( notificationManager ),
renderManager( renderManager ),
renderQueue( renderQueue ),
renderInstructions( renderManager.GetRenderInstructionContainer() ),
- touchResampler( touchResampler ),
backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
taskList( renderMessageDispatcher, resourceManager ),
systemLevelTaskList( renderMessageDispatcher, resourceManager ),
RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
RenderQueue& renderQueue; ///< Used to queue messages for the next render
RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
- TouchResampler& touchResampler; ///< Used to resample touch events on every update.
Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
RenderController& controller,
RenderManager& renderManager,
RenderQueue& renderQueue,
- TextureCacheDispatcher& textureCacheDispatcher,
- TouchResampler& touchResampler )
+ TextureCacheDispatcher& textureCacheDispatcher )
: mImpl(NULL)
{
mImpl = new Impl( notificationManager,
controller,
renderManager,
renderQueue,
- touchResampler,
mSceneGraphBuffers );
textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
//Process Touches & Gestures
- mImpl->touchResampler.Update();
const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
const bool updateScene = // The scene-graph requires an update if..
* @param[in] renderManager This is responsible for rendering the results of each "update".
* @param[in] renderQueue Used to queue messages for the next render.
* @param[in] textureCacheDispatcher Used for sending messages to texture cache.
- * @param[in] touchResampler Used for re-sampling touch events.
*/
UpdateManager( NotificationManager& notificationManager,
CompleteNotificationInterface& animationFinishedNotifier,
Integration::RenderController& controller,
RenderManager& renderManager,
RenderQueue& renderQueue,
- TextureCacheDispatcher& textureCacheDispatcher,
- TouchResampler& touchResampler );
+ TextureCacheDispatcher& textureCacheDispatcher );
/**
* Destructor.
+++ /dev/null
-#ifndef __DALI_INTERNAL_HISTORY_H__
-#define __DALI_INTERNAL_HISTORY_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.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <limits>
-
-// INTERNAL INCLUDES
-#include <dali/devel-api/common/set-wrapper.h>
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/math/vector2.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-/**
- * HistoryPair
- * represents a key-value element in the HistoryContainer
- */
-template<class T>
-struct HistoryPairType
-{
-public:
-
- HistoryPairType(float firstValue)
- : first(firstValue)
- {
- }
-
- HistoryPairType(float firstValue, T secondValue)
- : first(firstValue),
- second(secondValue)
- {
- }
-
- bool operator<(const HistoryPairType& rhs) const
- {
- return first < rhs.first;
- }
-
- float first;
- T second;
-};
-
-/**
- * History container.
- * This container is used for keeping a list of element pairs while providing an API that can
- * generate interpolated values of requested elements that lie between two stored elements.
- *
- * e.g. stored values:
- *
- * 1.0 - 10
- * 2.0 - 30
- * 3.0 - 50
- *
- * Requesting value at key 1.5 will use the adjacent stored keys (1.0 and 2.0) to return an
- * interpolated value of 20.0 (i.e. 0.5 of the way between 10 and 30).
- *
- * Requesting value at key 2.9 will use the adjacent stored keys (2.0 and 3.0) to return an
- * interpolated value of 48.0 (i.e. 0.9 of the way between 30 and 50)
- */
-class History
-{
- typedef HistoryPairType<Vector2> HistoryPair;
- typedef std::set<HistoryPair> HistoryContainer;
- typedef HistoryContainer::iterator HistoryContainerIter;
-
-public:
-
- /**
- * History constructor
- */
- History()
- : mMaxSize(std::numeric_limits<size_t>::max())
- {
- }
-
- /**
- * History destructor
- */
- ~History()
- {
- }
-
- /**
- * Sets the maximum size of the history container in terms of elements stored, default is no limit
- * @param[in] maxSize The maximum number of elements stored in container
- */
- void SetMaxSize(size_t maxSize)
- {
- mMaxSize = maxSize;
-
- if(mHistory.size() > mMaxSize)
- {
- // determine reduction in history size, and remove these elements
- size_t reduction = mHistory.size() - mMaxSize;
-
- while(reduction--)
- {
- mHistory.erase(mHistory.begin() );
- }
- }
- }
-
- void Clear()
- {
- mHistory.clear();
- }
-
- /**
- * Adds an element (y) to the container at position (x)
- *
- * @param[in] x Key position value to add
- * @param[in] y Value to add at Key.
- */
- void Add(float x, const Vector2& y)
- {
- if(mHistory.size() >= mMaxSize)
- {
- RemoveTail();
- }
-
- mHistory.insert(HistoryPair(x,y));
- }
-
- /**
- * Removes first element in the container
- */
- void RemoveTail()
- {
- mHistory.erase(mHistory.begin());
- }
-
- /**
- * Retrieves value from the history using key (x).
- * If the requested key (x) lies between two points, a linearly interpolated value between the two
- * points is returned.
- *
- * @param[in] x Key position to retrieve
- *
- * @return The interpolated Value is returned for this position.
- */
- Vector2 Get(float x) const
- {
- HistoryContainerIter i = mHistory.lower_bound(x);
-
- if(i == mHistory.end())
- {
- --i;
- }
-
- // For samples based on first point, just return position.
- if(i == mHistory.begin())
- {
- return i->second;
- }
-
- // within begin() ... end() range
- float x2 = i->first;
- Vector2 y2 = i->second;
-
- --i;
- float x1 = i->first;
- Vector2 y1 = i->second;
-
- // For samples based on first 2 points, just use linear interpolation
- // TODO: Should really perform quadratic interpolation whenever there are 3+
- // points.
- if(i == mHistory.begin())
- {
- return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
- }
-
- // For samples based elsewhere, always use quadratic interpolation.
- --i;
- float x0 = i->first;
- Vector2 y0 = i->second;
-
- if(i != mHistory.begin())
- {
- --i;
- float xn = i->first;
- Vector2 yn = i->second;
-
- x2 = (x2 + x1) * 0.5f;
- x1 = (x1 + x0) * 0.5f;
- x0 = (xn + x0) * 0.5f;
-
- y2 = (y2 + y1) * 0.5f;
- y1 = (y1 + y0) * 0.5f;
- y0 = (yn + y0) * 0.5f;
- }
- // Quadratic equation:
-
- // y = ax^2 + bx + c
- // by making touches relative to x0, y0 (i.e. x0 = 0, y0 = 0)
- // we get c = 0, and equation becomes:
- // y = ax^2 + bx
- // 1) Y1 = a . X1^2 + b X1
- // 2) Y2 = a . X2^2 + b X2
- // solving simulatenous equations gets:
-
- // make time (x) & position (y) relative to x0, y0
- y1 -= y0;
- y2 -= y0;
- x1 -= x0;
- x2 -= x0;
-
- x -= x0;
-
- Vector2 a = ( y1 - (y2 * x1) / x2 ) / (x1 * (x1 - x2) );
- Vector2 b = ( y1 / x1 ) - (a * x1);
-
- return a * x * x + b * x + y0;
- }
-
- /**
- * Retrieves a value from the history relative to the head.
- *
- * @note If the Keys (x) in the history decrease in value the further back you go. Then a
- * negative deltaX value should be supplied to refer to these keys relative to the head key.
- *
- * @param[in] deltaX Key position to retrieve relative to head key
- *
- * @return The interpolated Value is returned for this relative position.
- */
- Vector2 GetRelativeToHead(float deltaX) const
- {
- HistoryContainerIter i = mHistory.end();
- --i;
- return Get(i->first + deltaX);
- }
-
- /**
- * Retrieves the head time value.
- *
- * @retrun The head time value.
- */
- float GetHeadTime() const
- {
- HistoryContainerIter i = mHistory.end();
- if(i==mHistory.begin())
- {
- return 0.0f;
- }
- --i;
- return i->first;
- }
-
- /**
- * Retrieves the head value.
- *
- * @return The head value.
- */
- Vector2 GetHead() const
- {
- HistoryContainerIter i = mHistory.end();
- if(i==mHistory.begin())
- {
- return Vector2();
- }
- --i;
- return i->second;
- }
-
-private:
-
- HistoryContainer mHistory; ///< History container
- size_t mMaxSize; ///< Current maximum size of container
-
-};
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_HISTORY_H__
+++ /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/update/touch/touch-resampler.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/update/touch/history.h>
-#include <dali/integration-api/events/touch-data.h>
-#include <dali/integration-api/events/touch-event-integ.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace
-{
-
-static const unsigned int MaxPendingTouches(16u); ///< Queue can keep track of a maximum of 16 events per update refresh.
-
-/**
- * Conversion function. To convert from raw touch data (which is either
- * in a Down, Up or Motion state) to TouchPoint states.
- * @param[in] touch The raw touch data state.
- * @return[out] The TouchPoint state.
- */
-TouchPoint::State GetStateFromTouch( const Dali::Integration::TouchData& touch )
-{
- switch(touch.type)
- {
- case Dali::Integration::TouchData::Down:
- {
- return TouchPoint::Down;
- }
- case Dali::Integration::TouchData::Up:
- {
- return TouchPoint::Up;
- }
- case Dali::Integration::TouchData::Motion:
- {
- return TouchPoint::Motion;
- }
- } // end switch
-
- DALI_ASSERT_ALWAYS(false); // should never reach here as we handle all possible cases in above switch
-
- return TouchPoint::Last;
-}
-
-}
-
-/**
- * TouchTracker keeps track of a single finger's touch movement from touch
- * down to release. While the caller can then inspect the touch position and
- * incidents that occured at a convenient time i.e. update-time.
- * Typically there is 1 to 2 touches that occur between two updates.
- *
- * The application developer is interested in the touch position at a constant
- * time point relative to the visual update (e.g. Always 5ms before the next
- * render) - while touches rarely occur at the same time due to a difference
- * in frequency amongst other timing issues.
- *
- * The application developer also wants to know if Up, Down or Motion events
- * occured. But multiple motion "Motion 1 & Motion 2" events within a frame are
- * wasteful information so they're consolidated into just "Motion 2".
- * "Motion & Up" events within a frame are also wasteful, they're consolidated
- * into just "Up". However "Down & Motion", or "Down & Up" events both need
- * to be propagated to the user.
- *
- * Theoretically a double tap, given sufficient slow down of the update thread
- * could also be propagated to the user with this system as "Down 1, Up 1, Down 2, Up 2"
- */
-class TouchTracker
-{
-
-public:
-
- /**
- * Construct a TouchTracker based on an inital touch.
- * This initial touch should be a Down press.
- * @param[in] data The initial TouchData to populate this with.
- */
- TouchTracker(Dali::Integration::TouchData& data)
- : mActive(true),
- mIndex(data.index),
- mPreviousType(data.type),
- mStartTimestamp(data.timestamp)
- {
- mTouchHistory.SetMaxSize(5);
- mIncidents.push_back(data);
-
- mTouchHistory.Add(0.0f, Vector2(data.x, data.y));
- }
-
- /**
- * Call SendTouchData to send this object some touch data.
- * @param[in] data The data to send
- */
- void SendTouchData(Dali::Integration::TouchData& data)
- {
- mTouchHistory.Add(data.timestamp - mStartTimestamp, Vector2(data.x, data.y));
-
- if(!mIncidents.size() || mPreviousType != data.type)
- {
- mIncidents.push_back(data);
- mPreviousType = data.type;
- }
- else // If there are multiple touches on this frame, and previous is the same, then overwrite previous.
- {
- mIncidents[mIncidents.size()-1] = data;
- }
- }
-
- /**
- * Query the this object's touch position at a given timestamp
- * @param[in] timestamp The point in time where the touch is wished
- * to be known (using same timestamp scale as that provided in the
- * TouchData)
- * @return The interpolated touch position is returned.
- */
- Vector2 GetTouchPosition(unsigned int timestamp) const
- {
- float time( timestamp - mStartTimestamp );
- Vector2 position = mTouchHistory.Get(time);
- return position;
- }
-
- bool mActive;
- unsigned int mIndex;
- Dali::Integration::TouchDataContainer mIncidents; ///< All of the touches from down to up for this
- Dali::Integration::TouchData::TouchType mPreviousType;
- History mTouchHistory; ///< Keep track of recent touches
- unsigned int mStartTimestamp; ///< Timestamp of the first touch. Touch history has time relative to first touch.
-};
-
-typedef std::vector<TouchTracker> TouchTrackerContainer;
-typedef TouchTrackerContainer::iterator TouchTrackerIter;
-typedef TouchTrackerContainer::const_iterator TouchTrackerConstIter;
-
-/**
- * TouchPointsTracker keeps track of all the touch points,
- * receives touch data and sends to an individual TouchTracker
- * to handle. It also generates TouchEvents based on all
- * the TouchTrackers' event data.
- */
-class TouchPointsTracker
-{
-public:
-
- /**
- * Call SendTouchData to send this tracker some touch data.
- * @param[in] data The data to send
- */
- void SendTouchData( Dali::Integration::TouchData& data );
-
- /**
- * Query the number of touch events that can be generated from calling GetNextTouchEvent
- * @return The number of touch events available.
- */
- unsigned int GetTouchEventCount() const;
-
- /**
- * Populate touchEvent with the next TouchEvent.
- * The touch event position information is interpolated to produce a touch event that
- * reflects the time provided (nextRenderTime)
- *
- * @note Call GetTouchEventCount() prior to calling this to know whether there are any
- * TouchEvents available.
- *
- * @param[in] touchEvent The touch event to be populated with touch event info.
- * @param[in] referenceTimestamp The timestamp required to assist touch smoothing.
- */
- bool GetNextTouchEvent( Dali::Integration::TouchEvent& touchEvent, unsigned int referenceTimestamp );
-
-private:
-
- TouchTrackerContainer mTouches; ///< A container for each individual touch.
-
-};
-
-void TouchPointsTracker::SendTouchData( Dali::Integration::TouchData& data )
-{
- // Check if we have a record of this touch index.
- TouchTrackerIter i = mTouches.begin();
- TouchTrackerIter endIter = mTouches.end();
- for(;i != endIter; ++i )
- {
- if(i->mIndex == data.index)
- {
- i->SendTouchData(data);
- return;
- }
- }
-
- // If no record exists, then create a new record for this touch index.
- mTouches.push_back( TouchTracker(data) );
-}
-
-unsigned int TouchPointsTracker::GetTouchEventCount() const
-{
- TouchTrackerConstIter i = mTouches.begin();
- TouchTrackerConstIter endIter = mTouches.end();
- size_t maxTouches(0u);
- for(;i != endIter; ++i )
- {
- // check if touch has incident(s), get max number of incidents on any touch.
- maxTouches = std::max(maxTouches, i->mIncidents.size());
- }
-
- return maxTouches;
-}
-
-bool TouchPointsTracker::GetNextTouchEvent( Dali::Integration::TouchEvent& touchEvent, unsigned int referenceTimestamp )
-{
- bool hasTouchEvent( GetTouchEventCount() > 0 );
-
- if( hasTouchEvent )
- {
- TouchTrackerIter i = mTouches.begin();
- TouchTrackerIter endIter = mTouches.end();
- unsigned int maxTimestamp = 0u;
-
- for(;i != endIter; ++i )
- {
- // check if touch has an incident, if so then take oldest incident off.
- if(i->mIncidents.size())
- {
- const Dali::Integration::TouchData& touchData(*i->mIncidents.begin());
-
- if(touchData.type == Dali::Integration::TouchData::Motion)
- {
- // For Motion, use a smoothed position.
- Vector2 smoothPosition = i->GetTouchPosition(referenceTimestamp);
-
- touchEvent.AddPoint( TouchPoint(i->mIndex, TouchPoint::Motion, smoothPosition.x, smoothPosition.y ) );
- maxTimestamp = std::max(maxTimestamp, touchData.timestamp);
- }
- else
- {
- // For Up/Down, use a actual touch position.
- touchEvent.AddPoint( TouchPoint(i->mIndex, GetStateFromTouch(touchData), touchData.x, touchData.y ) );
- maxTimestamp = std::max(maxTimestamp, touchData.timestamp);
- }
-
- i->mIncidents.erase(i->mIncidents.begin());
- i->mActive = touchData.type != Dali::Integration::TouchData::Up;
- }
- else
- {
- Vector2 smoothPosition = i->GetTouchPosition(referenceTimestamp);
-
- // Stationary (TODO: final position should gravitate to real last touch position)
- touchEvent.AddPoint( TouchPoint(i->mIndex, TouchPoint::Stationary, smoothPosition.x, smoothPosition.y ) );
- }
- }
-
- touchEvent.time = maxTimestamp;
-
- // clean up list. TODO: change to pointers.
- TouchTrackerContainer touchesCleaned;
- for(i = mTouches.begin();i != endIter; ++i )
- {
- if(i->mIncidents.size() || i->mActive)
- {
- touchesCleaned.push_back(*i);
- }
- }
- mTouches = touchesCleaned;
- }
-
- return hasTouchEvent;
-}
-
-TouchResampler* TouchResampler::New()
-{
- return new TouchResampler();
-}
-
-TouchResampler::~TouchResampler()
-{
- delete[] mTouchesQueue;
- delete mTouchPointsTracker;
-}
-
-void TouchResampler::SendTouchData( const Dali::Integration::TouchData& touch )
-{
- mTouchesQueue[mTouchesWrite] = touch;
- mTouchesWrite = (mTouchesWrite + 1) % MaxPendingTouches;
- // TODO: Should only do this if it has been concluded that the down touch hits an Actor listening for touch.
- // I think needs to send a down touch to Event thread to evaluate hit-test, and if valid, then enable update Required.
-
- mUpdateRequired = true;
-}
-
-void TouchResampler::Update()
-{
- while(mTouchesRead != mTouchesWrite)
- {
- mTouchPointsTracker->SendTouchData( mTouchesQueue[mTouchesRead] );
-
- mTouchesRead = (mTouchesRead + 1) % MaxPendingTouches;
- }
-}
-
-bool TouchResampler::GetNextTouchEvent( Dali::Integration::TouchEvent& touchEvent, unsigned int time )
-{
- touchEvent.points.clear();
- touchEvent.time = 0u;
-
- return mTouchPointsTracker->GetNextTouchEvent( touchEvent, time );
-}
-
-bool TouchResampler::NeedsUpdate()
-{
- bool updateRequired(mUpdateRequired);
-
- mUpdateRequired = false;
-
- return updateRequired;
-}
-
-TouchResampler::TouchResampler()
-: mUpdateRequired(false),
- mTouchesQueue(new Dali::Integration::TouchData[MaxPendingTouches]),
- mTouchesRead(0u),
- mTouchesWrite(0u),
- mTouchPointsTracker(new TouchPointsTracker())
-{
-}
-
-} // namespace Internal
-
-} // namespace Dali
-
+++ /dev/null
-#ifndef __DALI_INTERNAL_TOUCH_RESAMPLER_H__
-#define __DALI_INTERNAL_TOUCH_RESAMPLER_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.
- *
- */
-
-namespace Dali
-{
-
-namespace Integration
-{
-
-struct TouchData;
-struct TouchEvent;
-
-} // namespace Integration
-
-namespace Internal
-{
-
-class TouchPointsTracker;
-
-/**
- * The TouchResampler is responsible for receiving and regulating raw input touches, generating
- * TouchEvents at a regulated frequency suitable for the update/render cycle.
- *
- * Usage:
- *
- * // Touch Thread...
- * OnTouchEvent(const Dali::Integration::TouchData& rawTouchData)
- * {
- * mResampler.SendTouchData( rawTouchData );
- * }
- *
- * // Update Thread...
- * OnUpdate(unsigned int timestamp)
- * {
- * mResampler.Update();
- *
- * while(mResampler.GetNextTouchEvent( touchEvent, timestamp ))
- * {
- * // send resampled touchEvent on to Application Thread.
- * }
- * }
- *
- *
- * Feed touch Events in at any frequency, and new touch Events will come out at the desired
- * frequency of the caller.
- */
-class TouchResampler
-{
-public:
-
- /**
- * Create a touch Resampler
- */
- static TouchResampler* New();
-
- /**
- * Virtual destructor
- */
- virtual ~TouchResampler();
-
- /**
- * Whenever there is new raw touch data it should be sent into the touch-resampler.
- * This will queue the data, and it will be processed on every update
- * (at the video refresh frequency e.g. 60Hz)
- * @param[in] touch The latest touch data
- */
- void SendTouchData( const Dali::Integration::TouchData& touch );
-
- /**
- * Update should be called on every update frame (i.e. at video refresh frequency)
- * This will identify all the touch incidents that occured since the past call.
- */
- void Update();
-
- /**
- * Calling GetNextTouchEvent after an Update will retrieve each TouchEvent that
- * was generated by Update.
- * @param[in] touchEvent Reference to a TouchEvent structure to be populated with
- * a single TouchEvent.
- * @param[in] time The time of interest in touch space-time that the caller
- * is interested in.
- */
- bool GetNextTouchEvent( Dali::Integration::TouchEvent& touchEvent, unsigned int time );
-
- /**
- * Returns whether an update is required
- * @note this changes the internal mUpdateRequired flag to false upon calling.
- */
- bool NeedsUpdate();
-
-private:
-
- /**
- * Protected constructor.
- */
- TouchResampler();
-
- // Undefined
- TouchResampler(const TouchResampler&);
-
- // Undefined
- TouchResampler& operator=(const TouchResampler&);
-
-private:
-
- bool mUpdateRequired;
- Dali::Integration::TouchData* mTouchesQueue; ///< Circular buffer.
- volatile unsigned int mTouchesRead; ///< Circular buffer read offset.
- volatile unsigned int mTouchesWrite; ///< Circular buffer write offset.
- TouchPointsTracker* mTouchPointsTracker;
-
-};
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_TOUCH_RESAMPLER_H__