uiacceltk/hitchcock/coretoolkit/src/HuiFxEffectCache.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiFxEffectCache.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,409 @@
+/*
+* 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:   
+*
+*/
+
+#include "HuiFxEffectCache.h"
+#include "HuiFxEffectParser.h"
+#include "HuiFxEffect.h"
+#include "uiacceltk/HuiVisual.h" 
+#include "uiacceltk/HuiPanic.h"
+#include "HuiFxConstants.h"
+
+CHuiFxEffectCache *CHuiFxEffectCache::NewL()
+{
+	return new (ELeave)CHuiFxEffectCache;
+}
+
+CHuiFxEffectCache::~CHuiFxEffectCache()
+   {
+   iCachedEffects.ResetAndDestroy();
+#if 0
+   THashMapIter<TInt, MHuiFxEffectCacheNode*> iter(iDuplicateEffects);
+   MHuiFxEffectCacheNode * const *node;
+   do
+       {
+       node =  iter.NextValue();
+       if (node)
+           {
+           delete *node;
+           }
+       }
+   while(node);
+#endif
+   TInt size = iDuplicateEffects.Count();
+   for(TInt i=0;i<size;i++)
+       {
+       const IDNode &node = iDuplicateEffects[i];
+       delete node.iNode;
+       }
+
+   iCachedEffects.Close();
+   iDuplicateEffects.Close();   
+   }
+
+TInt CHuiFxEffectCache::UniqueId()
+    {
+    iUniqueId++;
+    return iUniqueId;
+    }
+
+void CHuiFxEffectCache::CreateL(MHuiFxEffectCacheNode *aNode)
+    { // registration of fxml file
+    MHuiFxEffectCacheNode *cachedNode = Find(aNode);
+    if (cachedNode)
+       { // found in cache => duplicate registration => no need to do anything
+       cachedNode->Ref(1);
+       delete aNode;
+       }
+    else
+       { // not found in cache, so insert it and start parsing the effect.
+       TInt id = UniqueId();
+       IDNode n = { id, aNode };
+       iDuplicateEffects.Append(n);
+
+       TRAPD(err, aNode->HeavyOperationL(this, id)); // from empty to this instance
+       if (err != KErrNone)
+           {
+           iDuplicateEffects.Remove(iDuplicateEffects.Count()-1);
+           User::Leave(err);
+           }
+       }
+    }
+
+EXPORT_C void CHuiFxEffectCache::FindOrCreateL(MHuiFxEffectCacheNode *aNode)
+   { // using fxml file
+   MHuiFxEffectCacheNode *cachedNode = Find(aNode);
+
+   if (cachedNode)
+	  { // found in cache
+	  aNode->LightOperationL(cachedNode); // from cache to this instance  
+	  delete aNode;
+	  }
+   else
+	  { // not found in cache, so start parsing the effect.
+
+	  // TODO: What happens if we did not find it from cache, but it exists in iDuplicateEffects?
+	  //       Current behaviour is that it starts to load it again, causing duplicate entries in the cache.
+	  TInt id = UniqueId();
+      IDNode n = { id, aNode };
+      iDuplicateEffects.Append(n);
+      //iDuplicateEffects.InsertL(id, aNode);
+
+	  TRAPD(err, aNode->HeavyOperationL(this, id)); // from empty to this instance
+	  if (err != KErrNone)
+	      {
+	      iDuplicateEffects.Remove(iDuplicateEffects.Count()-1);
+	      User::Leave(err);
+	      }
+	  }
+  }
+
+void CHuiFxEffectCache::UnUse(MHuiFxEffectCacheNode *aNode)
+   { // unregisteration of fxml file
+   MHuiFxEffectCacheNode *cachedNode = Find(aNode);
+   if (cachedNode)
+       {
+       TInt count = cachedNode->Ref(-1);
+       if (count == 0)
+           {
+           delete cachedNode;
+           Remove(iCachedEffects, cachedNode);
+           }
+       }
+   if (cachedNode != aNode)
+       { // this node was not found in iCachedEffects array, so it needs to be in iDuplicateEffects array
+       delete aNode;
+       Remove(iDuplicateEffects, aNode);
+       }
+   }
+
+void CHuiFxEffectCache::ParsingEnded(TInt aHandle)
+    {
+    //MHuiFxEffectCacheNode **node2 = iDuplicateEffects.Find(aHandle);
+    TInt index = FindById(aHandle);
+    if (index == -1) return;
+    MHuiFxEffectCacheNode *node = iDuplicateEffects[index].iNode;
+    node->ParsingEndedBefore();
+    iCachedEffects.AppendL(node); // takes ownership
+    iDuplicateEffects.Remove(index);
+    node->Ref(1);
+    node->ParsingEndedAfter(node);
+    }
+
+bool CHuiFxEffectCache::Compare(MHuiFxEffectCacheNode *aNode1, MHuiFxEffectCacheNode *aNode2)
+   {
+   return aNode1->Id().Compare(aNode2->Id()) == 0;
+   }
+
+MHuiFxEffectCacheNode *CHuiFxEffectCache::Find(MHuiFxEffectCacheNode *aNode)
+   {
+   TInt size = iCachedEffects.Count();
+   for(TInt i=0;i<size;i++)
+	{
+	MHuiFxEffectCacheNode *node = iCachedEffects[i];
+	if (Compare(node, aNode))
+		{
+		return node;
+		}
+	}
+   return 0;
+   }
+
+TInt CHuiFxEffectCache::FindById(TInt aId)
+    {
+    TInt size = iDuplicateEffects.Count();
+    for(TInt i=0;i<size;i++)
+        {
+        const IDNode &node = iDuplicateEffects[i];
+        if (node.iId == aId)
+            {
+            return i;
+            }
+        }
+    return -1;
+    }
+
+
+MHuiFxEffectCacheNode *CHuiFxEffectCache::FindDup(const TDesC &aId)
+    {
+    TInt size = iDuplicateEffects.Count();
+    for(TInt i=0;i<size;i++)
+        {
+        const IDNode &node = iDuplicateEffects[i];
+        if (node.iNode->Id() == aId)
+            {
+            return node.iNode;
+            }
+        }
+    
+#if 0
+    THashMapIter<TInt, MHuiFxEffectCacheNode*> iter(iDuplicateEffects);
+    MHuiFxEffectCacheNode * const * node = 0;
+    do
+        {
+        node = iter.NextValue();
+        if (node && (*node)->Id()==aId)
+            {
+            return *node;
+            }
+        }
+    while(node);
+#endif
+    
+   TInt size2 = iCachedEffects.Count();
+   for(TInt i=0;i<size2;i++)
+	   {
+	   MHuiFxEffectCacheNode *node = iCachedEffects[i];
+	   if (node->Id()==aId)
+		  {
+		  return node;
+		  }
+	   }
+    return 0;
+    }
+MHuiFxEffectCacheNode *CHuiFxEffectCache::FindCached(const TDesC &aId)
+    {
+    TInt size2 = iCachedEffects.Count();
+    for(TInt i=0;i<size2;i++)
+        {
+        MHuiFxEffectCacheNode *node = iCachedEffects[i];
+        if (node->Id()==aId)
+           {
+           return node;
+           }
+        }
+     return 0;    
+    }
+
+TBool CHuiFxEffectCache::FxmlUsesInput1(const TDesC &aFileName)
+    {
+    MHuiFxEffectCacheNode *node = FindCached(aFileName);
+    if (node)
+        return node->FxmlUsesInput1();
+    else
+        return EFalse;
+    }
+
+
+void CHuiFxEffectCache::Remove(RHashMap<TInt, MHuiFxEffectCacheNode*> & /*aMap*/, MHuiFxEffectCacheNode * /*aNode*/)
+    {
+#if 0
+    THashMapIter<TInt, MHuiFxEffectCacheNode*> iter(aMap);
+    MHuiFxEffectCacheNode * const *node = 0;
+    do
+        {
+        node = iter.NextValue();
+        if (!node)
+            break;
+	    MHuiFxEffectCacheNode *n = *node;
+        if (n == aNode)
+            {
+            const TInt *key = iter.CurrentKey();
+            aMap.Remove(*key);
+            return;
+            }
+        }
+    while(node);
+#endif
+    }
+
+void CHuiFxEffectCache::Remove(RPointerArray<MHuiFxEffectCacheNode> &aEffects, MHuiFxEffectCacheNode *aNode)
+    {
+    TInt size = aEffects.Count();
+    for(TInt i=0;i<size;i++)
+        {
+        MHuiFxEffectCacheNode *node = aEffects[i];
+        if (node == aNode)
+            {
+            aEffects.Remove(i);
+            return;
+            }
+        }
+    }
+
+void CHuiFxEffectCache::Remove(RArray<IDNode> &aMap, MHuiFxEffectCacheNode *aNode)
+    {
+    TInt size = aMap.Count();
+    for(TInt i=0;i<size;i++)
+        {
+        const IDNode &n = aMap[i];
+        if (n.iNode == aNode)
+            {
+            aMap.Remove(i);
+            return;
+            }
+        }
+    }
+
+
+CHuiFxEffectCacheEffectNode::~CHuiFxEffectCacheEffectNode()
+    {
+    delete iFileName;
+    delete iParser;
+    }
+
+TPtrC CHuiFxEffectCacheEffectNode::Id()
+   {
+   return TPtrC(*iFileName);
+   }
+
+TInt CHuiFxEffectCacheEffectNode::Ref(TInt aCount)
+    {
+    iRefCount += aCount;
+    return iRefCount;
+    }
+
+MHuiFxEffectCacheNode *CHuiFxEffectCacheEffectNode::CloneL()
+   {
+   CHuiFxEffect *effect = iEffect->CloneL();
+   return new CHuiFxEffectCacheEffectNode(*iFileName, effect);
+   }
+
+void CHuiFxEffectCacheEffectNode::HeavyOperationL(MHuiFxParsingEndedObserver *aObserver, TInt aIndex)
+	{
+	TRect extRect = TRect();
+    if ( iExtRect )
+       	{
+       	extRect = *iExtRect;
+       	}
+    iParser = CHuiFxEffectParser::NewL( *iEngine, iVisual );
+    iParser->SetEffectEndObserver( iEffectEndObserver, iHandle );
+    iParser->SetEffectFlags( iFlags );
+    iParser->SetParsingEndedObserver(aObserver, aIndex);
+    iParser->ParseL( *iFileName, extRect );
+    if (iVisual)
+        {
+        iVisual->SetLoadingEffect(ETrue);
+        }
+	}
+
+void CHuiFxEffectCacheEffectNode::LightOperationL(MHuiFxEffectCacheNode *aCached)
+	{
+	CHuiFxEffectCacheEffectNode *cachednode = (CHuiFxEffectCacheEffectNode*)aCached;
+	TRect extRect = TRect();
+	if ( iExtRect )
+		{
+		extRect = *iExtRect;
+		}
+	iEffectCached = cachednode->iEffect;
+	iEffect = iEffectCached->CloneL();	
+	iEffect->SetEffectEndObserver(iEffectEndObserver, iHandle);
+	iEffect->SetEffectFlags(iFlags);
+	iEffect->SetEffectGroup(iGroup);
+	iEffect->SetExtRect( &extRect );
+	iEffect->SetVisual( iVisual );
+	iEffect->SetEngine( iEngine );
+	if (iVisual)
+	    iVisual->EffectSetEffect( iEffect );
+	}
+
+void CHuiFxEffectCacheEffectNode::ParsingEndedBefore()
+    {
+    iParser->Effect( iEffect );
+    }
+
+void CHuiFxEffectCacheEffectNode::ParsingEndedAfter(MHuiFxEffectCacheNode *aCached)
+    {
+    if (iVisual)
+        {
+        //iVisual->SetEffect( iEffect );
+        iVisual->SetLoadingEffect(EFalse);
+        CHuiFxEffectCacheEffectNode *node = new (ELeave) CHuiFxEffectCacheEffectNode(*iFileName, iEffect, iVisual, iExtRect, iEngine);
+        CleanupStack::PushL(node);
+        node->LightOperationL(aCached);
+        CleanupStack::PopAndDestroy(node);
+        }
+    // no delete here, because the parser will be destroyed immediately after this inside CHuiFxEffectParser::RunL()
+    // This moves ownership to CHuiFxEffectParser.
+    iParser = NULL;
+    }
+
+void CHuiFxEffectCacheEffectNode::SetEffectEndObserver( MAlfGfxEffectObserver* aEffectEndObserver, TInt aHandle )
+    {
+    iEffectEndObserver = aEffectEndObserver;
+    iHandle = aHandle;
+    }
+
+void CHuiFxEffectCacheEffectNode::SetEffectFlags( TInt aFlags )
+    {
+    iFlags = aFlags;
+    }
+	
+void CHuiFxEffectCacheEffectNode::SetEffectGroup( TInt aGroup)
+    {
+    iGroup = aGroup;
+    }
+
+TBool CHuiFxEffectCacheEffectNode::FxmlUsesInput1()
+    {
+    CHuiFxEffect *effect = iEffect;
+
+    RArray<THuiFxVisualSrcType> array;
+    effect->FxmlVisualInputs(array);
+ 
+    TInt c = array.Count();
+    for(TInt i = 0; i<c; i++)
+        {
+        THuiFxVisualSrcType val = array[i];
+        if (val == EVisualSrcInput1)
+            {
+            array.Close();
+            return ETrue;
+            }
+        }
+    array.Close();
+    return EFalse;
+    }