--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hwrmhaptics/hapticsclient/src/hwrmhapticsivtdatacache.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,377 @@
+/*
+* Copyright (c) 2008 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: Implementation of haptics client's IVT-data cache.
+*
+*/
+
+
+#include "hwrmhapticsivtdatacache.h"
+
+// ---------------------------------------------------------------------------
+// Two-phase constructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsIVTDataCache* CHWRMHapticsIVTDataCache::NewL()
+ {
+ CHWRMHapticsIVTDataCache* self = CHWRMHapticsIVTDataCache::NewLC();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Two-phase asynchronous constructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsIVTDataCache* CHWRMHapticsIVTDataCache::NewLC()
+ {
+ CHWRMHapticsIVTDataCache* self = new ( ELeave ) CHWRMHapticsIVTDataCache();
+ CleanupStack::PushL( self );
+
+ self->ConstructL();
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsIVTDataCache::~CHWRMHapticsIVTDataCache()
+ {
+ Reset();
+ if ( iIdle )
+ {
+ iIdle->Cancel();
+ delete iIdle;
+ }
+ iCache.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// Adds a new IVT-data item to the cache.
+// ---------------------------------------------------------------------------
+//
+TInt CHWRMHapticsIVTDataCache::AddCacheItem( const TDesC8& aIVTData,
+ TInt& aFileHandle )
+ {
+ TInt err = KErrNoMemory;
+
+ TCacheItem newItem;
+ newItem.iIVTData = aIVTData.Alloc();
+ newItem.iClientFileHandle = ++iInternalHandle;
+ newItem.iDeletionRequested = EFalse;
+ newItem.iLoadObserver = NULL;
+
+ aFileHandle = iInternalHandle;
+
+ if ( newItem.iIVTData )
+ {
+ err = iCache.Append( newItem );
+ }
+
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Adds a new IVT-data item to the cache. This overload is meant for
+// asynch calls.
+// ---------------------------------------------------------------------------
+//
+TBool CHWRMHapticsIVTDataCache::UpdateCacheItemListener(
+ TInt aFileHandle,
+ TRequestStatus& aClientStatus,
+ RHWRMHapticsSession* aClientSession,
+ const TIpcArgs& aArgs )
+ {
+ TBool retVal( EFalse );
+ TInt itemIndex = FindItem( aFileHandle );
+
+ if ( itemIndex >= 0 )
+ {
+ // New load observer listener is only instantiated if there isn't
+ // already a listener for the cache item. Note that if there already
+ // were one, this method will return EFalse, and the actual asynch
+ // call will be made with the original client's status in Impl class.
+ if ( !iCache[itemIndex].iLoadObserver )
+ {
+ // If the below leaves this method will return EFalse,
+ // and the actual asynch call will be made with the original
+ // client's status.
+ TRAPD(err,
+ iCache[itemIndex].iLoadObserver =
+ CHWRMHapticsIVTDataCacheAO::NewL( aFileHandle,
+ this,
+ aClientStatus ) );
+ if ( !err )
+ {
+ iCache[itemIndex].iLoadObserver->PlayEffectAsynch
+ ( aClientSession, aArgs );
+ retVal = ETrue;
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Removes a cache item identified by the given filehandle.
+// ---------------------------------------------------------------------------
+//
+TInt CHWRMHapticsIVTDataCache::RemoveCacheItem( TInt aFileHandle )
+ {
+ TInt err = KErrNotFound;
+
+ // search for the item in the cache
+ TInt itemIndex = FindItem( aFileHandle );
+
+ if ( itemIndex >= 0 )
+ {
+ // item was found, either mark it for deletion (if there's active
+ // load observer active object waiting for response for previous
+ // play with data request) or otherwise delete and remove it.
+ if ( iCache[itemIndex].iLoadObserver &&
+ iCache[itemIndex].iLoadObserver->IsActive() )
+ {
+ iCache[itemIndex].iDeletionRequested = ETrue;
+ }
+ else
+ {
+ delete iCache[itemIndex].iIVTData;
+ iCache[itemIndex].iIVTData = NULL;
+ delete iCache[itemIndex].iLoadObserver;
+ iCache[itemIndex].iLoadObserver = NULL;
+ iCache.Remove( itemIndex );
+
+ err = KErrNone;
+
+ // update loaded item index, if needed
+ if ( iLoadedItem == itemIndex )
+ {
+ iLoadedItem = KErrNotFound;
+ }
+ else if ( iLoadedItem > itemIndex )
+ {
+ --iLoadedItem;
+ }
+ }
+ }
+
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Removes all items from the cache.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsIVTDataCache::Reset()
+ {
+ // delete and remove all items
+ while ( iCache.Count() )
+ {
+ delete iCache[0].iIVTData;
+ iCache[0].iIVTData = NULL;
+ delete iCache[0].iLoadObserver;
+ iCache[0].iLoadObserver = NULL;
+ iCache.Remove( 0 );
+ }
+
+ iLoadedItem = KErrNotFound;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns a pointer to the IVT-data buffer, which corresponds to
+// the given filehandle.
+// ---------------------------------------------------------------------------
+//
+const HBufC8* CHWRMHapticsIVTDataCache::IVTData( TInt aFileHandle ) const
+ {
+ HBufC8* ivtData = NULL;
+
+ // search for the item in the cache
+ TInt itemIndex = FindItem( aFileHandle );
+ if ( itemIndex >= 0 )
+ {
+ ivtData = iCache[itemIndex].iIVTData;
+ }
+
+ return ivtData;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns whether or not the IVT-data of the given filehandle
+// is currently loaded into the haptics system.
+// ---------------------------------------------------------------------------
+//
+TBool CHWRMHapticsIVTDataCache::IsLoaded( TInt aFileHandle ) const
+ {
+ TInt ret = EFalse;
+ TInt index = FindItem( aFileHandle );
+
+ // if index was found and the index is the loaded item's index,
+ // this data is already loaded
+ if ( index >= 0 && index == iLoadedItem )
+ {
+ ret = ETrue;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// Updates server side file handle
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsIVTDataCache::UpdateCacheItem( TInt aClientFileHandle,
+ TBool aSetLoaded )
+ {
+ // find the item from cache with the given filehandle
+ TInt itemIndex = FindItem( aClientFileHandle );
+ if ( itemIndex >= 0 )
+ {
+ if ( aSetLoaded && !iCache[itemIndex].iDeletionRequested )
+ {
+ iLoadedItem = itemIndex;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Returns client side file handle
+// ---------------------------------------------------------------------------
+//
+TInt CHWRMHapticsIVTDataCache::ClientFileHandle( const TDesC8& aIVTData )
+ {
+ // find the item from cache with the given filehandle
+ TInt clientFileHandle( KErrNotFound );
+ TInt count( iCache.Count() );
+ for ( TInt i( 0 ); i < count && KErrNotFound == clientFileHandle; ++i )
+ {
+ TPtr8 cachedData = iCache[i].iIVTData->Des();
+ if ( cachedData == aIVTData )
+ {
+ clientFileHandle = iCache[i].iClientFileHandle;
+ }
+ }
+
+ return clientFileHandle;
+ }
+
+// ---------------------------------------------------------------------------
+// Method for starting the idle object that then calls garbage collection
+// callback.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsIVTDataCache::RequestGarbageCollection()
+ {
+ if ( iIdle && !iIdle->IsActive() )
+ {
+ iIdle->Start( TCallBack ( CollectGarbageIdle, this ) );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Garbage collection static callback.
+// ---------------------------------------------------------------------------
+//
+TInt CHWRMHapticsIVTDataCache::CollectGarbageIdle( TAny* aObjectPtr )
+ {
+ CHWRMHapticsIVTDataCache* self =
+ reinterpret_cast<CHWRMHapticsIVTDataCache*>( aObjectPtr );
+ if ( self )
+ {
+ self->CollectGarbage();
+ }
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Garbage collection actual (object specific) callback. Cleans obsolete
+// load observers and whole TCacheItems if needed.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsIVTDataCache::CollectGarbage()
+ {
+ for ( TInt i = iCache.Count() - 1; i >= 0; --i )
+ {
+ // This garbage collection is only interested in those entries for
+ // which there has been load observer running, i.e., for which the
+ // iLoadObserver is non-NULL, and for which the running has stopped,
+ // i.e., the iLoadObserver.IsActive() check returns EFalse
+ if ( iCache[i].iLoadObserver && !iCache[i].iLoadObserver->IsActive() )
+ {
+ delete iCache[i].iLoadObserver;
+ iCache[i].iLoadObserver = NULL;
+ // If the entry was also marked for deletion, delete the whole
+ // entry from TCacheItem array
+ if ( iCache[i].iDeletionRequested )
+ {
+ delete iCache[i].iIVTData;
+ iCache[i].iIVTData = NULL;
+ iCache.Remove( i );
+
+ // update loaded item index, if needed
+ if ( iLoadedItem == i )
+ {
+ iLoadedItem = KErrNotFound;
+ }
+ else if ( iLoadedItem > i )
+ {
+ --iLoadedItem;
+ }
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// C++ constructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsIVTDataCache::CHWRMHapticsIVTDataCache()
+ : iLoadedItem( KErrNotFound )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Second phase construction.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsIVTDataCache::ConstructL()
+ {
+ iIdle = CIdle::NewL( CActive::EPriorityIdle );
+ }
+
+// ---------------------------------------------------------------------------
+// Searches the cache for an item with the given filehandle.
+// ---------------------------------------------------------------------------
+//
+TInt CHWRMHapticsIVTDataCache::FindItem( TInt aClientFileHandle ) const
+ {
+ TInt index = KErrNotFound;
+
+ // find the item from cache with the given filehandle
+ for ( TInt i = 0; i < iCache.Count() && index == KErrNotFound; ++i )
+ {
+ if ( iCache[i].iClientFileHandle == aClientFileHandle )
+ {
+ index = i;
+ }
+ }
+
+ return index;
+ }
+
+// End of File