datasourcemodules/simulationpositioningmodule/src/EPos_CPosControllerManager.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:50:39 +0200
changeset 0 9cfd9a3ee49c
permissions -rw-r--r--
Revision: 201002 Kit: 201005

/*
* 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:
*
*/

#include "EPos_CPosControllerManager.h"
#include <e32debug.h> 
#include <f32file.h>
#include <e32std.h>
#include <centralrepository.h>
#include "EPos_CPosSimulationPositioner.h"
#include "EPos_CPosControllerBase.h"
#include "SimulationPSYInternalCRKeys.h"
#include "EPos_CPosNmeaController.h"
#include "EPos_CPosFixedDataController.h"
#include "EPos_CPosDataSimulationController.h"
_LIT(KDefaultNmeFileName, "\\resource\\default.nme");

// The unit tests (te_lbssimulationsuite.exe) are built as an EXE and cannot 
// use TLS.  The macro below redefines Dll to a new class TestDll that provides 
// an EXE equivalent.
#ifdef SIMPSYTEST
#define Dll TestDll
class TestDll
	{
public:
	static TAny* Tls() { return reinterpret_cast<TAny*>(iInternal); };
	static TInt SetTls(const TAny* aAny) 
		{ 
		iInternal = reinterpret_cast<TUint32>(aAny); 
		return KErrNone;
		};
	static void FreeTls() { iInternal = 0; };
private:
	static TUint32 iInternal;
	};
TUint32 TestDll::iInternal = 0;
#endif

TUint32 HashFunc(const CPosSimulationPositioner& aSimPos)
	{
	return DefaultHash::Integer(reinterpret_cast<TInt>(&aSimPos));
	}

TBool IdentityFunc(const CPosSimulationPositioner& aSimPos1, const CPosSimulationPositioner& aSimPos2)
	{
	return &aSimPos1 == &aSimPos2;
	}

// ---------------------------------------------------------------------------
// Returns the singleton instance.
// ---------------------------------------------------------------------------
//
CPosControllerManager* CPosControllerManager::InstanceL()
	{
	CPosControllerManager* self = NULL;

	TAny* tlsPtr = Dll::Tls();
	if (!tlsPtr)
		{
		self = new (ELeave) CPosControllerManager;
		CleanupStack::PushL(self);
		self->ConstructL();
		User::LeaveIfError(Dll::SetTls(self));
		CleanupStack::Pop(self);
		}
	else
		{
		self = static_cast<CPosControllerManager*> (tlsPtr);
		++self->iReferenceCount;
		}

	return self;
	}

// ---------------------------------------------------------------------------
// Releases the singleton instance.
// ---------------------------------------------------------------------------
//
void CPosControllerManager::ReleaseInstance(const CPosSimulationPositioner& aSimPos)
	{
	//Delete controller only in Independent Data Set mode.
	//when there is more then one controller
	//In TRP mode the only existing controller is deleted in destructor
	if (!iTrp)
		{
		CPosControllerBase* p = iPositionerControllerMap.Find(aSimPos);
		delete p;
		iPositionerControllerMap.Remove(&aSimPos);
		}
	

	TAny* tlsPtr = Dll::Tls();
	__ASSERT_DEBUG( tlsPtr, User::Panic(
					_L( "CPosControllerManager" ), KErrNotFound ) );

	CPosControllerManager* self = static_cast<CPosControllerManager*> (tlsPtr);
	if (--self->iReferenceCount == 0)
		{
		Dll::FreeTls();
		delete self;
		}
	}

CPosControllerManager::CPosControllerManager() :
	iReferenceCount(1),
	iPositionerControllerMap(THashFunction32<CPosSimulationPositioner>(&HashFunc), TIdentityRelation<CPosSimulationPositioner>(&IdentityFunc))
	{
	iLastFixIsPartial = EFalse; 
	}

void CPosControllerManager::ConstructL()
	{
	iTrp = RepositoryTrpValueL();
	}

/**
 * Private destructor so users cannot directly delete this instance.
 * They must call ReleaseInstance()
 */
CPosControllerManager::~CPosControllerManager()
	{
	iPositionerControllerMap.Close();
	if (iTrpController && iTrp)
		{
		delete iTrpController;
		}
	}

/**
 * Check in central repository if time relative playback (TRP) in on.
 * @return ETrue if TRP is on, EFalse if it's off.
 */
TBool CPosControllerManager::RepositoryTrpValueL()
	{
	TInt val = 0;
	CRepository* repository = CRepository::NewLC(KCRUidSimulationPSY);
	User::LeaveIfError( repository->Get(KCRKeySimPSYCommonDataSet, val) );
	CleanupStack::PopAndDestroy(repository);
	return static_cast<TBool>(val);
	}

CPosControllerBase& CPosControllerManager::ControllerL(
		const CPosSimulationPositioner& aSimPos)
	{
	CPosControllerBase* p = NULL;
	if(!iTrp)
		{
		p = iPositionerControllerMap.Find(aSimPos);
		}
	else
		{
		p = iTrpController;
		}
	//if there is no controller associated with give positioner
	//just create new one
	if(!p)
		{
		p = CreateControllerL(aSimPos);
		//in Time Relative Playback we should have only one controller
		//in old mode we need to create each time new one.
		if (iTrp)
			{
			iTrpController = p;
			}
		}
	return *p;
	}

/**
 * Create controller and pairs it with given CPosSimulationPositioner 
 * Controller type is determined by filename given in central repository.
 * @param aSimPos Pointer to positioner that will be connecter with new controller
 */
CPosControllerBase* CPosControllerManager::CreateControllerL(const CPosSimulationPositioner& aSimPos)
	{
	CPosControllerBase* retController = NULL;
	//getting file name from repository
	TFileName fileName;
	CRepository* repository = CRepository::NewLC(KCRUidSimulationPSY);
	User::LeaveIfError(repository->Get(KCRKeySimPSYSimulationFile, fileName));
	CleanupStack::PopAndDestroy(repository);

	fileName.LowerCase();
	TParsePtrC fileNamePtr(fileName);

	//based on file extension creating correct type controller
	TInt err = KErrNone;
	if (fileNamePtr.Ext().Compare(KPosNMEAFileExtension) == 0)
		{
			TRAP(err, retController =
					CPosNmeaController::NewL(fileName, iTrp));
		}
	else if (fileNamePtr.Ext().Compare(KPosSimulationFileExtension) == 0)
		{
			TRAP(err, retController =
					CPosDataSimController::NewL(fileName, iTrp));
		}
	else if (fileName.Length() == 0)
		{
		// No file selected so use the default.nme file from
		// \resource directory
		TFileName DllName;
		TParse nmeFileName;
#ifndef SIMPSYTEST
		Dll::FileName(DllName);
#else
		_LIT(KTestPathTxt, "Z:\\resource\\");
		DllName.Copy(KTestPathTxt);
#endif

		nmeFileName.Set(KDefaultNmeFileName, &DllName, NULL);

			TRAP(err, retController =
					CPosNmeaController::NewL(nmeFileName.FullName(), iTrp));
		if (err == KErrPathNotFound || err == KErrNotFound 
				|| err == KErrCorrupt)
			{
				TRAP(err, retController = CPosFixedDataController::NewL());
			}
		}
	else
		{
		err = KErrNotSupported;
		}
	User::LeaveIfError(err);
	//after valid controller creation adding it to map of positioners 
	//and controllers to be able then properly delete it when it will be unneeded
	if(!iTrp)
		{
		iPositionerControllerMap.InsertL(&aSimPos, retController);
		}
	return retController;
	}

TPositionInfo& CPosControllerManager::GetLastFix()
	{
	return iLastFix;
	}

void CPosControllerManager::SetLastFix(TPositionInfo& aPosInfo)
	{
	iLastFix = aPosInfo;
	}

TBool CPosControllerManager::GetLastFixIsPartial()
	{
	return iLastFixIsPartial;
	}

void CPosControllerManager::SetLastFixIsPartial(TBool aPartial)
	{
	iLastFixIsPartial = aPartial;
	}