--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/radioapp/radiouiengine/src/radiotimerpool.cpp Fri Oct 15 16:26:27 2010 +0300
@@ -0,0 +1,196 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+// System includes
+#include <QTimer>
+#include <QMetaMethod>
+
+// User includes
+#include "radiotimerpool.h"
+#include "radiologger.h"
+
+const int TIMER_BUFFER_SIZE = 2;
+
+/*!
+ *
+ */
+RadioTimerPool::RadioTimerItem::RadioTimerItem( RadioTimerPool* parent ) :
+ mTimer( new QTimer() )
+{
+ Radio::connect( mTimer.data(), SIGNAL(timeout()),
+ parent, SLOT(timerFired()) );
+ mTimer->setSingleShot( true );
+}
+
+/*!
+ *
+ */
+RadioTimerPool::RadioTimerItem::~RadioTimerItem()
+{
+}
+
+/*!
+ *
+ */
+void RadioTimerPool::RadioTimerItem::reset()
+{
+ mTimer->stop();
+ mId = -1;
+ mParam = QVariant();
+ mReceiver = NULL;
+ mReceiverMember.clear();
+}
+
+/*!
+ *
+ */
+RadioTimerPool::RadioTimerPool( QObject* parent ) :
+ QObject( parent )
+{
+ createItem();
+}
+
+/*!
+ *
+ */
+RadioTimerPool::~RadioTimerPool()
+{
+ qDeleteAll( mTimerMap.values() );
+}
+
+/*!
+ *
+ */
+void RadioTimerPool::startTimer( int msec, int id, QObject* receiver, const char* member, QVariant param )
+{
+ LOG_METHOD;
+ RadioTimerItem* availableItem = NULL;
+ foreach ( RadioTimerItem* item, mTimerMap.values() ) {
+ if ( !item->mTimer->isActive() ) {
+ availableItem = item;
+ } else {
+ if ( item->mReceiver == receiver && item->mId == id ) {
+ LOG_FORMAT( "RadioTimerPool::startTimer. Timer %d already running for class %s", id, receiver->metaObject()->className() );
+ }
+ }
+ }
+
+ if ( !availableItem ) {
+ availableItem = createItem();
+ LOG( "RadioTimerPool::startTimer. Creating new timer" );
+ }
+ LOG_FORMAT( "Amount of timers: %d", mTimerMap.count() );
+
+ availableItem->mId = id;
+ availableItem->mParam = param;
+ availableItem->mReceiver = receiver;
+
+ // SIGNAL() and SLOT() macros add a number in the beginning of member function name for some internal housekeeping
+ // That causes the method to not be found from the meta object so we need to trim it off
+ availableItem->mReceiverMember = member;
+ availableItem->mReceiverMember = availableItem->mReceiverMember.right( availableItem->mReceiverMember.length() - 1 );
+
+ availableItem->mTimer->start( msec );
+}
+
+/*!
+ *
+ */
+void RadioTimerPool::cancelTimer( int id, const QObject* receiver )
+{
+ foreach ( RadioTimerItem* item, mTimerMap.values() ) {
+ if ( item->mId == id && item->mReceiver == receiver ) {
+ item->reset();
+ break;
+ }
+ }
+ freeUnusedTimers();
+}
+
+/*!
+ *
+ */
+bool RadioTimerPool::isTimerActive( int id, const QObject* receiver ) const
+{
+ foreach ( const RadioTimerItem* item, mTimerMap.values() ) {
+ if ( item->mId == id &&
+ item->mReceiver == receiver &&
+ item->mTimer->isActive() ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ *
+ */
+void RadioTimerPool::freeUnusedTimers()
+{
+ QList<RadioTimerItem*> unusedItems;
+ foreach ( RadioTimerItem* item, mTimerMap.values() ) {
+ if ( !item->mTimer->isActive() ) {
+ unusedItems.append( item );
+ }
+ }
+
+ if ( unusedItems.count() > TIMER_BUFFER_SIZE ) {
+ foreach( const RadioTimerItem* item, unusedItems ) {
+ mTimerMap.remove( item->mTimer.data() );
+ delete item;
+ }
+ }
+}
+
+/*!
+ * Private slot
+ */
+void RadioTimerPool::timerFired()
+{
+ QTimer* timer = static_cast<QTimer*>( sender() );
+ if ( mTimerMap.contains( timer ) ) {
+ RadioTimerItem* item = mTimerMap.value( timer );
+ if ( item->mReceiver ) {
+ QByteArray normalizedSignature = QMetaObject::normalizedSignature( item->mReceiverMember.toAscii().constData() );
+ int methodIndex = item->mReceiver->metaObject()->indexOfMethod( normalizedSignature );
+ if ( methodIndex != -1 ) {
+ QMetaMethod method = item->mReceiver->metaObject()->method( methodIndex );
+ const int paramCount = method.parameterTypes().count();
+ if ( paramCount == 0 ) {
+ method.invoke( item->mReceiver, Qt::QueuedConnection );
+ } else if ( paramCount == 1 ) {
+ method.invoke( item->mReceiver, Qt::QueuedConnection, Q_ARG( int, item->mId ) );
+ } else if ( paramCount == 2 ) {
+ method.invoke( item->mReceiver, Qt::QueuedConnection,
+ Q_ARG( int, item->mId ), Q_ARG( QVariant, item->mParam ) );
+ }
+ }
+
+ item->reset();
+ }
+ }
+}
+
+/*!
+ *
+ */
+RadioTimerPool::RadioTimerItem* RadioTimerPool::createItem()
+{
+ RadioTimerItem* item = new RadioTimerItem( this );
+ mTimerMap.insert( item->mTimer.data(), item );
+ return item;
+}