lafagnosticuifoundation/cone/inc/CoeDynamicStorage.inl
changeset 0 2f259fa3e83a
child 10 9f56a4e1b8ab
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 // #define PROFILE_MEMORY	// Uncomment to profile ammount of saved memory.
       
    17 
       
    18 #ifdef PROFILE_MEMORY
       
    19 static TInt MEMORY_SAVED = 0;	// In bytes
       
    20 const TInt KCurrentNumberOfOptionalVaraiblesInCCoeControl = 13;
       
    21 #endif
       
    22 
       
    23 /** 
       
    24 This class implements a container for (in most cases, pointers to) optional 
       
    25 CCoeControl members.
       
    26 
       
    27 The size of the class is 12 bytes: one 32-bit pointer to a C-style array 
       
    28 of 32-bit data, and one long long (64 bits) variable used as an array of 4-bit 
       
    29 indices into said C-style array. 
       
    30 
       
    31 Each optional CCoeControl data is assigned an index into the long long member, 
       
    32 used to look up the variables actual index in the C-style array. This way, the 
       
    33 first time a new optional CCoeControl variable is set it is appended to the C-style 
       
    34 array, and the index of the new item is recorded in the variable's assigned 
       
    35 4-bit slot in the long long. 
       
    36 
       
    37 The 4-bits used for each index allows for 16 indices to be stored in the long long. 
       
    38 However, one value (say 0xF) is required to signal that the optional variable has 
       
    39 not yet been added to the C-style array, so this leaves 15 optional CCoeControl members. 
       
    40 
       
    41 This also leaves the last 4 bits in the long long unused. Now, we also need a way 
       
    42 to record the current size of the C-style array. As the size range from 0 to 15, 
       
    43 4-bit is enough, which means that we can use the last 4 spare bits in the long long 
       
    44 instead of adding another variable to the RCoeDynamicDataStorage!
       
    45 
       
    46 Thus, each first time an optional member is set, we need to re-allocate the C-style 
       
    47 array, and this operation might of course fail. All of the data kept in the 
       
    48 RCoeDynamicDataStorage must therefore be optional, and the code able to cope 
       
    49 with this. To minimize the number of re-allocations, the RCoeDynamicDataStorage 
       
    50 allows pre-allocation of the maximum amount needed. Currently, pre-allocation is 
       
    51 attempted at CCoeControl construction (in the c'tor), and compression is attempted 
       
    52 when the control is activated. The RCoeDynamicDataStorage will still work if either 
       
    53 fails.
       
    54 
       
    55 @internalComponent */
       
    56 class RCoeDynamicDataStorage
       
    57 	{
       
    58 public:
       
    59 	RCoeDynamicDataStorage();
       
    60 	void Open();
       
    61 	void Close();
       
    62 	TInt Count() const;
       
    63 	void ResetCount();
       
    64 	void IncCount();
       
    65 	TInt ReserveData();
       
    66 	TBool HasReservedData() const;
       
    67 	void AttemptCompress();
       
    68 	inline TAny* Data(TInt aSlotIndex, TAny* aDefaultValue) const;	//mm Will this method be expanded inline when used inside coecntrl.cpp?
       
    69 	TInt SetData(TInt aSlotIndex, TAny* aAny);
       
    70 	inline TInt DataIndex(TInt aSlotIndex) const;
       
    71 	void SetDataIndex(TInt aSlotIndex, TInt aDataIndex);
       
    72 	
       
    73 private:
       
    74 	static const TInt KMaxDataItems;
       
    75 	static const TInt KCounterSlotIndex;
       
    76 	static const TInt KIndexSlotSize;
       
    77 	static const Uint64 KIndexSlotMask;
       
    78 	static const TInt KUndefinedIndex;
       
    79 
       
    80 private:
       
    81 	TInt Append(TAny* aAny);
       
    82 	
       
    83 private:	
       
    84 	Uint64 iIndices;	// array of slots containing indices into the data array
       
    85 	TAny** iDynamicData;		// dynamic array of 32-bit data (mostly pointers)
       
    86 	};
       
    87 	
       
    88 
       
    89 const TInt RCoeDynamicDataStorage::KMaxDataItems = 15;
       
    90 const TInt RCoeDynamicDataStorage::KCounterSlotIndex = 0xF;
       
    91 const TInt RCoeDynamicDataStorage::KIndexSlotSize = 4;
       
    92 const Uint64 RCoeDynamicDataStorage::KIndexSlotMask = 0xFLL;	//long long
       
    93 const TInt RCoeDynamicDataStorage::KUndefinedIndex = 0xF;
       
    94 
       
    95 RCoeDynamicDataStorage::RCoeDynamicDataStorage()
       
    96 : iIndices(~0x0), iDynamicData(NULL)	// Set iIndices to all ones
       
    97 	{
       
    98 	ResetCount();
       
    99 	}
       
   100 
       
   101 void RCoeDynamicDataStorage::Open()
       
   102 	{
       
   103 	ASSERT(!iDynamicData);
       
   104 	ReserveData();
       
   105 	
       
   106 #ifdef PROFILE_MEMORY
       
   107 	MEMORY_SAVED += KCurrentNumberOfOptionalVaraiblesInCCoeControl*sizeof(TAny*);
       
   108 	MEMORY_SAVED -= sizeof(RCoeDynamicDataStorage);
       
   109 #endif	
       
   110 	}
       
   111 	
       
   112 void RCoeDynamicDataStorage::Close()
       
   113 	{
       
   114 #ifdef PROFILE_MEMORY
       
   115 	MEMORY_SAVED += sizeof(RCoeDynamicDataStorage);
       
   116 	if(HasReservedData())
       
   117 		MEMORY_SAVED +=  KMaxDataItems*sizeof(TAny*);
       
   118 	else
       
   119 		MEMORY_SAVED += Count()*sizeof(TAny*);
       
   120 	
       
   121 	MEMORY_SAVED -= KCurrentNumberOfOptionalVaraiblesInCCoeControl*sizeof(TAny*);
       
   122 #endif	
       
   123 	delete [] iDynamicData;
       
   124 	}
       
   125 
       
   126 TInt RCoeDynamicDataStorage::Count() const
       
   127 	{
       
   128 	if(HasReservedData())
       
   129 		{
       
   130 		TInt count = 0;
       
   131 		for(TInt i = 0; i < KMaxDataItems; i++)
       
   132 			{
       
   133 			if(DataIndex(i) != KUndefinedIndex)
       
   134 				count++;
       
   135 			}
       
   136 		return count;	
       
   137 		}
       
   138 	else
       
   139 		return DataIndex(KCounterSlotIndex);	
       
   140 	}
       
   141 
       
   142 void RCoeDynamicDataStorage::ResetCount()
       
   143 	{
       
   144 	SetDataIndex(KCounterSlotIndex, 0);
       
   145 	}
       
   146 	
       
   147 void RCoeDynamicDataStorage::IncCount()
       
   148 	{
       
   149 	TInt count = Count();
       
   150 	count++;
       
   151 	SetDataIndex(KCounterSlotIndex, count);
       
   152 	ASSERT(count <= KMaxDataItems);
       
   153 	}
       
   154 
       
   155 TInt RCoeDynamicDataStorage::SetData(TInt aSlotIndex, TAny* aAny)
       
   156 	{
       
   157 	if(!this)
       
   158 		return KErrNoMemory;
       
   159 	
       
   160 	const TInt dataIndex = DataIndex(aSlotIndex);
       
   161 
       
   162 	if(dataIndex != KUndefinedIndex)
       
   163 		iDynamicData[dataIndex] = aAny;
       
   164 	else if(HasReservedData())
       
   165 		{
       
   166 		const TInt count = Count();
       
   167 		iDynamicData[count] = aAny;
       
   168 		SetDataIndex(aSlotIndex, count);
       
   169 		}
       
   170 	else
       
   171 		{
       
   172 		const TInt err = Append(aAny);
       
   173 		if(err)
       
   174 			return err;
       
   175 		else
       
   176 			SetDataIndex(aSlotIndex, Count()-1);
       
   177 		}
       
   178 	ASSERT(Data(aSlotIndex, NULL) == aAny);	
       
   179 	return KErrNone;
       
   180 	}
       
   181 
       
   182 inline TAny* RCoeDynamicDataStorage::Data(TInt aSlotIndex, TAny* aDefaultValue) const
       
   183 	{
       
   184 	if(!this)
       
   185 		return aDefaultValue;
       
   186 		
       
   187 	const TInt dataIndex = DataIndex(aSlotIndex);
       
   188 	if(dataIndex != KUndefinedIndex)
       
   189 		return iDynamicData[dataIndex];
       
   190 	else
       
   191 		return aDefaultValue;	
       
   192 	}
       
   193 
       
   194 inline TInt RCoeDynamicDataStorage::DataIndex(TInt aSlotIndex) const
       
   195 	{
       
   196 	const Uint64 mask = KIndexSlotMask << KIndexSlotSize*aSlotIndex;
       
   197 	return ((iIndices&mask) >> KIndexSlotSize*aSlotIndex);
       
   198 	}
       
   199 	
       
   200 void RCoeDynamicDataStorage::SetDataIndex(TInt aSlotIndex, TInt aDataIndex)
       
   201 	{
       
   202 	const Uint64 mask = KIndexSlotMask << KIndexSlotSize*aSlotIndex;
       
   203 	const Uint64 dataIndex = Uint64(aDataIndex) << KIndexSlotSize*aSlotIndex;
       
   204 	iIndices &= ~mask;	// clear the old index
       
   205 	iIndices |= dataIndex; // set the new index
       
   206 	}
       
   207 
       
   208 TInt RCoeDynamicDataStorage::Append(TAny* aAny)
       
   209 	{
       
   210 	ASSERT(!HasReservedData());	// Should never have reserved data if we get here
       
   211 	
       
   212 	const TInt count = Count();
       
   213 	TAny** newData = new TAny*[count+1];
       
   214 	if(!newData)
       
   215 		return KErrNoMemory;
       
   216 	
       
   217 	memcpy(newData, iDynamicData, count * sizeof(TAny*));
       
   218 		
       
   219 	newData[count]	= aAny;
       
   220 	IncCount();
       
   221 #ifdef PROFILE_MEMORY
       
   222 	MEMORY_SAVED -= (1 * sizeof(TAny*));
       
   223 #endif
       
   224 		
       
   225 	delete [] iDynamicData;
       
   226 	iDynamicData = newData;
       
   227 	return KErrNone;
       
   228 	}
       
   229 
       
   230 
       
   231 TInt RCoeDynamicDataStorage::ReserveData()
       
   232 	{
       
   233 	ASSERT(!iDynamicData);
       
   234 	iDynamicData = new TAny*[KMaxDataItems];	// Attempt to pre-alloc data
       
   235 	if(!iDynamicData)
       
   236 		return KErrNoMemory;	
       
   237 	
       
   238 #ifdef PROFILE_MEMORY
       
   239 	MEMORY_SAVED -= KMaxDataItems*sizeof(TAny*);
       
   240 #endif	
       
   241 	return KErrNone;
       
   242 	}
       
   243 		
       
   244 TBool RCoeDynamicDataStorage::HasReservedData() const
       
   245 	{
       
   246 	return (iDynamicData && DataIndex(KCounterSlotIndex) == 0);
       
   247 	}
       
   248 
       
   249 void RCoeDynamicDataStorage::AttemptCompress()
       
   250 	{
       
   251 	if(!HasReservedData()) 
       
   252 		return;
       
   253 	
       
   254 	const TInt count = Count();
       
   255 	if(!count)	// "new TAny*[0]" gives undefined result!
       
   256 		{
       
   257 		delete [] iDynamicData;
       
   258 		iDynamicData = NULL;
       
   259 		}
       
   260 	else
       
   261 		{
       
   262 		TAny** newData = new TAny*[count];
       
   263 		if(!newData)
       
   264 			return;
       
   265 		
       
   266 		memcpy(newData, iDynamicData, count * sizeof(TAny*));
       
   267 					
       
   268 		delete [] iDynamicData;
       
   269 		iDynamicData = newData;
       
   270 		SetDataIndex(KCounterSlotIndex, count);
       
   271 		}
       
   272 		
       
   273 #ifdef PROFILE_MEMORY		
       
   274 	MEMORY_SAVED += (sizeof(TAny*) * (0xF - count));
       
   275 #endif	
       
   276 	}
       
   277 
       
   278 // 
       
   279 // class TCoeZoomWithType 
       
   280 // 
       
   281 
       
   282 class TCoeZoomWithType 
       
   283     { 
       
   284 public:                 
       
   285     TInt iZoomFactor; 
       
   286     CCoeControl::TZoomType iZoomType; 
       
   287     }; 
       
   288 
       
   289 // 
       
   290 // class SColorOverride
       
   291 // 
       
   292 
       
   293 struct SColorOverride	
       
   294 	{
       
   295 	TRgb iColor;
       
   296 	TInt iLogicalColor;
       
   297 	};
       
   298 
       
   299 enum TData
       
   300 	{
       
   301 	ECoeControlParent = 0x0,
       
   302 	ECoeControlObserver = 0x1,
       
   303 	ECoeComponentArray = 0x2,
       
   304 	ECoeLayoutManager = 0x3,
       
   305 	ECoeControlBackground = 0x4,
       
   306 	EMaximumWidthTInt = 0x5,
       
   307 	EUniqueHandleTInt = 0x6,
       
   308 	EColorOverrides = 0x7,
       
   309 	EFocusObserverNotificationIdentifier = 0x8,
       
   310 	ECoeControlHitTest = 0x9,
       
   311 	EZoomWithType = 0xA,
       
   312 	ECustomGc = 0xB,
       
   313 	EFontProvider = 0xC,
       
   314 	
       
   315 	EMaxOptionlData = 0xF
       
   316 	};
       
   317 
       
   318 // CoeControlParent
       
   319 inline CCoeControl* DoGetParent(const RCoeDynamicDataStorage& aData)
       
   320 	{ return static_cast<CCoeControl*>(aData.Data(ECoeControlParent, NULL)); }
       
   321 
       
   322 inline TInt DoSetParent(RCoeDynamicDataStorage& aData, CCoeControl* aParent) 
       
   323 	{ return aData.SetData(ECoeControlParent, aParent); }
       
   324 
       
   325 // Observer
       
   326 inline MCoeControlObserver* DoGetObserver(const RCoeDynamicDataStorage& aData)
       
   327 	{ return static_cast<MCoeControlObserver*>(aData.Data(ECoeControlObserver, NULL)); }
       
   328 
       
   329 inline TInt DoSetObserver(RCoeDynamicDataStorage& aData, MCoeControlObserver* aObserver) 
       
   330 	{ return aData.SetData(ECoeControlObserver, aObserver); }
       
   331 
       
   332 // ComponentArray
       
   333 inline CCoeControlArray* DoGetComponentArray(const RCoeDynamicDataStorage& aData)
       
   334 	{ return static_cast<CCoeControlArray*>(aData.Data(ECoeComponentArray, NULL)); }
       
   335 
       
   336 inline TInt DoSetComponentArray(RCoeDynamicDataStorage& aData, CCoeControlArray* aComponentArray) 
       
   337 	{ return aData.SetData(ECoeComponentArray, aComponentArray); }
       
   338 
       
   339 // LayoutManager
       
   340 inline MCoeLayoutManager* DoGetLayoutManager(const RCoeDynamicDataStorage& aData)
       
   341 	{ return static_cast<MCoeLayoutManager*>(aData.Data(ECoeLayoutManager, NULL)); }
       
   342 
       
   343 inline TInt DoSetLayoutManager(RCoeDynamicDataStorage& aData, MCoeLayoutManager* aLayoutManager) 
       
   344 	{ return aData.SetData(ECoeLayoutManager, aLayoutManager); }
       
   345 
       
   346 // Background
       
   347 inline const MCoeControlBackground* DoGetBackground(const RCoeDynamicDataStorage& aData)
       
   348 	{ return reinterpret_cast<const MCoeControlBackground*>(aData.Data(ECoeControlBackground, NULL)); }
       
   349 
       
   350 inline TInt DoSetBackground(RCoeDynamicDataStorage& aData, const MCoeControlBackground* aBackground) 
       
   351 	{ return aData.SetData(ECoeControlBackground, const_cast<MCoeControlBackground*>(aBackground)); }
       
   352 
       
   353 // Max width
       
   354 inline TInt DoGetMaximumWidth(const RCoeDynamicDataStorage& aData)
       
   355 	{ return reinterpret_cast<TInt>(aData.Data(EMaximumWidthTInt, NULL)); }
       
   356 
       
   357 inline TInt DoSetMaximumWidth(RCoeDynamicDataStorage& aData, TInt aMaxWidth) 
       
   358 	{ return aData.SetData(EMaximumWidthTInt, reinterpret_cast<TAny*>(aMaxWidth)); }
       
   359 
       
   360 // Unique Id
       
   361 inline TInt DoGetUniqueHandle(const RCoeDynamicDataStorage& aData)
       
   362 	{ return reinterpret_cast<TInt>(aData.Data(EUniqueHandleTInt, reinterpret_cast<TAny*>(KErrNotFound))); }
       
   363 
       
   364 inline TInt DoSetUniqueHandle(RCoeDynamicDataStorage& aData, TInt aUniqueHandle) 
       
   365 	{ return aData.SetData(EUniqueHandleTInt, reinterpret_cast<TAny*>(aUniqueHandle)); }
       
   366 
       
   367 // ColorOverrides
       
   368 inline CArrayFix<SColorOverride>* DoGetColorOverrides(const RCoeDynamicDataStorage& aData)
       
   369 	{ return reinterpret_cast<CArrayFix<SColorOverride>*>(aData.Data(EColorOverrides, NULL)); }
       
   370 
       
   371 inline TInt DoSetColorOverrides(RCoeDynamicDataStorage& aData, CArrayFix<SColorOverride>* aColorOverrides) 
       
   372 	{ return aData.SetData(EColorOverrides, static_cast<TAny*>(aColorOverrides)); }
       
   373 
       
   374 // FocusObserverNotificationIdentifier
       
   375 inline TInt DoGetFocusObserverNotificationIdentifier(const RCoeDynamicDataStorage& aData)
       
   376 	{ return reinterpret_cast<TInt>(aData.Data(EFocusObserverNotificationIdentifier, NULL)); }
       
   377 
       
   378 inline TInt DoSetFocusObserverNotificationIdentifier(RCoeDynamicDataStorage& aData, TInt aFocusObserverNotificationIdentifier) 
       
   379 	{ return aData.SetData(EFocusObserverNotificationIdentifier, reinterpret_cast<TAny*>(aFocusObserverNotificationIdentifier)); }
       
   380 
       
   381 // HitTest
       
   382 inline const MCoeControlHitTest* DoGetHitTest(const RCoeDynamicDataStorage& aData)
       
   383 	{ return reinterpret_cast<const MCoeControlHitTest*>(aData.Data(ECoeControlHitTest, NULL)); }
       
   384 
       
   385 inline TInt DoSetHitTest(RCoeDynamicDataStorage& aData, const MCoeControlHitTest* aHitTest) 
       
   386 	{ return aData.SetData(ECoeControlHitTest, const_cast<MCoeControlHitTest*>(aHitTest)); }
       
   387 
       
   388 // ZoomWithType
       
   389 inline TCoeZoomWithType* DoGetZoomWithType(const RCoeDynamicDataStorage& aData)
       
   390 	{ return reinterpret_cast<TCoeZoomWithType*>(aData.Data(EZoomWithType, NULL)); }
       
   391 
       
   392 inline TInt DoSetZoomWithType(RCoeDynamicDataStorage& aData, const TCoeZoomWithType* aZoomWithType) 
       
   393 	{ return aData.SetData(EZoomWithType, const_cast<TCoeZoomWithType*>(aZoomWithType)); }
       
   394 
       
   395 // CustomGc
       
   396 inline CWindowGc* DoGetCustomGc(const RCoeDynamicDataStorage& aData)
       
   397 	{ return reinterpret_cast<CWindowGc*>(aData.Data(ECustomGc, NULL)); }
       
   398 
       
   399 inline TInt DoSetCustomGc(const RCoeDynamicDataStorage& aData, CWindowGc* aGc) 
       
   400 	{ return const_cast<RCoeDynamicDataStorage&>(aData).SetData(ECustomGc, aGc); }
       
   401 
       
   402 // FontProvider
       
   403 inline const CCoeFontProvider* DoGetFontProvider(const RCoeDynamicDataStorage& aData)
       
   404 	{ return reinterpret_cast<const CCoeFontProvider*>(aData.Data(EFontProvider, NULL)); }
       
   405 
       
   406 inline TInt DoSetFontProvider(const RCoeDynamicDataStorage& aData, const CCoeFontProvider* aFontProvider) 
       
   407 	{ return const_cast<RCoeDynamicDataStorage&>(aData).SetData(EFontProvider, const_cast<CCoeFontProvider*>(aFontProvider)); }
       
   408