<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliVZERODataDCS.h"

#include "AliDCSValue.h"
#include "AliLog.h"

#include <TGraph.h>
#include <TAxis.h>
#include <TCanvas.h>
#include <TTimeStamp.h>
#include <TMap.h>
#include <TString.h>
#include <TH1F.h>

class TH2;
class AliCDBMetaData;
class TDatime;

// AliVZERODataDCS class
// main aim to introduce the aliases for the VZERO DCS
// data points to be then
// stored in the OCDB, and to process them.
// ProcessData() method called by VZEROPreprocessor

ClassImp(AliVZERODataDCS)

//_____________________________________________________________________________
AliVZERODataDCS::AliVZERODataDCS():
	TObject(),
	fRun(0),
	fStartTime(0),
	fEndTime(0),
        fGraphs("TGraph",kNGraphs),
	fIsProcessed(kFALSE)
{
  // Default constructor
  for(int i=0;i<kNHvChannel;i++) fDeadChannel[i] = kFALSE;
}

//_____________________________________________________________________________
AliVZERODataDCS::AliVZERODataDCS(Int_t nRun, UInt_t startTime, UInt_t endTime):
	TObject(),
	fRun(nRun),
	fStartTime(startTime),
	fEndTime(endTime),
        fGraphs("TGraph",kNGraphs),
	fIsProcessed(kFALSE)
{

  // constructor with arguments
  	for(int i=0;i<kNHvChannel;i++) fDeadChannel[i] = kFALSE;

	AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", nRun,
	TTimeStamp(startTime).AsString(),
	TTimeStamp(endTime).AsString()));

	Init();

}

//_____________________________________________________________________________
AliVZERODataDCS::~AliVZERODataDCS() {

  // destructor
  fGraphs.Clear("C");

}

//_____________________________________________________________________________
void AliVZERODataDCS::ProcessData(TMap& aliasMap){

  // method to process the data

  if(!(fAliasNames[0])) Init();

  TObjArray *aliasArr;
  AliDCSValue* aValue;

  // starting loop on aliases
  for(int iAlias=0; iAlias<kNAliases; iAlias++){

    aliasArr = (TObjArray*) aliasMap.GetValue(fAliasNames[iAlias].Data());
    if(!aliasArr){
      AliError(Form("Alias %s not found!", fAliasNames[iAlias].Data()));
      return;
    }

    //Introduce(iAlias, aliasArr);

    if(aliasArr->GetEntries()<2){
      AliError(Form("Alias %s has just %d entries!",
		    fAliasNames[iAlias].Data(),aliasArr->GetEntries()));
      continue;
    }

    TIter iterarray(aliasArr);

    Int_t nentries = aliasArr->GetEntries();

    Double_t *times = new Double_t[nentries];
    Double_t *values = new Double_t[nentries];

    UInt_t iValue=0;
    while((aValue = (AliDCSValue*) iterarray.Next())) {
   		values[iValue] = aValue->GetFloat();
		if(iValue>0) {
			Float_t variation ;
			if(values[iValue-1]>0.) variation = TMath::Abs(values[iValue]-values[iValue-1])/values[iValue-1];
			if(variation > 0.10) fDeadChannel[GetOfflineChannel(iAlias)] = kTRUE;
		}
   		times[iValue] = (Double_t) (aValue->GetTimeStamp());
		fHv[iAlias]->Fill(values[iValue]);
		printf("%s %f Dead=%d\n",fAliasNames[iAlias].Data(),values[iValue],fDeadChannel[GetOfflineChannel(iAlias)]);
   		iValue++;
    }
    CreateGraph(iAlias, aliasArr->GetEntries(), times, values); // fill graphs

    delete[] values;
    delete[] times;
  }

  	// calculate mean and rms of the first two histos
	// and convert index to aliroot channel
	for(int i=0;i<kNAliases;i++){
	        Int_t iChannel     = GetOfflineChannel(i);
		fMeanHV[iChannel]  = fHv[i]->GetMean();
		fWidthHV[iChannel] = fHv[i]->GetRMS();
	}

  fIsProcessed=kTRUE;
}

//_____________________________________________________________________________
void AliVZERODataDCS::Init(){

  // initialization of aliases and DCS data

  TString sindex;
  int iAlias = 0;

  for(int iSide = 0; iSide<2 ; iSide++){
  	for(int iRing = 0; iRing<4 ; iRing++){
  		for(int iSector = 0; iSector<8 ; iSector++){
  			if(iSide == 0) fAliasNames[iAlias] = "V00/HV/V0A/SECTOR";
  			else fAliasNames[iAlias] = "V00/HV/V0C/SECTOR";
			sindex.Form("%d/RING%d",iSector,iRing);
			fAliasNames[iAlias] += sindex;

			fHv[iAlias] = new TH1F(fAliasNames[iAlias].Data(),fAliasNames[iAlias].Data(), 2000, kHvMin, kHvMax);
			fHv[iAlias]->GetXaxis()->SetTitle("Hv");
			iAlias++;
  		}
  	}
  }
  if(iAlias!=kNAliases)
  	      AliError(Form("Number of DCS Aliases defined not correct"));

}

//_____________________________________________________________________________
void AliVZERODataDCS::Introduce(UInt_t numAlias, const TObjArray* aliasArr)const
{

  // method to introduce new aliases

  int entries=aliasArr->GetEntries();
  AliInfo(Form("************ Alias: %s **********",fAliasNames[numAlias].Data()));
  AliInfo(Form("    	%d DP values collected",entries));

}

//_____________________________________________________________________________
void AliVZERODataDCS::CreateGraph(int i, int dim, const Double_t *x, const Double_t *y)
{

   // Create graphics

   TGraph *gr = new(fGraphs[fGraphs.GetEntriesFast()]) TGraph(dim, x, y);

   gr->GetXaxis()->SetTimeDisplay(1);
   gr->SetTitle(fAliasNames[i].Data());

   AliInfo(Form("Array entries: %d",fGraphs.GetEntriesFast()));

}

//_____________________________________________________________________________
void AliVZERODataDCS::Draw(const Option_t* /*option*/)
{
// Draw all histos and graphs

  if(!fIsProcessed) return;

  if(fGraphs.GetEntries()==0)  return;

  TString canvasName;
  TCanvas *cHV[8];

  for(int iSide = 0 ;iSide<2;iSide++){
  	for(int iRing=0;iRing<4;iRing++){
  		if(iSide == 0)  canvasName = "V0A_Ring";
  		else  canvasName = "V0C_Ring";
  		canvasName += iRing;
  		int iCanvas = iSide*4 + iRing;
  		cHV[iCanvas] = new TCanvas(canvasName,canvasName);
  		cHV[iCanvas]->Divide(3,3);
  		for(int iSector=0;iSector<8;iSector++){
  			cHV[iCanvas]->cd(iSector+1);
  			int iChannel = iSide*32 + iRing*8 + iSector;
  			((TGraph*) fGraphs.UncheckedAt(iChannel))->SetMarkerStyle(20);
  			((TGraph*) fGraphs.UncheckedAt(iChannel))->Draw("ALP");

  		}

  	}
  }

}

<commit_msg>Warning fixed<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliVZERODataDCS.h"

#include "AliDCSValue.h"
#include "AliLog.h"

#include <TGraph.h>
#include <TAxis.h>
#include <TCanvas.h>
#include <TTimeStamp.h>
#include <TMap.h>
#include <TString.h>
#include <TH1F.h>

class TH2;
class AliCDBMetaData;
class TDatime;

// AliVZERODataDCS class
// main aim to introduce the aliases for the VZERO DCS
// data points to be then
// stored in the OCDB, and to process them.
// ProcessData() method called by VZEROPreprocessor

ClassImp(AliVZERODataDCS)

//_____________________________________________________________________________
AliVZERODataDCS::AliVZERODataDCS():
	TObject(),
	fRun(0),
	fStartTime(0),
	fEndTime(0),
        fGraphs("TGraph",kNGraphs),
	fIsProcessed(kFALSE)
{
  // Default constructor
  for(int i=0;i<kNHvChannel;i++) fDeadChannel[i] = kFALSE;
}

//_____________________________________________________________________________
AliVZERODataDCS::AliVZERODataDCS(Int_t nRun, UInt_t startTime, UInt_t endTime):
	TObject(),
	fRun(nRun),
	fStartTime(startTime),
	fEndTime(endTime),
        fGraphs("TGraph",kNGraphs),
	fIsProcessed(kFALSE)
{

  // constructor with arguments
  	for(int i=0;i<kNHvChannel;i++) fDeadChannel[i] = kFALSE;

	AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", nRun,
	TTimeStamp(startTime).AsString(),
	TTimeStamp(endTime).AsString()));

	Init();

}

//_____________________________________________________________________________
AliVZERODataDCS::~AliVZERODataDCS() {

  // destructor
  fGraphs.Clear("C");

}

//_____________________________________________________________________________
void AliVZERODataDCS::ProcessData(TMap& aliasMap){

  // method to process the data

  if(!(fAliasNames[0])) Init();

  TObjArray *aliasArr;
  AliDCSValue* aValue;

  // starting loop on aliases
  for(int iAlias=0; iAlias<kNAliases; iAlias++){

    aliasArr = (TObjArray*) aliasMap.GetValue(fAliasNames[iAlias].Data());
    if(!aliasArr){
      AliError(Form("Alias %s not found!", fAliasNames[iAlias].Data()));
      return;
    }

    //Introduce(iAlias, aliasArr);

    if(aliasArr->GetEntries()<2){
      AliError(Form("Alias %s has just %d entries!",
		    fAliasNames[iAlias].Data(),aliasArr->GetEntries()));
      continue;
    }

    TIter iterarray(aliasArr);

    Int_t nentries = aliasArr->GetEntries();

    Double_t *times = new Double_t[nentries];
    Double_t *values = new Double_t[nentries];

    UInt_t iValue=0;
    Float_t variation = 0.0;

    while((aValue = (AliDCSValue*) iterarray.Next())) {
   		values[iValue] = aValue->GetFloat();
		if(iValue>0) {
			if(values[iValue-1]>0.) variation = TMath::Abs(values[iValue]-values[iValue-1])/values[iValue-1];
			if(variation > 0.10) fDeadChannel[GetOfflineChannel(iAlias)] = kTRUE;
		}
   		times[iValue] = (Double_t) (aValue->GetTimeStamp());
		fHv[iAlias]->Fill(values[iValue]);
		printf("%s %f Dead=%d\n",fAliasNames[iAlias].Data(),values[iValue],fDeadChannel[GetOfflineChannel(iAlias)]);
   		iValue++;
    }
    CreateGraph(iAlias, aliasArr->GetEntries(), times, values); // fill graphs

    delete[] values;
    delete[] times;
  }

  	// calculate mean and rms of the first two histos
	// and convert index to aliroot channel
	for(int i=0;i<kNAliases;i++){
	        Int_t iChannel     = GetOfflineChannel(i);
		fMeanHV[iChannel]  = fHv[i]->GetMean();
		fWidthHV[iChannel] = fHv[i]->GetRMS();
	}

  fIsProcessed=kTRUE;
}

//_____________________________________________________________________________
void AliVZERODataDCS::Init(){

  // initialization of aliases and DCS data

  TString sindex;
  int iAlias = 0;

  for(int iSide = 0; iSide<2 ; iSide++){
  	for(int iRing = 0; iRing<4 ; iRing++){
  		for(int iSector = 0; iSector<8 ; iSector++){
  			if(iSide == 0) fAliasNames[iAlias] = "V00/HV/V0A/SECTOR";
  			else fAliasNames[iAlias] = "V00/HV/V0C/SECTOR";
			sindex.Form("%d/RING%d",iSector,iRing);
			fAliasNames[iAlias] += sindex;

			fHv[iAlias] = new TH1F(fAliasNames[iAlias].Data(),fAliasNames[iAlias].Data(), 2000, kHvMin, kHvMax);
			fHv[iAlias]->GetXaxis()->SetTitle("Hv");
			iAlias++;
  		}
  	}
  }
  if(iAlias!=kNAliases)
  	      AliError(Form("Number of DCS Aliases defined not correct"));

}

//_____________________________________________________________________________
void AliVZERODataDCS::Introduce(UInt_t numAlias, const TObjArray* aliasArr)const
{

  // method to introduce new aliases

  int entries=aliasArr->GetEntries();
  AliInfo(Form("************ Alias: %s **********",fAliasNames[numAlias].Data()));
  AliInfo(Form("    	%d DP values collected",entries));

}

//_____________________________________________________________________________
void AliVZERODataDCS::CreateGraph(int i, int dim, const Double_t *x, const Double_t *y)
{

   // Create graphics

   TGraph *gr = new(fGraphs[fGraphs.GetEntriesFast()]) TGraph(dim, x, y);

   gr->GetXaxis()->SetTimeDisplay(1);
   gr->SetTitle(fAliasNames[i].Data());

   AliInfo(Form("Array entries: %d",fGraphs.GetEntriesFast()));

}

//_____________________________________________________________________________
void AliVZERODataDCS::Draw(const Option_t* /*option*/)
{
// Draw all histos and graphs

  if(!fIsProcessed) return;

  if(fGraphs.GetEntries()==0)  return;

  TString canvasName;
  TCanvas *cHV[8];

  for(int iSide = 0 ;iSide<2;iSide++){
  	for(int iRing=0;iRing<4;iRing++){
  		if(iSide == 0)  canvasName = "V0A_Ring";
  		else  canvasName = "V0C_Ring";
  		canvasName += iRing;
  		int iCanvas = iSide*4 + iRing;
  		cHV[iCanvas] = new TCanvas(canvasName,canvasName);
  		cHV[iCanvas]->Divide(3,3);
  		for(int iSector=0;iSector<8;iSector++){
  			cHV[iCanvas]->cd(iSector+1);
  			int iChannel = iSide*32 + iRing*8 + iSector;
  			((TGraph*) fGraphs.UncheckedAt(iChannel))->SetMarkerStyle(20);
  			((TGraph*) fGraphs.UncheckedAt(iChannel))->Draw("ALP");

  		}

  	}
  }

}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "DropDownPane.h"
#include "String.h"
#include "InterpretProp2.h"
#include <UIFunctions.h>

static wstring CLASS = L"DropDownPane";

ViewPane* CreateDropDownPane(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, bool bReadOnly)
{
	return new DropDownPane(uidLabel, bReadOnly, ulDropList, lpuidDropList, nullptr, false);
}

ViewPane* CreateDropDownArrayPane(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) LPNAME_ARRAY_ENTRY lpnaeDropList, bool bReadOnly)
{
	return new DropDownPane(uidLabel, bReadOnly, ulDropList, nullptr, lpnaeDropList, false);
}

ViewPane* CreateDropDownGuidPane(UINT uidLabel, bool bReadOnly)
{
	return new DropDownPane(uidLabel, bReadOnly, 0, nullptr, nullptr, true);
}

DropDownPane::DropDownPane(UINT uidLabel, bool bReadOnly, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, _In_opt_count_(ulDropList) LPNAME_ARRAY_ENTRY lpnaeDropList, bool bGUID) :ViewPane(uidLabel, bReadOnly)
{
	m_ulDropList = ulDropList;
	m_lpuidDropList = lpuidDropList;
	m_iDropSelection = CB_ERR;
	m_iDropSelectionValue = 0;
	m_lpnaeDropList = lpnaeDropList;
	m_bGUID = bGUID;
}

bool DropDownPane::IsType(__ViewTypes vType)
{
	return CTRL_DROPDOWNPANE == vType;
}

ULONG DropDownPane::GetFlags()
{
	ULONG ulFlags = vpNone;
	if (m_bReadOnly) ulFlags |= vpReadonly;
	return ulFlags;
}

wstring GetLBText(CComboBox& box, int nIndex)
{
	auto len = box.GetLBTextLen(nIndex);
	auto buffer = new TCHAR[len];
	memset(buffer, 0, sizeof(TCHAR)* len);
	box.GetLBText(nIndex, buffer);
	auto szOut = LPCTSTRToWstring(buffer);
	delete[] buffer;
	return szOut;
}

int DropDownPane::GetMinWidth(_In_ HDC hdc)
{
	auto cxDropDown = 0;
	for (auto iDropString = 0; iDropString < m_DropDown.GetCount(); iDropString++)
	{
		SIZE sizeDrop = { 0 };
		auto szDropString = GetLBText(m_DropDown, iDropString);
		::GetTextExtentPoint32W(hdc, szDropString.c_str(), szDropString.length(), &sizeDrop);
		cxDropDown = max(cxDropDown, sizeDrop.cx);
	}

	// Add scroll bar and margins for our frame
	cxDropDown += ::GetSystemMetrics(SM_CXVSCROLL) + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);

	return max(ViewPane::GetMinWidth(hdc), cxDropDown);
}

int DropDownPane::GetFixedHeight()
{
	auto iHeight = 0;

	if (0 != m_iControl) iHeight += m_iSmallHeightMargin; // Top margin

	if (m_bUseLabelControl)
	{
		iHeight += m_iLabelHeight;
	}

	iHeight += m_iEditHeight; // Height of the dropdown

	// No bottom margin on the DropDown as it's usually tied to the following control
	return iHeight;
}

int DropDownPane::GetLines()
{
	return 0;
}

void DropDownPane::SetWindowPos(int x, int y, int width, int /*height*/)
{
	auto hRes = S_OK;
	if (0 != m_iControl)
	{
		y += m_iSmallHeightMargin;
		// height -= m_iSmallHeightMargin;
	}

	if (m_bUseLabelControl)
	{
		EC_B(m_Label.SetWindowPos(
			nullptr,
			x,
			y,
			width,
			m_iLabelHeight,
			SWP_NOZORDER));
		y += m_iLabelHeight;
		// height -= m_iLabelHeight;
	}

	EC_B(m_DropDown.SetWindowPos(NULL, x, y, width, m_iEditHeight, SWP_NOZORDER));
}

void DropDownPane::DoInit(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	auto hRes = S_OK;

	ViewPane::Initialize(iControl, pParent, hdc);

	auto ulDrops = 1 + (m_ulDropList ? min(m_ulDropList, 4) : 4);
	auto dropHeight = ulDrops * (pParent ? GetEditHeight(pParent->m_hWnd) : 0x1e);

	// m_bReadOnly means you can't type...
	DWORD dwDropStyle;
	if (m_bReadOnly)
	{
		dwDropStyle = CBS_DROPDOWNLIST; // does not allow typing
	}
	else
	{
		dwDropStyle = CBS_DROPDOWN; // allows typing
	}

	EC_B(m_DropDown.Create(
		WS_TABSTOP
		| WS_CHILD
		| WS_CLIPSIBLINGS
		| WS_BORDER
		| WS_VISIBLE
		| WS_VSCROLL
		| CBS_OWNERDRAWFIXED
		| CBS_HASSTRINGS
		| CBS_AUTOHSCROLL
		| CBS_DISABLENOSCROLL
		| dwDropStyle,
		CRect(0, 0, 0, dropHeight),
		pParent,
		m_nID));
}

void DropDownPane::Initialize(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	DoInit(iControl, pParent, hdc);

	if (m_lpuidDropList)
	{
		for (ULONG iDropNum = 0; iDropNum < m_ulDropList; iDropNum++)
		{
			auto szDropString = loadstring(m_lpuidDropList[iDropNum]);
			InsertDropString(iDropNum, szDropString, m_lpuidDropList[iDropNum]);
		}
	}
	else if (m_lpnaeDropList)
	{
		for (ULONG iDropNum = 0; iDropNum < m_ulDropList; iDropNum++)
		{
			auto szDropString = wstring(m_lpnaeDropList[iDropNum].lpszName);
			InsertDropString(iDropNum, szDropString, m_lpnaeDropList[iDropNum].ulValue);
		}
	}

	// If this is a GUID list, load up our list of guids
	if (m_bGUID)
	{
		for (ULONG iDropNum = 0; iDropNum < ulPropGuidArray; iDropNum++)
		{
			InsertDropString(iDropNum, GUIDToStringAndName(PropGuidArray[iDropNum].lpGuid), iDropNum);
		}
	}

	m_DropDown.SetCurSel(static_cast<int>(m_iDropSelectionValue));

	m_bInitialized = true;
}

void DropDownPane::InsertDropString(int iRow, _In_ wstring szText, ULONG ulValue)
{
	m_DropDown.InsertString(iRow, wstringToCString(szText));
	m_DropDown.SetItemData(iRow, ulValue);
}

void DropDownPane::CommitUIValues()
{
	m_iDropSelection = GetDropDownSelection();
	m_iDropSelectionValue = GetDropDownSelectionValue();
	m_lpszSelectionString = GetDropStringUseControl();
	m_bInitialized = false; // must be last
}

_Check_return_ wstring DropDownPane::GetDropStringUseControl() const
{
	CString szText;
	m_DropDown.GetWindowText(szText);

	return LPCTSTRToWstring(szText);
}

// This should work whether the editor is active/displayed or not
_Check_return_ int DropDownPane::GetDropDownSelection() const
{
	if (m_bInitialized) return m_DropDown.GetCurSel();

	// In case we're being called after we're done displaying, use the stored value
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownSelectionValue() const
{
	if (m_bInitialized)
	{
		auto iSel = m_DropDown.GetCurSel();

		if (CB_ERR != iSel)
		{
			return m_DropDown.GetItemData(iSel);
		}
	}
	else
	{
		return m_iDropSelectionValue;
	}

	return 0;
}

_Check_return_ int DropDownPane::GetDropDown() const
{
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownValue() const
{
	return m_iDropSelectionValue;
}

// This should work whether the editor is active/displayed or not
_Check_return_ bool DropDownPane::GetSelectedGUID(bool bByteSwapped, _In_ LPGUID lpSelectedGUID) const
{
	if (!lpSelectedGUID) return NULL;

	auto iCurSel = GetDropDownSelection();
	if (iCurSel != CB_ERR)
	{
		memcpy(lpSelectedGUID, PropGuidArray[iCurSel].lpGuid, sizeof(GUID));
		return true;
	}

	// no match - need to do a lookup
	wstring szText;
	if (m_bInitialized)
	{
		szText = GetDropStringUseControl();
	}

	if (szText.empty())
	{
		szText = m_lpszSelectionString;
	}

	auto lpGUID = GUIDNameToGUID(szText, bByteSwapped);
	if (lpGUID)
	{
		memcpy(lpSelectedGUID, lpGUID, sizeof(GUID));
		delete[] lpGUID;
		return true;
	}

	return false;
}

void DropDownPane::SetDropDownSelection(_In_ wstring szText)
{
	auto hRes = S_OK;
	auto text = wstringToCString(szText);
	auto iSelect = m_DropDown.SelectString(0, text);

	// if we can't select, try pushing the text in there
	// not all dropdowns will support this!
	if (CB_ERR == iSelect)
	{
		EC_B(::SendMessage(
			m_DropDown.m_hWnd,
			WM_SETTEXT,
			NULL,
			reinterpret_cast<LPARAM>(static_cast<LPCTSTR>(text))));
	}
}

void DropDownPane::SetSelection(DWORD_PTR iSelection)
{
	if (!m_bInitialized)
	{
		m_iDropSelectionValue = iSelection;
	}
	else
	{
		m_DropDown.SetCurSel(static_cast<int>(iSelection));
	}
}<commit_msg>kill final CString variable<commit_after>#include "stdafx.h"
#include "DropDownPane.h"
#include "String.h"
#include "InterpretProp2.h"
#include <UIFunctions.h>

static wstring CLASS = L"DropDownPane";

ViewPane* CreateDropDownPane(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, bool bReadOnly)
{
	return new DropDownPane(uidLabel, bReadOnly, ulDropList, lpuidDropList, nullptr, false);
}

ViewPane* CreateDropDownArrayPane(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) LPNAME_ARRAY_ENTRY lpnaeDropList, bool bReadOnly)
{
	return new DropDownPane(uidLabel, bReadOnly, ulDropList, nullptr, lpnaeDropList, false);
}

ViewPane* CreateDropDownGuidPane(UINT uidLabel, bool bReadOnly)
{
	return new DropDownPane(uidLabel, bReadOnly, 0, nullptr, nullptr, true);
}

DropDownPane::DropDownPane(UINT uidLabel, bool bReadOnly, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, _In_opt_count_(ulDropList) LPNAME_ARRAY_ENTRY lpnaeDropList, bool bGUID) :ViewPane(uidLabel, bReadOnly)
{
	m_ulDropList = ulDropList;
	m_lpuidDropList = lpuidDropList;
	m_iDropSelection = CB_ERR;
	m_iDropSelectionValue = 0;
	m_lpnaeDropList = lpnaeDropList;
	m_bGUID = bGUID;
}

bool DropDownPane::IsType(__ViewTypes vType)
{
	return CTRL_DROPDOWNPANE == vType;
}

ULONG DropDownPane::GetFlags()
{
	ULONG ulFlags = vpNone;
	if (m_bReadOnly) ulFlags |= vpReadonly;
	return ulFlags;
}

wstring GetLBText(const CComboBox& box, int nIndex)
{
	auto len = box.GetLBTextLen(nIndex) + 1;
	auto buffer = new TCHAR[len];
	memset(buffer, 0, sizeof(TCHAR)* len);
	box.GetLBText(nIndex, buffer);
	auto szOut = LPCTSTRToWstring(buffer);
	delete[] buffer;
	return szOut;
}

int DropDownPane::GetMinWidth(_In_ HDC hdc)
{
	auto cxDropDown = 0;
	for (auto iDropString = 0; iDropString < m_DropDown.GetCount(); iDropString++)
	{
		SIZE sizeDrop = { 0 };
		auto szDropString = GetLBText(m_DropDown, iDropString);
		::GetTextExtentPoint32W(hdc, szDropString.c_str(), szDropString.length(), &sizeDrop);
		cxDropDown = max(cxDropDown, sizeDrop.cx);
	}

	// Add scroll bar and margins for our frame
	cxDropDown += ::GetSystemMetrics(SM_CXVSCROLL) + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);

	return max(ViewPane::GetMinWidth(hdc), cxDropDown);
}

int DropDownPane::GetFixedHeight()
{
	auto iHeight = 0;

	if (0 != m_iControl) iHeight += m_iSmallHeightMargin; // Top margin

	if (m_bUseLabelControl)
	{
		iHeight += m_iLabelHeight;
	}

	iHeight += m_iEditHeight; // Height of the dropdown

	// No bottom margin on the DropDown as it's usually tied to the following control
	return iHeight;
}

int DropDownPane::GetLines()
{
	return 0;
}

void DropDownPane::SetWindowPos(int x, int y, int width, int /*height*/)
{
	auto hRes = S_OK;
	if (0 != m_iControl)
	{
		y += m_iSmallHeightMargin;
		// height -= m_iSmallHeightMargin;
	}

	if (m_bUseLabelControl)
	{
		EC_B(m_Label.SetWindowPos(
			nullptr,
			x,
			y,
			width,
			m_iLabelHeight,
			SWP_NOZORDER));
		y += m_iLabelHeight;
		// height -= m_iLabelHeight;
	}

	EC_B(m_DropDown.SetWindowPos(NULL, x, y, width, m_iEditHeight, SWP_NOZORDER));
}

void DropDownPane::DoInit(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	auto hRes = S_OK;

	ViewPane::Initialize(iControl, pParent, hdc);

	auto ulDrops = 1 + (m_ulDropList ? min(m_ulDropList, 4) : 4);
	auto dropHeight = ulDrops * (pParent ? GetEditHeight(pParent->m_hWnd) : 0x1e);

	// m_bReadOnly means you can't type...
	DWORD dwDropStyle;
	if (m_bReadOnly)
	{
		dwDropStyle = CBS_DROPDOWNLIST; // does not allow typing
	}
	else
	{
		dwDropStyle = CBS_DROPDOWN; // allows typing
	}

	EC_B(m_DropDown.Create(
		WS_TABSTOP
		| WS_CHILD
		| WS_CLIPSIBLINGS
		| WS_BORDER
		| WS_VISIBLE
		| WS_VSCROLL
		| CBS_OWNERDRAWFIXED
		| CBS_HASSTRINGS
		| CBS_AUTOHSCROLL
		| CBS_DISABLENOSCROLL
		| dwDropStyle,
		CRect(0, 0, 0, dropHeight),
		pParent,
		m_nID));
}

void DropDownPane::Initialize(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	DoInit(iControl, pParent, hdc);

	if (m_lpuidDropList)
	{
		for (ULONG iDropNum = 0; iDropNum < m_ulDropList; iDropNum++)
		{
			auto szDropString = loadstring(m_lpuidDropList[iDropNum]);
			InsertDropString(iDropNum, szDropString, m_lpuidDropList[iDropNum]);
		}
	}
	else if (m_lpnaeDropList)
	{
		for (ULONG iDropNum = 0; iDropNum < m_ulDropList; iDropNum++)
		{
			auto szDropString = wstring(m_lpnaeDropList[iDropNum].lpszName);
			InsertDropString(iDropNum, szDropString, m_lpnaeDropList[iDropNum].ulValue);
		}
	}

	// If this is a GUID list, load up our list of guids
	if (m_bGUID)
	{
		for (ULONG iDropNum = 0; iDropNum < ulPropGuidArray; iDropNum++)
		{
			InsertDropString(iDropNum, GUIDToStringAndName(PropGuidArray[iDropNum].lpGuid), iDropNum);
		}
	}

	m_DropDown.SetCurSel(static_cast<int>(m_iDropSelectionValue));

	m_bInitialized = true;
}

void DropDownPane::InsertDropString(int iRow, _In_ wstring szText, ULONG ulValue)
{
	m_DropDown.InsertString(iRow, wstringToCString(szText));
	m_DropDown.SetItemData(iRow, ulValue);
}

void DropDownPane::CommitUIValues()
{
	m_iDropSelection = GetDropDownSelection();
	m_iDropSelectionValue = GetDropDownSelectionValue();
	m_lpszSelectionString = GetDropStringUseControl();
	m_bInitialized = false; // must be last
}

_Check_return_ wstring DropDownPane::GetDropStringUseControl() const
{
	auto len = m_DropDown.GetWindowTextLength() + 1;
	auto buffer = new WCHAR[len];
	memset(buffer, 0, sizeof(WCHAR)* len);
	::GetWindowTextW(m_DropDown.m_hWnd, buffer, len);
	wstring szOut = buffer;
	delete[] buffer;
	return szOut;
}

// This should work whether the editor is active/displayed or not
_Check_return_ int DropDownPane::GetDropDownSelection() const
{
	if (m_bInitialized) return m_DropDown.GetCurSel();

	// In case we're being called after we're done displaying, use the stored value
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownSelectionValue() const
{
	if (m_bInitialized)
	{
		auto iSel = m_DropDown.GetCurSel();

		if (CB_ERR != iSel)
		{
			return m_DropDown.GetItemData(iSel);
		}
	}
	else
	{
		return m_iDropSelectionValue;
	}

	return 0;
}

_Check_return_ int DropDownPane::GetDropDown() const
{
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownValue() const
{
	return m_iDropSelectionValue;
}

// This should work whether the editor is active/displayed or not
_Check_return_ bool DropDownPane::GetSelectedGUID(bool bByteSwapped, _In_ LPGUID lpSelectedGUID) const
{
	if (!lpSelectedGUID) return NULL;

	auto iCurSel = GetDropDownSelection();
	if (iCurSel != CB_ERR)
	{
		memcpy(lpSelectedGUID, PropGuidArray[iCurSel].lpGuid, sizeof(GUID));
		return true;
	}

	// no match - need to do a lookup
	wstring szText;
	if (m_bInitialized)
	{
		szText = GetDropStringUseControl();
	}

	if (szText.empty())
	{
		szText = m_lpszSelectionString;
	}

	auto lpGUID = GUIDNameToGUID(szText, bByteSwapped);
	if (lpGUID)
	{
		memcpy(lpSelectedGUID, lpGUID, sizeof(GUID));
		delete[] lpGUID;
		return true;
	}

	return false;
}

void DropDownPane::SetDropDownSelection(_In_ wstring szText)
{
	auto hRes = S_OK;
	auto text = wstringToCString(szText);
	auto iSelect = m_DropDown.SelectString(0, text);

	// if we can't select, try pushing the text in there
	// not all dropdowns will support this!
	if (CB_ERR == iSelect)
	{
		EC_B(::SendMessage(
			m_DropDown.m_hWnd,
			WM_SETTEXT,
			NULL,
			reinterpret_cast<LPARAM>(static_cast<LPCTSTR>(text))));
	}
}

void DropDownPane::SetSelection(DWORD_PTR iSelection)
{
	if (!m_bInitialized)
	{
		m_iDropSelectionValue = iSelection;
	}
	else
	{
		m_DropDown.SetCurSel(static_cast<int>(iSelection));
	}
}<|endoftext|>


<commit_before>#include "stdafx.h"
#include "DropDownPane.h"
#include "String.h"
#include "InterpretProp2.h"
#include <UIFunctions.h>

static wstring CLASS = L"DropDownPane";

DropDownPane* DropDownPane::Create(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane && lpuidDropList)
	{
		for (ULONG iDropNum = 0; iDropNum < ulDropList; iDropNum++)
		{
			pane->InsertDropString(loadstring(lpuidDropList[iDropNum]), lpuidDropList[iDropNum]);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane* DropDownPane::CreateGuid(UINT uidLabel, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane)
	{
		for (ULONG iDropNum = 0; iDropNum < PropGuidArray.size(); iDropNum++)
		{
			pane->InsertDropString(GUIDToStringAndName(PropGuidArray[iDropNum].lpGuid), iDropNum);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane::DropDownPane()
{
	m_iDropSelection = CB_ERR;
	m_iDropSelectionValue = 0;
}

int DropDownPane::GetMinWidth(_In_ HDC hdc)
{
	auto cxDropDown = 0;
	for (auto iDropString = 0; iDropString < m_DropDown.GetCount(); iDropString++)
	{
		auto szDropString = GetLBText(m_DropDown.m_hWnd, iDropString);
		auto sizeDrop = GetTextExtentPoint32(hdc, szDropString);
		cxDropDown = max(cxDropDown, sizeDrop.cx);
	}

	// Add scroll bar and margins for our frame
	cxDropDown += GetSystemMetrics(SM_CXVSCROLL) + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);

	return max(ViewPane::GetMinWidth(hdc), cxDropDown);
}

int DropDownPane::GetFixedHeight()
{
	auto iHeight = 0;

	if (0 != m_iControl) iHeight += m_iSmallHeightMargin; // Top margin

	if (!m_szLabel.empty())
	{
		iHeight += m_iLabelHeight;
	}

	iHeight += m_iEditHeight; // Height of the dropdown

	iHeight += m_iLargeHeightMargin; // Bottom margin

	return iHeight;
}

void DropDownPane::SetWindowPos(int x, int y, int width, int /*height*/)
{
	auto hRes = S_OK;
	if (0 != m_iControl)
	{
		y += m_iSmallHeightMargin;
	}

	if (!m_szLabel.empty())
	{
		EC_B(m_Label.SetWindowPos(
			nullptr,
			x,
			y,
			width,
			m_iLabelHeight,
			SWP_NOZORDER));
		y += m_iLabelHeight;
	}

	// Note - Real height of a combo box is fixed at m_iEditHeight
	// Height we set here influences the amount of dropdown entries we see
	// This will give us something between 4 and 10 entries
	ULONG ulDrops = min(10, 1 + max(m_DropList.size(), 4));

	EC_B(m_DropDown.SetWindowPos(NULL, x, y, width, m_iEditHeight * ulDrops, SWP_NOZORDER));
}

void DropDownPane::CreateControl(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	auto hRes = S_OK;

	ViewPane::Initialize(iControl, pParent, hdc);

	auto ulDrops = 1 + (m_DropList.size() ? min(m_DropList.size(), 4) : 4);
	auto dropHeight = ulDrops * (pParent ? GetEditHeight(pParent->m_hWnd) : 0x1e);

	// m_bReadOnly means you can't type...
	DWORD dwDropStyle;
	if (m_bReadOnly)
	{
		dwDropStyle = CBS_DROPDOWNLIST; // does not allow typing
	}
	else
	{
		dwDropStyle = CBS_DROPDOWN; // allows typing
	}

	EC_B(m_DropDown.Create(
		WS_TABSTOP
		| WS_CHILD
		| WS_CLIPSIBLINGS
		| WS_BORDER
		| WS_VISIBLE
		| WS_VSCROLL
		| CBS_OWNERDRAWFIXED
		| CBS_HASSTRINGS
		| CBS_AUTOHSCROLL
		| CBS_DISABLENOSCROLL
		| CBS_NOINTEGRALHEIGHT
		| dwDropStyle,
		CRect(0, 0, 0, static_cast<int>(dropHeight)),
		pParent,
		m_nID));

	SendMessage(m_DropDown.m_hWnd, WM_SETFONT, reinterpret_cast<WPARAM>(GetSegoeFont()), false);
}

void DropDownPane::Initialize(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	CreateControl(iControl, pParent, hdc);

	auto iDropNum = 0;
	for (const auto& drop : m_DropList)
	{
		m_DropDown.InsertString(iDropNum, wstringTotstring(drop.first).c_str());
		m_DropDown.SetItemData(iDropNum, drop.second);
		iDropNum++;
	}

	m_DropDown.SetCurSel(static_cast<int>(m_iDropSelectionValue));

	m_bInitialized = true;
	SetDropDownSelection(m_lpszSelectionString);
}

void DropDownPane::InsertDropString(_In_ const wstring& szText, ULONG ulValue)
{
	m_DropList.push_back({ szText, ulValue });
}

void DropDownPane::CommitUIValues()
{
	m_iDropSelection = GetDropDownSelection();
	m_iDropSelectionValue = GetDropDownSelectionValue();
	m_lpszSelectionString = GetDropStringUseControl();
	m_bInitialized = false; // must be last
}

_Check_return_ wstring DropDownPane::GetDropStringUseControl() const
{
	auto len = m_DropDown.GetWindowTextLength() + 1;
	auto buffer = new WCHAR[len];
	memset(buffer, 0, sizeof(WCHAR)* len);
	GetWindowTextW(m_DropDown.m_hWnd, buffer, len);
	wstring szOut = buffer;
	delete[] buffer;
	return szOut;
}

// This should work whether the editor is active/displayed or not
_Check_return_ int DropDownPane::GetDropDownSelection() const
{
	if (m_bInitialized) return m_DropDown.GetCurSel();

	// In case we're being called after we're done displaying, use the stored value
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownSelectionValue() const
{
	if (m_bInitialized)
	{
		auto iSel = m_DropDown.GetCurSel();

		if (CB_ERR != iSel)
		{
			return m_DropDown.GetItemData(iSel);
		}
	}
	else
	{
		return m_iDropSelectionValue;
	}

	return 0;
}

_Check_return_ int DropDownPane::GetDropDown() const
{
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownValue() const
{
	return m_iDropSelectionValue;
}

// This should work whether the editor is active/displayed or not
_Check_return_ GUID DropDownPane::GetSelectedGUID(bool bByteSwapped) const
{
	auto iCurSel = GetDropDownSelection();
	if (iCurSel != CB_ERR)
	{
		return *PropGuidArray[iCurSel].lpGuid;
	}

	// no match - need to do a lookup
	wstring szText;
	if (m_bInitialized)
	{
		szText = GetDropStringUseControl();
	}

	if (szText.empty())
	{
		szText = m_lpszSelectionString;
	}

	auto lpGUID = GUIDNameToGUID(szText, bByteSwapped);
	if (lpGUID)
	{
		auto guid = *lpGUID;
		delete[] lpGUID;
		return guid;
	}

	return{ 0 };
}

void DropDownPane::SetDropDownSelection(_In_ const wstring& szText)
{
	m_lpszSelectionString = szText;
	if (!m_bInitialized) return;

	auto hRes = S_OK;
	auto text = wstringTotstring(m_lpszSelectionString);
	auto iSelect = m_DropDown.SelectString(0, text.c_str());

	// if we can't select, try pushing the text in there
	// not all dropdowns will support this!
	if (CB_ERR == iSelect)
	{
		EC_B(::SendMessage(
			m_DropDown.m_hWnd,
			WM_SETTEXT,
			NULL,
			reinterpret_cast<LPARAM>(static_cast<LPCTSTR>(text.c_str()))));
	}
}

void DropDownPane::SetSelection(DWORD_PTR iSelection)
{
	if (!m_bInitialized)
	{
		m_iDropSelectionValue = iSelection;
	}
	else
	{
		m_DropDown.SetCurSel(static_cast<int>(iSelection));
	}
}<commit_msg>Use better type for unicode<commit_after>#include "stdafx.h"
#include "DropDownPane.h"
#include "String.h"
#include "InterpretProp2.h"
#include <UIFunctions.h>

static wstring CLASS = L"DropDownPane";

DropDownPane* DropDownPane::Create(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane && lpuidDropList)
	{
		for (ULONG iDropNum = 0; iDropNum < ulDropList; iDropNum++)
		{
			pane->InsertDropString(loadstring(lpuidDropList[iDropNum]), lpuidDropList[iDropNum]);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane* DropDownPane::CreateGuid(UINT uidLabel, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane)
	{
		for (ULONG iDropNum = 0; iDropNum < PropGuidArray.size(); iDropNum++)
		{
			pane->InsertDropString(GUIDToStringAndName(PropGuidArray[iDropNum].lpGuid), iDropNum);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane::DropDownPane()
{
	m_iDropSelection = CB_ERR;
	m_iDropSelectionValue = 0;
}

int DropDownPane::GetMinWidth(_In_ HDC hdc)
{
	auto cxDropDown = 0;
	for (auto iDropString = 0; iDropString < m_DropDown.GetCount(); iDropString++)
	{
		auto szDropString = GetLBText(m_DropDown.m_hWnd, iDropString);
		auto sizeDrop = GetTextExtentPoint32(hdc, szDropString);
		cxDropDown = max(cxDropDown, sizeDrop.cx);
	}

	// Add scroll bar and margins for our frame
	cxDropDown += GetSystemMetrics(SM_CXVSCROLL) + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);

	return max(ViewPane::GetMinWidth(hdc), cxDropDown);
}

int DropDownPane::GetFixedHeight()
{
	auto iHeight = 0;

	if (0 != m_iControl) iHeight += m_iSmallHeightMargin; // Top margin

	if (!m_szLabel.empty())
	{
		iHeight += m_iLabelHeight;
	}

	iHeight += m_iEditHeight; // Height of the dropdown

	iHeight += m_iLargeHeightMargin; // Bottom margin

	return iHeight;
}

void DropDownPane::SetWindowPos(int x, int y, int width, int /*height*/)
{
	auto hRes = S_OK;
	if (0 != m_iControl)
	{
		y += m_iSmallHeightMargin;
	}

	if (!m_szLabel.empty())
	{
		EC_B(m_Label.SetWindowPos(
			nullptr,
			x,
			y,
			width,
			m_iLabelHeight,
			SWP_NOZORDER));
		y += m_iLabelHeight;
	}

	// Note - Real height of a combo box is fixed at m_iEditHeight
	// Height we set here influences the amount of dropdown entries we see
	// This will give us something between 4 and 10 entries
	auto ulDrops = static_cast<int>(min(10, 1 + max(m_DropList.size(), 4)));

	EC_B(m_DropDown.SetWindowPos(NULL, x, y, width, m_iEditHeight * ulDrops, SWP_NOZORDER));
}

void DropDownPane::CreateControl(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	auto hRes = S_OK;

	ViewPane::Initialize(iControl, pParent, hdc);

	auto ulDrops = 1 + (m_DropList.size() ? min(m_DropList.size(), 4) : 4);
	auto dropHeight = ulDrops * (pParent ? GetEditHeight(pParent->m_hWnd) : 0x1e);

	// m_bReadOnly means you can't type...
	DWORD dwDropStyle;
	if (m_bReadOnly)
	{
		dwDropStyle = CBS_DROPDOWNLIST; // does not allow typing
	}
	else
	{
		dwDropStyle = CBS_DROPDOWN; // allows typing
	}

	EC_B(m_DropDown.Create(
		WS_TABSTOP
		| WS_CHILD
		| WS_CLIPSIBLINGS
		| WS_BORDER
		| WS_VISIBLE
		| WS_VSCROLL
		| CBS_OWNERDRAWFIXED
		| CBS_HASSTRINGS
		| CBS_AUTOHSCROLL
		| CBS_DISABLENOSCROLL
		| CBS_NOINTEGRALHEIGHT
		| dwDropStyle,
		CRect(0, 0, 0, static_cast<int>(dropHeight)),
		pParent,
		m_nID));

	SendMessage(m_DropDown.m_hWnd, WM_SETFONT, reinterpret_cast<WPARAM>(GetSegoeFont()), false);
}

void DropDownPane::Initialize(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	CreateControl(iControl, pParent, hdc);

	auto iDropNum = 0;
	for (const auto& drop : m_DropList)
	{
		m_DropDown.InsertString(iDropNum, wstringTotstring(drop.first).c_str());
		m_DropDown.SetItemData(iDropNum, drop.second);
		iDropNum++;
	}

	m_DropDown.SetCurSel(static_cast<int>(m_iDropSelectionValue));

	m_bInitialized = true;
	SetDropDownSelection(m_lpszSelectionString);
}

void DropDownPane::InsertDropString(_In_ const wstring& szText, ULONG ulValue)
{
	m_DropList.push_back({ szText, ulValue });
}

void DropDownPane::CommitUIValues()
{
	m_iDropSelection = GetDropDownSelection();
	m_iDropSelectionValue = GetDropDownSelectionValue();
	m_lpszSelectionString = GetDropStringUseControl();
	m_bInitialized = false; // must be last
}

_Check_return_ wstring DropDownPane::GetDropStringUseControl() const
{
	auto len = m_DropDown.GetWindowTextLength() + 1;
	auto buffer = new WCHAR[len];
	memset(buffer, 0, sizeof(WCHAR)* len);
	GetWindowTextW(m_DropDown.m_hWnd, buffer, len);
	wstring szOut = buffer;
	delete[] buffer;
	return szOut;
}

// This should work whether the editor is active/displayed or not
_Check_return_ int DropDownPane::GetDropDownSelection() const
{
	if (m_bInitialized) return m_DropDown.GetCurSel();

	// In case we're being called after we're done displaying, use the stored value
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownSelectionValue() const
{
	if (m_bInitialized)
	{
		auto iSel = m_DropDown.GetCurSel();

		if (CB_ERR != iSel)
		{
			return m_DropDown.GetItemData(iSel);
		}
	}
	else
	{
		return m_iDropSelectionValue;
	}

	return 0;
}

_Check_return_ int DropDownPane::GetDropDown() const
{
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownValue() const
{
	return m_iDropSelectionValue;
}

// This should work whether the editor is active/displayed or not
_Check_return_ GUID DropDownPane::GetSelectedGUID(bool bByteSwapped) const
{
	auto iCurSel = GetDropDownSelection();
	if (iCurSel != CB_ERR)
	{
		return *PropGuidArray[iCurSel].lpGuid;
	}

	// no match - need to do a lookup
	wstring szText;
	if (m_bInitialized)
	{
		szText = GetDropStringUseControl();
	}

	if (szText.empty())
	{
		szText = m_lpszSelectionString;
	}

	auto lpGUID = GUIDNameToGUID(szText, bByteSwapped);
	if (lpGUID)
	{
		auto guid = *lpGUID;
		delete[] lpGUID;
		return guid;
	}

	return{ 0 };
}

void DropDownPane::SetDropDownSelection(_In_ const wstring& szText)
{
	m_lpszSelectionString = szText;
	if (!m_bInitialized) return;

	auto hRes = S_OK;
	auto text = wstringTotstring(m_lpszSelectionString);
	auto iSelect = m_DropDown.SelectString(0, text.c_str());

	// if we can't select, try pushing the text in there
	// not all dropdowns will support this!
	if (CB_ERR == iSelect)
	{
		EC_B(::SendMessage(
			m_DropDown.m_hWnd,
			WM_SETTEXT,
			NULL,
			reinterpret_cast<LPARAM>(static_cast<LPCTSTR>(text.c_str()))));
	}
}

void DropDownPane::SetSelection(DWORD_PTR iSelection)
{
	if (!m_bInitialized)
	{
		m_iDropSelectionValue = iSelection;
	}
	else
	{
		m_DropDown.SetCurSel(static_cast<int>(iSelection));
	}
}<|endoftext|>


<commit_before>#include "stdafx.h"
#include "DropDownPane.h"
#include "String.h"
#include "InterpretProp2.h"
#include <UIFunctions.h>

static wstring CLASS = L"DropDownPane";

DropDownPane* DropDownPane::Create(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane)
	{
		for (ULONG iDropNum = 0; iDropNum < ulDropList; iDropNum++)
		{
			pane->InsertDropString(loadstring(lpuidDropList[iDropNum]), lpuidDropList[iDropNum]);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane* DropDownPane::CreateGuid(UINT uidLabel, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane)
	{
		for (ULONG iDropNum = 0; iDropNum < PropGuidArray.size(); iDropNum++)
		{
			pane->InsertDropString(GUIDToStringAndName(PropGuidArray[iDropNum].lpGuid), iDropNum);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane::DropDownPane()
{
	m_iDropSelection = CB_ERR;
	m_iDropSelectionValue = 0;
}

bool DropDownPane::IsType(__ViewTypes vType)
{
	return CTRL_DROPDOWNPANE == vType;
}

ULONG DropDownPane::GetFlags()
{
	ULONG ulFlags = vpNone;
	if (m_bReadOnly) ulFlags |= vpReadonly;
	return ulFlags;
}

int DropDownPane::GetMinWidth(_In_ HDC hdc)
{
	auto cxDropDown = 0;
	for (auto iDropString = 0; iDropString < m_DropDown.GetCount(); iDropString++)
	{
		auto szDropString = GetLBText(m_DropDown.m_hWnd, iDropString);
		auto sizeDrop = GetTextExtentPoint32(hdc, szDropString);
		cxDropDown = max(cxDropDown, sizeDrop.cx);
	}

	// Add scroll bar and margins for our frame
	cxDropDown += ::GetSystemMetrics(SM_CXVSCROLL) + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);

	return max(ViewPane::GetMinWidth(hdc), cxDropDown);
}

int DropDownPane::GetFixedHeight()
{
	auto iHeight = 0;

	if (0 != m_iControl) iHeight += m_iSmallHeightMargin; // Top margin

	if (m_bUseLabelControl)
	{
		iHeight += m_iLabelHeight;
	}

	iHeight += m_iEditHeight; // Height of the dropdown

	// No bottom margin on the DropDown as it's usually tied to the following control
	return iHeight;
}

int DropDownPane::GetLines()
{
	return 0;
}

void DropDownPane::SetWindowPos(int x, int y, int width, int /*height*/)
{
	auto hRes = S_OK;
	if (0 != m_iControl)
	{
		y += m_iSmallHeightMargin;
		// height -= m_iSmallHeightMargin;
	}

	if (m_bUseLabelControl)
	{
		EC_B(m_Label.SetWindowPos(
			nullptr,
			x,
			y,
			width,
			m_iLabelHeight,
			SWP_NOZORDER));
		y += m_iLabelHeight;
		// height -= m_iLabelHeight;
	}

	EC_B(m_DropDown.SetWindowPos(NULL, x, y, width, m_iEditHeight, SWP_NOZORDER));
}

void DropDownPane::CreateControl(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	auto hRes = S_OK;

	ViewPane::Initialize(iControl, pParent, hdc);

	auto ulDrops = 1 + (m_DropList.size() ? min(m_DropList.size(), 4) : 4);
	auto dropHeight = ulDrops * (pParent ? GetEditHeight(pParent->m_hWnd) : 0x1e);

	// m_bReadOnly means you can't type...
	DWORD dwDropStyle;
	if (m_bReadOnly)
	{
		dwDropStyle = CBS_DROPDOWNLIST; // does not allow typing
	}
	else
	{
		dwDropStyle = CBS_DROPDOWN; // allows typing
	}

	EC_B(m_DropDown.Create(
		WS_TABSTOP
		| WS_CHILD
		| WS_CLIPSIBLINGS
		| WS_BORDER
		| WS_VISIBLE
		| WS_VSCROLL
		| CBS_OWNERDRAWFIXED
		| CBS_HASSTRINGS
		| CBS_AUTOHSCROLL
		| CBS_DISABLENOSCROLL
		| dwDropStyle,
		CRect(0, 0, 0, dropHeight),
		pParent,
		m_nID));
}

void DropDownPane::Initialize(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	CreateControl(iControl, pParent, hdc);

	auto iDropNum = 0;
	for (auto drop : m_DropList)
	{
		m_DropDown.InsertString(iDropNum, wstringTotstring(drop.first).c_str());
		m_DropDown.SetItemData(iDropNum, drop.second);
		iDropNum++;
	}

	m_DropDown.SetCurSel(static_cast<int>(m_iDropSelectionValue));

	m_bInitialized = true;
}

void DropDownPane::InsertDropString(_In_ const wstring& szText, ULONG ulValue)
{
	m_DropList.push_back({ szText, ulValue });
}

void DropDownPane::CommitUIValues()
{
	m_iDropSelection = GetDropDownSelection();
	m_iDropSelectionValue = GetDropDownSelectionValue();
	m_lpszSelectionString = GetDropStringUseControl();
	m_bInitialized = false; // must be last
}

_Check_return_ wstring DropDownPane::GetDropStringUseControl() const
{
	auto len = m_DropDown.GetWindowTextLength() + 1;
	auto buffer = new WCHAR[len];
	memset(buffer, 0, sizeof(WCHAR)* len);
	::GetWindowTextW(m_DropDown.m_hWnd, buffer, len);
	wstring szOut = buffer;
	delete[] buffer;
	return szOut;
}

// This should work whether the editor is active/displayed or not
_Check_return_ int DropDownPane::GetDropDownSelection() const
{
	if (m_bInitialized) return m_DropDown.GetCurSel();

	// In case we're being called after we're done displaying, use the stored value
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownSelectionValue() const
{
	if (m_bInitialized)
	{
		auto iSel = m_DropDown.GetCurSel();

		if (CB_ERR != iSel)
		{
			return m_DropDown.GetItemData(iSel);
		}
	}
	else
	{
		return m_iDropSelectionValue;
	}

	return 0;
}

_Check_return_ int DropDownPane::GetDropDown() const
{
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownValue() const
{
	return m_iDropSelectionValue;
}

// This should work whether the editor is active/displayed or not
_Check_return_ GUID DropDownPane::GetSelectedGUID(bool bByteSwapped) const
{
	auto iCurSel = GetDropDownSelection();
	if (iCurSel != CB_ERR)
	{
		return *PropGuidArray[iCurSel].lpGuid;
	}

	// no match - need to do a lookup
	wstring szText;
	if (m_bInitialized)
	{
		szText = GetDropStringUseControl();
	}

	if (szText.empty())
	{
		szText = m_lpszSelectionString;
	}

	auto lpGUID = GUIDNameToGUID(szText, bByteSwapped);
	if (lpGUID)
	{
		auto guid = *lpGUID;
		delete[] lpGUID;
		return guid;
	}

	return{ 0 };
}

void DropDownPane::SetDropDownSelection(_In_ const wstring& szText)
{
	auto hRes = S_OK;
	auto text = wstringTotstring(szText);
	auto iSelect = m_DropDown.SelectString(0, text.c_str());

	// if we can't select, try pushing the text in there
	// not all dropdowns will support this!
	if (CB_ERR == iSelect)
	{
		EC_B(::SendMessage(
			m_DropDown.m_hWnd,
			WM_SETTEXT,
			NULL,
			reinterpret_cast<LPARAM>(static_cast<LPCTSTR>(text.c_str()))));
	}
}

void DropDownPane::SetSelection(DWORD_PTR iSelection)
{
	if (!m_bInitialized)
	{
		m_iDropSelectionValue = iSelection;
	}
	else
	{
		m_DropDown.SetCurSel(static_cast<int>(iSelection));
	}
}<commit_msg>Casting issue<commit_after>#include "stdafx.h"
#include "DropDownPane.h"
#include "String.h"
#include "InterpretProp2.h"
#include <UIFunctions.h>

static wstring CLASS = L"DropDownPane";

DropDownPane* DropDownPane::Create(UINT uidLabel, ULONG ulDropList, _In_opt_count_(ulDropList) UINT* lpuidDropList, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane)
	{
		for (ULONG iDropNum = 0; iDropNum < ulDropList; iDropNum++)
		{
			pane->InsertDropString(loadstring(lpuidDropList[iDropNum]), lpuidDropList[iDropNum]);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane* DropDownPane::CreateGuid(UINT uidLabel, bool bReadOnly)
{
	auto pane = new DropDownPane();
	if (pane)
	{
		for (ULONG iDropNum = 0; iDropNum < PropGuidArray.size(); iDropNum++)
		{
			pane->InsertDropString(GUIDToStringAndName(PropGuidArray[iDropNum].lpGuid), iDropNum);
		}

		pane->SetLabel(uidLabel, bReadOnly);
	}

	return pane;
}

DropDownPane::DropDownPane()
{
	m_iDropSelection = CB_ERR;
	m_iDropSelectionValue = 0;
}

bool DropDownPane::IsType(__ViewTypes vType)
{
	return CTRL_DROPDOWNPANE == vType;
}

ULONG DropDownPane::GetFlags()
{
	ULONG ulFlags = vpNone;
	if (m_bReadOnly) ulFlags |= vpReadonly;
	return ulFlags;
}

int DropDownPane::GetMinWidth(_In_ HDC hdc)
{
	auto cxDropDown = 0;
	for (auto iDropString = 0; iDropString < m_DropDown.GetCount(); iDropString++)
	{
		auto szDropString = GetLBText(m_DropDown.m_hWnd, iDropString);
		auto sizeDrop = GetTextExtentPoint32(hdc, szDropString);
		cxDropDown = max(cxDropDown, sizeDrop.cx);
	}

	// Add scroll bar and margins for our frame
	cxDropDown += ::GetSystemMetrics(SM_CXVSCROLL) + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);

	return max(ViewPane::GetMinWidth(hdc), cxDropDown);
}

int DropDownPane::GetFixedHeight()
{
	auto iHeight = 0;

	if (0 != m_iControl) iHeight += m_iSmallHeightMargin; // Top margin

	if (m_bUseLabelControl)
	{
		iHeight += m_iLabelHeight;
	}

	iHeight += m_iEditHeight; // Height of the dropdown

	// No bottom margin on the DropDown as it's usually tied to the following control
	return iHeight;
}

int DropDownPane::GetLines()
{
	return 0;
}

void DropDownPane::SetWindowPos(int x, int y, int width, int /*height*/)
{
	auto hRes = S_OK;
	if (0 != m_iControl)
	{
		y += m_iSmallHeightMargin;
		// height -= m_iSmallHeightMargin;
	}

	if (m_bUseLabelControl)
	{
		EC_B(m_Label.SetWindowPos(
			nullptr,
			x,
			y,
			width,
			m_iLabelHeight,
			SWP_NOZORDER));
		y += m_iLabelHeight;
		// height -= m_iLabelHeight;
	}

	EC_B(m_DropDown.SetWindowPos(NULL, x, y, width, m_iEditHeight, SWP_NOZORDER));
}

void DropDownPane::CreateControl(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	auto hRes = S_OK;

	ViewPane::Initialize(iControl, pParent, hdc);

	auto ulDrops = 1 + (m_DropList.size() ? min(m_DropList.size(), 4) : 4);
	auto dropHeight = ulDrops * (pParent ? GetEditHeight(pParent->m_hWnd) : 0x1e);

	// m_bReadOnly means you can't type...
	DWORD dwDropStyle;
	if (m_bReadOnly)
	{
		dwDropStyle = CBS_DROPDOWNLIST; // does not allow typing
	}
	else
	{
		dwDropStyle = CBS_DROPDOWN; // allows typing
	}

	EC_B(m_DropDown.Create(
		WS_TABSTOP
		| WS_CHILD
		| WS_CLIPSIBLINGS
		| WS_BORDER
		| WS_VISIBLE
		| WS_VSCROLL
		| CBS_OWNERDRAWFIXED
		| CBS_HASSTRINGS
		| CBS_AUTOHSCROLL
		| CBS_DISABLENOSCROLL
		| dwDropStyle,
		CRect(0, 0, 0, static_cast<int>(dropHeight)),
		pParent,
		m_nID));
}

void DropDownPane::Initialize(int iControl, _In_ CWnd* pParent, _In_ HDC hdc)
{
	CreateControl(iControl, pParent, hdc);

	auto iDropNum = 0;
	for (auto drop : m_DropList)
	{
		m_DropDown.InsertString(iDropNum, wstringTotstring(drop.first).c_str());
		m_DropDown.SetItemData(iDropNum, drop.second);
		iDropNum++;
	}

	m_DropDown.SetCurSel(static_cast<int>(m_iDropSelectionValue));

	m_bInitialized = true;
}

void DropDownPane::InsertDropString(_In_ const wstring& szText, ULONG ulValue)
{
	m_DropList.push_back({ szText, ulValue });
}

void DropDownPane::CommitUIValues()
{
	m_iDropSelection = GetDropDownSelection();
	m_iDropSelectionValue = GetDropDownSelectionValue();
	m_lpszSelectionString = GetDropStringUseControl();
	m_bInitialized = false; // must be last
}

_Check_return_ wstring DropDownPane::GetDropStringUseControl() const
{
	auto len = m_DropDown.GetWindowTextLength() + 1;
	auto buffer = new WCHAR[len];
	memset(buffer, 0, sizeof(WCHAR)* len);
	::GetWindowTextW(m_DropDown.m_hWnd, buffer, len);
	wstring szOut = buffer;
	delete[] buffer;
	return szOut;
}

// This should work whether the editor is active/displayed or not
_Check_return_ int DropDownPane::GetDropDownSelection() const
{
	if (m_bInitialized) return m_DropDown.GetCurSel();

	// In case we're being called after we're done displaying, use the stored value
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownSelectionValue() const
{
	if (m_bInitialized)
	{
		auto iSel = m_DropDown.GetCurSel();

		if (CB_ERR != iSel)
		{
			return m_DropDown.GetItemData(iSel);
		}
	}
	else
	{
		return m_iDropSelectionValue;
	}

	return 0;
}

_Check_return_ int DropDownPane::GetDropDown() const
{
	return m_iDropSelection;
}

_Check_return_ DWORD_PTR DropDownPane::GetDropDownValue() const
{
	return m_iDropSelectionValue;
}

// This should work whether the editor is active/displayed or not
_Check_return_ GUID DropDownPane::GetSelectedGUID(bool bByteSwapped) const
{
	auto iCurSel = GetDropDownSelection();
	if (iCurSel != CB_ERR)
	{
		return *PropGuidArray[iCurSel].lpGuid;
	}

	// no match - need to do a lookup
	wstring szText;
	if (m_bInitialized)
	{
		szText = GetDropStringUseControl();
	}

	if (szText.empty())
	{
		szText = m_lpszSelectionString;
	}

	auto lpGUID = GUIDNameToGUID(szText, bByteSwapped);
	if (lpGUID)
	{
		auto guid = *lpGUID;
		delete[] lpGUID;
		return guid;
	}

	return{ 0 };
}

void DropDownPane::SetDropDownSelection(_In_ const wstring& szText)
{
	auto hRes = S_OK;
	auto text = wstringTotstring(szText);
	auto iSelect = m_DropDown.SelectString(0, text.c_str());

	// if we can't select, try pushing the text in there
	// not all dropdowns will support this!
	if (CB_ERR == iSelect)
	{
		EC_B(::SendMessage(
			m_DropDown.m_hWnd,
			WM_SETTEXT,
			NULL,
			reinterpret_cast<LPARAM>(static_cast<LPCTSTR>(text.c_str()))));
	}
}

void DropDownPane::SetSelection(DWORD_PTR iSelection)
{
	if (!m_bInitialized)
	{
		m_iDropSelectionValue = iSelection;
	}
	else
	{
		m_DropDown.SetCurSel(static_cast<int>(iSelection));
	}
}<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <memory>

#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h"  // from @flatbuffers
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate_kernel.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate_mock_test.h"
#include "tensorflow/lite/experimental/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/experimental/acceleration/configuration/delegate_registry.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/test_util.h"

// Tests for checking that the NNAPI Delegate plugin correctly handles all the
// options from the flatbuffer.
//
// Checking done at NNAPI call level, as that is where we have a mockable
// layer.
namespace tflite {
namespace {

using delegate::nnapi::NnApiMock;

class SingleAddOpModel : tflite::SingleOpModel {
 public:
  void Build() {
    int input = AddInput({tflite::TensorType_FLOAT32, {1, 2, 2}});
    int constant = AddConstInput({tflite::TensorType_FLOAT32, {1, 2, 2}},
                                 {1.0f, 1.0f, 1.0f, 1.0f});
    AddOutput({tflite::TensorType_FLOAT32, {}});

    SetBuiltinOp(tflite::BuiltinOperator_ADD, tflite::BuiltinOptions_AddOptions,
                 tflite::CreateAddOptions(builder_).Union());
    BuildInterpreter({GetShape(input), GetShape(constant)});
  }

  tflite::Interpreter* Interpreter() const { return interpreter_.get(); }
};

class NNAPIPluginTest : public ::testing::Test {
 protected:
  NNAPIPluginTest() : delegate_(nullptr, [](TfLiteDelegate*) {}) {}
  void SetUp() override {
    nnapi_ = const_cast<NnApi*>(NnApiImplementation());
    nnapi_mock_ = absl::make_unique<NnApiMock>(nnapi_);
    nnapi_->ANeuralNetworksModel_getSupportedOperationsForDevices =
        [](const ANeuralNetworksModel* model,
           const ANeuralNetworksDevice* const* devices, uint32_t numDevices,
           bool* supportedOps) -> int {
      supportedOps[0] = true;
      return 0;
    };
    model_.Build();
  }
  template <NNAPIExecutionPreference input, int output>
  void CheckExecutionPreference() {
    // Note - this uses a template since the NNAPI functions are C function
    // pointers rather than lambdas so can't capture variables.
    nnapi_->ANeuralNetworksCompilation_setPreference =
        [](ANeuralNetworksCompilation* compilation, int32_t preference) {
          return preference - output;
        };
    CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0, input));
    // Since delegation succeeds, the model becomes immutable and hence can't
    // reuse it.
    SingleAddOpModel model;
    model.Build();
    EXPECT_EQ(model.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
              kTfLiteOk)
        << " given input: " << input << " expected output: " << output;
  }
  template <NNAPIExecutionPriority input, int output>
  void CheckExecutionPriority() {
    // Note - this uses a template since the NNAPI functions are C function
    // pointers rather than lambdas so can't capture variables.
    nnapi_->ANeuralNetworksCompilation_setPriority =
        [](ANeuralNetworksCompilation* compilation, int32_t priority) {
          return priority - output;
        };
    CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0,
                                       NNAPIExecutionPreference_UNDEFINED, 0, 0,
                                       /*allow CPU=*/true, input));
    // Since delegation succeeds, the model becomes immutable and hence can't
    // reuse it.
    SingleAddOpModel model;
    model.Build();
    EXPECT_EQ(model.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
              kTfLiteOk)
        << " given input: " << input << " expected output: " << output;
  }

  void CreateDelegate(flatbuffers::Offset<NNAPISettings> settings) {
    settings_ = flatbuffers::GetTemporaryPointer(
        fbb_, CreateTFLiteSettings(fbb_, tflite::Delegate_NNAPI, settings));

    plugin_ = delegates::DelegatePluginRegistry::CreateByName("NnapiPlugin",
                                                              *settings_);
    delegate_ = plugin_->Create();
  }

  NnApi* nnapi_;
  std::unique_ptr<NnApiMock> nnapi_mock_;
  SingleAddOpModel model_;
  flatbuffers::FlatBufferBuilder fbb_;
  const TFLiteSettings* settings_ = nullptr;
  delegates::TfLiteDelegatePtr delegate_;
  std::unique_ptr<delegates::DelegatePluginInterface> plugin_;
};

TEST_F(NNAPIPluginTest, PassesAcceleratorName) {
  // Fails with non-existent "foo".
  CreateDelegate(CreateNNAPISettings(fbb_, fbb_.CreateString("foo")));
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteDelegateError);

  // Succeeds with "test-device" supported by the mock.
  CreateDelegate(CreateNNAPISettings(fbb_, fbb_.CreateString("test-device")));
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

TEST_F(NNAPIPluginTest, PassesExecutionPreference) {
  CheckExecutionPreference<NNAPIExecutionPreference_UNDEFINED,
                           StatefulNnApiDelegate::Options::kUndefined>();
  CheckExecutionPreference<NNAPIExecutionPreference_NNAPI_LOW_POWER,
                           StatefulNnApiDelegate::Options::kLowPower>();
  CheckExecutionPreference<NNAPIExecutionPreference_NNAPI_FAST_SINGLE_ANSWER,
                           StatefulNnApiDelegate::Options::kFastSingleAnswer>();
  CheckExecutionPreference<NNAPIExecutionPreference_NNAPI_SUSTAINED_SPEED,
                           StatefulNnApiDelegate::Options::kSustainedSpeed>();
}

TEST_F(NNAPIPluginTest, PassesExecutionPriority) {
  nnapi_->android_sdk_version =
      tflite::delegate::nnapi::kMinSdkVersionForNNAPI13;
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED,
                         ANEURALNETWORKS_PRIORITY_DEFAULT>();
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_LOW,
                         ANEURALNETWORKS_PRIORITY_LOW>();
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_MEDIUM,
                         ANEURALNETWORKS_PRIORITY_MEDIUM>();
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_HIGH,
                         ANEURALNETWORKS_PRIORITY_HIGH>();
}

TEST_F(NNAPIPluginTest, PassesCachingParameters) {
  nnapi_->ANeuralNetworksCompilation_setCaching =
      [](ANeuralNetworksCompilation* compilation, const char* cacheDir,
         const uint8_t* token) -> int {
    if (std::string(cacheDir) != "d") return 1;
    // Token is hashed with other bits, just check that it's not empty.
    if (std::string(reinterpret_cast<const char*>(token)).empty()) return 2;
    return 0;
  };
  CreateDelegate(CreateNNAPISettings(fbb_, 0, fbb_.CreateString("d"),
                                     fbb_.CreateString("t")));
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

TEST_F(NNAPIPluginTest, PassesFalseNNAPICpuFlag) {
  CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0,
                                     NNAPIExecutionPreference_UNDEFINED, 0, 0,
                                     /* allow CPU */ false));
  nnapi_->ANeuralNetworksModel_getSupportedOperationsForDevices =
      [](const ANeuralNetworksModel* model,
         const ANeuralNetworksDevice* const* devices, uint32_t numDevices,
         bool* supportedOps) -> int {
    supportedOps[0] = true;
    // Since no CPU, should only pass one device.
    return numDevices - 1;
  };
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

TEST_F(NNAPIPluginTest, PassesTrueNNAPICpuFlag) {
  CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0,
                                     NNAPIExecutionPreference_UNDEFINED, 0, 0,
                                     /* allow CPU */ true));
  nnapi_->ANeuralNetworksModel_getSupportedOperationsForDevices =
      [](const ANeuralNetworksModel* model,
         const ANeuralNetworksDevice* const* devices, uint32_t numDevices,
         bool* supportedOps) -> int {
    supportedOps[0] = true;
    // With CPU allowed, should pass two devices.
    return numDevices - 2;
  };
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

}  // namespace
}  // namespace tflite
<commit_msg>Skip applying TfLite default delegates for the nnapi_plugin_test.<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <memory>

#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h"  // from @flatbuffers
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate_kernel.h"
#include "tensorflow/lite/delegates/nnapi/nnapi_delegate_mock_test.h"
#include "tensorflow/lite/experimental/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/experimental/acceleration/configuration/delegate_registry.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/test_util.h"

// Tests for checking that the NNAPI Delegate plugin correctly handles all the
// options from the flatbuffer.
//
// Checking done at NNAPI call level, as that is where we have a mockable
// layer.
namespace tflite {
namespace {

using delegate::nnapi::NnApiMock;

class SingleAddOpModel : tflite::SingleOpModel {
 public:
  void Build() {
    int input = AddInput({tflite::TensorType_FLOAT32, {1, 2, 2}});
    int constant = AddConstInput({tflite::TensorType_FLOAT32, {1, 2, 2}},
                                 {1.0f, 1.0f, 1.0f, 1.0f});
    AddOutput({tflite::TensorType_FLOAT32, {}});

    SetBuiltinOp(tflite::BuiltinOperator_ADD, tflite::BuiltinOptions_AddOptions,
                 tflite::CreateAddOptions(builder_).Union());
    // Set apply_delegate to false to skip applying TfLite default delegates.
    BuildInterpreter({GetShape(input), GetShape(constant)},
                     /*num_threads=*/-1,
                     /*allow_fp32_relax_to_fp16=*/false,
                     /*apply_delegate=*/false,
                     /*allocate_and_delegate=*/true);
  }

  tflite::Interpreter* Interpreter() const { return interpreter_.get(); }
};

class NNAPIPluginTest : public ::testing::Test {
 protected:
  NNAPIPluginTest() : delegate_(nullptr, [](TfLiteDelegate*) {}) {}
  void SetUp() override {
    nnapi_ = const_cast<NnApi*>(NnApiImplementation());
    nnapi_mock_ = absl::make_unique<NnApiMock>(nnapi_);
    nnapi_->ANeuralNetworksModel_getSupportedOperationsForDevices =
        [](const ANeuralNetworksModel* model,
           const ANeuralNetworksDevice* const* devices, uint32_t numDevices,
           bool* supportedOps) -> int {
      supportedOps[0] = true;
      return 0;
    };
    model_.Build();
  }
  template <NNAPIExecutionPreference input, int output>
  void CheckExecutionPreference() {
    // Note - this uses a template since the NNAPI functions are C function
    // pointers rather than lambdas so can't capture variables.
    nnapi_->ANeuralNetworksCompilation_setPreference =
        [](ANeuralNetworksCompilation* compilation, int32_t preference) {
          return preference - output;
        };
    CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0, input));
    // Since delegation succeeds, the model becomes immutable and hence can't
    // reuse it.
    SingleAddOpModel model;
    model.Build();
    EXPECT_EQ(model.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
              kTfLiteOk)
        << " given input: " << input << " expected output: " << output;
  }
  template <NNAPIExecutionPriority input, int output>
  void CheckExecutionPriority() {
    // Note - this uses a template since the NNAPI functions are C function
    // pointers rather than lambdas so can't capture variables.
    nnapi_->ANeuralNetworksCompilation_setPriority =
        [](ANeuralNetworksCompilation* compilation, int32_t priority) {
          return priority - output;
        };
    CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0,
                                       NNAPIExecutionPreference_UNDEFINED, 0, 0,
                                       /*allow CPU=*/true, input));
    // Since delegation succeeds, the model becomes immutable and hence can't
    // reuse it.
    SingleAddOpModel model;
    model.Build();
    EXPECT_EQ(model.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
              kTfLiteOk)
        << " given input: " << input << " expected output: " << output;
  }

  void CreateDelegate(flatbuffers::Offset<NNAPISettings> settings) {
    settings_ = flatbuffers::GetTemporaryPointer(
        fbb_, CreateTFLiteSettings(fbb_, tflite::Delegate_NNAPI, settings));

    plugin_ = delegates::DelegatePluginRegistry::CreateByName("NnapiPlugin",
                                                              *settings_);
    delegate_ = plugin_->Create();
  }

  NnApi* nnapi_;
  std::unique_ptr<NnApiMock> nnapi_mock_;
  SingleAddOpModel model_;
  flatbuffers::FlatBufferBuilder fbb_;
  const TFLiteSettings* settings_ = nullptr;
  delegates::TfLiteDelegatePtr delegate_;
  std::unique_ptr<delegates::DelegatePluginInterface> plugin_;
};

TEST_F(NNAPIPluginTest, PassesAcceleratorName) {
  // Fails with non-existent "foo".
  CreateDelegate(CreateNNAPISettings(fbb_, fbb_.CreateString("foo")));
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteDelegateError);

  // Succeeds with "test-device" supported by the mock.
  CreateDelegate(CreateNNAPISettings(fbb_, fbb_.CreateString("test-device")));
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

TEST_F(NNAPIPluginTest, PassesExecutionPreference) {
  CheckExecutionPreference<NNAPIExecutionPreference_UNDEFINED,
                           StatefulNnApiDelegate::Options::kUndefined>();
  CheckExecutionPreference<NNAPIExecutionPreference_NNAPI_LOW_POWER,
                           StatefulNnApiDelegate::Options::kLowPower>();
  CheckExecutionPreference<NNAPIExecutionPreference_NNAPI_FAST_SINGLE_ANSWER,
                           StatefulNnApiDelegate::Options::kFastSingleAnswer>();
  CheckExecutionPreference<NNAPIExecutionPreference_NNAPI_SUSTAINED_SPEED,
                           StatefulNnApiDelegate::Options::kSustainedSpeed>();
}

TEST_F(NNAPIPluginTest, PassesExecutionPriority) {
  nnapi_->android_sdk_version =
      tflite::delegate::nnapi::kMinSdkVersionForNNAPI13;
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED,
                         ANEURALNETWORKS_PRIORITY_DEFAULT>();
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_LOW,
                         ANEURALNETWORKS_PRIORITY_LOW>();
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_MEDIUM,
                         ANEURALNETWORKS_PRIORITY_MEDIUM>();
  CheckExecutionPriority<NNAPIExecutionPriority_NNAPI_PRIORITY_HIGH,
                         ANEURALNETWORKS_PRIORITY_HIGH>();
}

TEST_F(NNAPIPluginTest, PassesCachingParameters) {
  nnapi_->ANeuralNetworksCompilation_setCaching =
      [](ANeuralNetworksCompilation* compilation, const char* cacheDir,
         const uint8_t* token) -> int {
    if (std::string(cacheDir) != "d") return 1;
    // Token is hashed with other bits, just check that it's not empty.
    if (std::string(reinterpret_cast<const char*>(token)).empty()) return 2;
    return 0;
  };
  CreateDelegate(CreateNNAPISettings(fbb_, 0, fbb_.CreateString("d"),
                                     fbb_.CreateString("t")));
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

TEST_F(NNAPIPluginTest, PassesFalseNNAPICpuFlag) {
  CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0,
                                     NNAPIExecutionPreference_UNDEFINED, 0, 0,
                                     /* allow CPU */ false));
  nnapi_->ANeuralNetworksModel_getSupportedOperationsForDevices =
      [](const ANeuralNetworksModel* model,
         const ANeuralNetworksDevice* const* devices, uint32_t numDevices,
         bool* supportedOps) -> int {
    supportedOps[0] = true;
    // Since no CPU, should only pass one device.
    return numDevices - 1;
  };
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

TEST_F(NNAPIPluginTest, PassesTrueNNAPICpuFlag) {
  CreateDelegate(CreateNNAPISettings(fbb_, 0, 0, 0,
                                     NNAPIExecutionPreference_UNDEFINED, 0, 0,
                                     /* allow CPU */ true));
  nnapi_->ANeuralNetworksModel_getSupportedOperationsForDevices =
      [](const ANeuralNetworksModel* model,
         const ANeuralNetworksDevice* const* devices, uint32_t numDevices,
         bool* supportedOps) -> int {
    supportedOps[0] = true;
    // With CPU allowed, should pass two devices.
    return numDevices - 2;
  };
  EXPECT_EQ(model_.Interpreter()->ModifyGraphWithDelegate(delegate_.get()),
            kTfLiteOk);
}

}  // namespace
}  // namespace tflite
<|endoftext|>


<commit_before>/*!   \file unitTestCoefficientGenerator.cpp
 *    This file contains the unit test of the hypersonic local inclination
 *    analysis.
 *
 *    Path              : /Astrodynamics/ForceModels/Aerothermodynamics/
 *    Version           : 1
 *    Check status      : Checked
 *
 *    Author            : Dominic Dirkx
 *    Affiliation       : Delft University of Technology
 *    E-mail address    : D.Dirkx@student.tudelft.nl
 *
 *    Checker           : Bart Romgens
 *    Affiliation       : Delft University of Technology
 *    E-mail address    : B.Romgens@student.tudelft.nl
 *
 *    Date created      : 25 November, 2010
 *    Last modified     : 9 February,  2011
 *
 *    References
 *      Gentry, A., Smyth, D., and Oliver, W. . The Mark IV Supersonic-Hypersonic
 *        Arbitrary Body Program, Volume II - Program Formulation, Douglas Aircraft
 *        Aircraft Company, 1973.
 *
 *    Notes
 *
 *    Copyright (c) 2010 Delft University of Technology.
 *
 *    This software is protected by national and international copyright.
 *    Any unauthorized use, reproduction or modification is unlawful and
 *    will be prosecuted. Commercial and non-private application of the
 *    software in any form is strictly prohibited unless otherwise granted
 *    by the authors.
 *
 *    The code is provided without any warranty; without even the implied
 *    warranty of merchantibility or fitness for a particular purpose.
 *
 *    Changelog
 *      YYMMDD    Author            Comment
 *      102511    D. Dirkx          First version of file.
 */

// Include statements.
#include "unitTestCoefficientGenerator.h"
#include "writingOutputToFile.h"

bool unit_tests::testCoefficientGenerator( )
{

    // Declare test variable.
    bool isCoefficientGeneratorBad_ = 0;

    // Create test sphere.
    SphereSegment sphere = SphereSegment( );
    sphere.setRadius( 1.0 );
    sphere.setMinimumAzimuthAngle(  0.0 );
    sphere.setMaximumAzimuthAngle( 2.0 * M_PI);
    sphere.setMinimumZenithAngle( 0.0 );
    sphere.setMaximumZenithAngle( M_PI );
    VehicleExternalModel externalModel = VehicleExternalModel();
    externalModel.setVehicleGeometry( sphere );
    Vehicle vehicle = Vehicle();
    vehicle.setExternalModel( externalModel );

    // Create analysis object.
    HypersonicLocalInclinationAnalysis analysis =
            HypersonicLocalInclinationAnalysis( );

    // Set vehicle in analysis with 10,000 panels.
    int* numberOfLines = new int[ 1 ];
    int* numberOfPoints = new int[ 1 ];
    bool* invertOrder = new bool[ 1 ];
    numberOfLines[ 0 ] = 101;
    numberOfPoints[ 0 ] = 101;
    invertOrder[ 0 ] = 0;
    analysis.setVehicle( vehicle, numberOfLines, numberOfPoints, invertOrder );

    // Set reference quantities.
    analysis.setReferenceArea( M_PI );
    analysis.setReferenceLength( 1.0 );
    analysis.setMomentReferencePoint( Vector3d( 0, 0, 0) );

    // Set pure Newtonian compression method for test purposes.
    analysis.setSelectedMethod( 0, 0, 0 );

    // Generate sphere database.
    analysis.generateDatabase( );

    // Allocate memory for independent variables
    // to pass to analysis for retrieval.
    int* independentVariables = new int[ 3 ];
    independentVariables[ 0 ] = 0;
    independentVariables[ 1 ] = 0;
    independentVariables[ 2 ] = 0;

    // Declare local test variables.
    VectorXd aerodynamicCoefficients_;
    double forceCoefficient_;

    // Iterate over all angles of attack to verify sphere coefficients.
    for( int i = 0; i < analysis.getNumberOfMachPoints(); i++ )
    {
        independentVariables[ 0 ] = i;

        for( int j = 0; j < analysis.getNumberOfAngleOfAttackPoints( ); j++ )
        {
            independentVariables[ 1 ] = j;

            for( int k = 0; k < analysis.getNumberOfAngleOfSideslipPoints( ); k++ )
            {
                independentVariables[ 2 ] = k;

                // Retrieve aerodynamic coefficients.
                aerodynamicCoefficients_ = analysis.getAerodynamicCoefficients(
                        independentVariables );
                forceCoefficient_ = sqrt( aerodynamicCoefficients_.x( )
                                        * aerodynamicCoefficients_.x( )
                                        + aerodynamicCoefficients_.y( )
                                        * aerodynamicCoefficients_.y( )
                                        + aerodynamicCoefficients_.z( )
                                        * aerodynamicCoefficients_.z( ) );

                // Check if 'total' aerodynamic coefficient is always
                // sufficiently close to zero.
                if( fabs( forceCoefficient_ - 1.0 ) > 1.0E-3 )
                {
                    std::cout<<"Total magnitude of aerodynamic force wrong in "
                            <<"sphere."<<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }

                // Check if moment coefficients are approximately zero. Deviations
                // for pitch moment are greater due to greater range of angles of
                // attack than sideslip.
                if( fabs( aerodynamicCoefficients_[ 3 ] ) > 1.0E-5 )
                {
                    std::cerr<<" Error, sphere roll moment coefficient not zero. "
                            <<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }
                if( fabs( aerodynamicCoefficients_[ 4 ] ) > 1.0E-3 )
                {
                    std::cerr<<" Error, sphere pitch moment coefficient not zero. "
                            <<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }
                if( fabs( aerodynamicCoefficients_[ 5 ] ) > 1.0E-5 )
                {
                    std::cerr<<" Error, sphere yaw moment coefficient not zero. "
                            <<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }
            }
        }
    }

    // Set Apollo capsule for validation.
    Capsule capsule = Capsule( );
    capsule.setNoseRadius( 4.694 );
    capsule.setMiddleRadius( 1.956 );
    capsule.setRearAngle( -1*33.0 * M_PI / 180.0 );
    capsule.setRearLength( 2.662 );
    capsule.setSideRadius( 0.196 );
    capsule.setCapsule( );
    externalModel.setVehicleGeometry( capsule );
    vehicle.setExternalModel( externalModel );

    // Declare new analysis object
    HypersonicLocalInclinationAnalysis analysis2 =
            HypersonicLocalInclinationAnalysis( );

    int * numberOfLines2 = new int[ 4 ];
    int * numberOfPoints2 = new int[ 4 ];
    bool * invertOrders2 = new bool[ 4 ];

    // Set number of analysis points
    numberOfLines2[ 0 ] = 51;
    numberOfPoints2[ 0 ] = 51;
    numberOfLines2[ 1 ] = 51;
    numberOfPoints2[ 1 ] = 51;
    numberOfLines2[ 2 ] = 51;
    numberOfPoints2[ 2 ] = 2;
    numberOfLines2[ 3 ] = 51;
    numberOfPoints2[ 3 ] = 51;
    invertOrders2[ 0 ] = 1;
    invertOrders2[ 1 ] = 1;
    invertOrders2[ 2 ] = 1;
    invertOrders2[ 3 ] = 1;

    // Set capsule for analysis.
    analysis2.setVehicle( vehicle, numberOfLines2, numberOfPoints2, invertOrders2 );

    // Set reference quantities.
    analysis2.setReferenceArea( M_PI * pow( capsule.getMiddleRadius( ), 2.0 ) );
    analysis2.setReferenceLength( 3.9116 );
    VectorXd momentReference = VectorXd( 3 );
    momentReference( 0 ) = 0.6624;//27.334;
    momentReference( 1 ) = 0;
    momentReference( 2 ) = 0.1369;//9.398;
    analysis2.setMomentReferencePoint( momentReference );

    // Set angle of attack analysis points.
    analysis2.setNumberOfAngleOfAttackPoints( 7 );
    int i;
    for( i = 0; i < 7; i++ )
    {
        analysis2.setAngleOfAttackPoint( i,
                                         static_cast< double >( i - 6 )
                                         * 5.0 * M_PI / 180.0 );
    }

    // Generate database.
    analysis2.generateDatabase( );

    // Retrieve coefficients at zero angle of attack for comparison.
    independentVariables[ 0 ] = analysis2.getNumberOfMachPoints( ) - 1;
    independentVariables[ 1 ] = analysis2.getNumberOfMachPoints( ) - 1;
    independentVariables[ 2 ] = 0;
    aerodynamicCoefficients_ = analysis2.getAerodynamicCoefficients( independentVariables );

    // Compare values to database values.
    if( fabs( aerodynamicCoefficients_[ 0 ] - 1.51 ) > 0.1 )
    {
        std::cerr<<" Error in Apollo drag coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 1 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo side force coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 2 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo normal force coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 3 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo roll moment coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( fabs( aerodynamicCoefficients_[ 4 ] +0.052 ) > 0.01 )
    {
        std::cerr<<" Error in Apollo pitch moment coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 5 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo yaw moment coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }

    return isCoefficientGeneratorBad_;
}

// End of file.
<commit_msg>Commit of update to unit test of aerodynamics coefficient generator.<commit_after>/*!   \file unitTestCoefficientGenerator.cpp
 *    This file contains the unit test of the hypersonic local inclination
 *    analysis.
 *
 *    Path              : /Astrodynamics/ForceModels/Aerothermodynamics/
 *    Version           : 1
 *    Check status      : Checked
 *
 *    Author            : Dominic Dirkx
 *    Affiliation       : Delft University of Technology
 *    E-mail address    : D.Dirkx@student.tudelft.nl
 *
 *    Checker           : Bart Romgens
 *    Affiliation       : Delft University of Technology
 *    E-mail address    : B.Romgens@student.tudelft.nl
 *
 *    Date created      : 25 November, 2010
 *    Last modified     : 9 February,  2011
 *
 *    References
 *      Gentry, A., Smyth, D., and Oliver, W. . The Mark IV Supersonic-Hypersonic
 *        Arbitrary Body Program, Volume II - Program Formulation, Douglas Aircraft
 *        Aircraft Company, 1973.
 *
 *    Notes
 *
 *    Copyright (c) 2010 Delft University of Technology.
 *
 *    This software is protected by national and international copyright.
 *    Any unauthorized use, reproduction or modification is unlawful and
 *    will be prosecuted. Commercial and non-private application of the
 *    software in any form is strictly prohibited unless otherwise granted
 *    by the authors.
 *
 *    The code is provided without any warranty; without even the implied
 *    warranty of merchantibility or fitness for a particular purpose.
 *
 *    Changelog
 *      YYMMDD    Author            Comment
 *      102511    D. Dirkx          First version of file.
 */

// Include statements.
#include "unitTestCoefficientGenerator.h"
#include "writingOutputToFile.h"

bool unit_tests::testCoefficientGenerator( )
{

    // Declare test variable.
    bool isCoefficientGeneratorBad_ = 0;

    // Create test sphere.
    SphereSegment sphere = SphereSegment( );
    sphere.setRadius( 1.0 );
    sphere.setMinimumAzimuthAngle(  0.0 );
    sphere.setMaximumAzimuthAngle( 2.0 * M_PI);
    sphere.setMinimumZenithAngle( 0.0 );
    sphere.setMaximumZenithAngle( M_PI );
    VehicleExternalModel externalModel = VehicleExternalModel();
    externalModel.setVehicleGeometry( sphere );
    Vehicle vehicle = Vehicle();
    vehicle.setExternalModel( externalModel );

    // Create analysis object.
    HypersonicLocalInclinationAnalysis analysis =
            HypersonicLocalInclinationAnalysis( );

    // Set vehicle in analysis with 10,000 panels.
    int* numberOfLines = new int[ 1 ];
    int* numberOfPoints = new int[ 1 ];
    bool* invertOrder = new bool[ 1 ];
    numberOfLines[ 0 ] = 31;
    numberOfPoints[ 0 ] = 31;
    invertOrder[ 0 ] = 0;
    analysis.setVehicle( vehicle, numberOfLines, numberOfPoints, invertOrder );

    // Set reference quantities.
    analysis.setReferenceArea( M_PI );
    analysis.setReferenceLength( 1.0 );
    analysis.setMomentReferencePoint( Vector3d( 0, 0, 0) );

    // Set pure Newtonian compression method for test purposes.
    analysis.setSelectedMethod( 0, 0, 0 );

    // Generate sphere database.
    analysis.generateDatabase( );

    // Allocate memory for independent variables
    // to pass to analysis for retrieval.
    int* independentVariables = new int[ 3 ];
    independentVariables[ 0 ] = 0;
    independentVariables[ 1 ] = 0;
    independentVariables[ 2 ] = 0;

    // Declare local test variables.
    VectorXd aerodynamicCoefficients_;
    double forceCoefficient_;

    // Iterate over all angles of attack to verify sphere coefficients.
    for( int i = 0; i < analysis.getNumberOfMachPoints(); i++ )
    {
        independentVariables[ 0 ] = i;

        for( int j = 0; j < analysis.getNumberOfAngleOfAttackPoints( ); j++ )
        {
            independentVariables[ 1 ] = j;

            for( int k = 0; k < analysis.getNumberOfAngleOfSideslipPoints( ); k++ )
            {
                independentVariables[ 2 ] = k;

                // Retrieve aerodynamic coefficients.
                aerodynamicCoefficients_ = analysis.getAerodynamicCoefficients(
                        independentVariables );
                forceCoefficient_ = sqrt( aerodynamicCoefficients_.x( )
                                        * aerodynamicCoefficients_.x( )
                                        + aerodynamicCoefficients_.y( )
                                        * aerodynamicCoefficients_.y( )
                                        + aerodynamicCoefficients_.z( )
                                        * aerodynamicCoefficients_.z( ) );

                // Check if 'total' aerodynamic coefficient is always
                // sufficiently close to zero.
                if( fabs( forceCoefficient_ - 1.0 ) > 1.0E-2 )
                {
                    std::cout<<"Total magnitude of aerodynamic force wrong in "
                            <<"sphere."<<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }

                // Check if moment coefficients are approximately zero. Deviations
                // for pitch moment are greater due to greater range of angles of
                // attack than sideslip.
                if( fabs( aerodynamicCoefficients_[ 3 ] ) > 1.0E-4 )
                {
                    std::cerr<<" Error, sphere roll moment coefficient not zero. "
                            <<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }
                if( fabs( aerodynamicCoefficients_[ 4 ] ) > 1.0E-2 )
                {
                    std::cerr<<" Error, sphere pitch moment coefficient not zero. "
                            <<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }
                if( fabs( aerodynamicCoefficients_[ 5 ] ) > 1.0E-2 )
                {
                    std::cerr<<" Error, sphere yaw moment coefficient not zero. "
                            <<std::endl;
                    isCoefficientGeneratorBad_ = true;
                }
            }
        }
    }

    // Set Apollo capsule for validation.
    Capsule capsule = Capsule( );
    capsule.setNoseRadius( 4.694 );
    capsule.setMiddleRadius( 1.956 );
    capsule.setRearAngle( -1*33.0 * M_PI / 180.0 );
    capsule.setRearLength( 2.662 );
    capsule.setSideRadius( 0.196 );
    capsule.setCapsule( );
    externalModel.setVehicleGeometry( capsule );
    vehicle.setExternalModel( externalModel );

    // Declare new analysis object
    HypersonicLocalInclinationAnalysis analysis2 =
            HypersonicLocalInclinationAnalysis( );

    int * numberOfLines2 = new int[ 4 ];
    int * numberOfPoints2 = new int[ 4 ];
    bool * invertOrders2 = new bool[ 4 ];

    // Set number of analysis points
    numberOfLines2[ 0 ] = 31;
    numberOfPoints2[ 0 ] = 31;
    numberOfLines2[ 1 ] = 31;
    numberOfPoints2[ 1 ] = 31;
    numberOfLines2[ 2 ] = 31;
    numberOfPoints2[ 2 ] = 2;
    numberOfLines2[ 3 ] = 11;
    numberOfPoints2[ 3 ] = 11;
    invertOrders2[ 0 ] = 1;
    invertOrders2[ 1 ] = 1;
    invertOrders2[ 2 ] = 1;
    invertOrders2[ 3 ] = 1;

    // Set capsule for analysis.
    analysis2.setVehicle( vehicle, numberOfLines2, numberOfPoints2, invertOrders2 );

    // Set reference quantities.
    analysis2.setReferenceArea( M_PI * pow( capsule.getMiddleRadius( ), 2.0 ) );
    analysis2.setReferenceLength( 3.9116 );
    VectorXd momentReference = VectorXd( 3 );
    momentReference( 0 ) = 0.6624;//27.334;
    momentReference( 1 ) = 0;
    momentReference( 2 ) = 0.1369;//9.398;
    analysis2.setMomentReferencePoint( momentReference );

    // Set angle of attack analysis points.
    analysis2.setNumberOfAngleOfAttackPoints( 7 );
    int i;
    for( i = 0; i < 7; i++ )
    {
        analysis2.setAngleOfAttackPoint( i,
                                         static_cast< double >( i - 6 )
                                         * 5.0 * M_PI / 180.0 );
    }

    // Generate database.
    analysis2.generateDatabase( );

    // Retrieve coefficients at zero angle of attack for comparison.
    independentVariables[ 0 ] = analysis2.getNumberOfMachPoints( ) - 1;
    independentVariables[ 1 ] = analysis2.getNumberOfMachPoints( ) - 1;
    independentVariables[ 2 ] = 0;
    aerodynamicCoefficients_ = analysis2.getAerodynamicCoefficients( independentVariables );

    // Compare values to database values.
    if( fabs( aerodynamicCoefficients_[ 0 ] - 1.51 ) > 0.1 )
    {
        std::cerr<<" Error in Apollo drag coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 1 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo side force coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 2 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo normal force coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 3 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo roll moment coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( fabs( aerodynamicCoefficients_[ 4 ] +0.052 ) > 0.01 )
    {
        std::cerr<<" Error in Apollo pitch moment coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }
    if( aerodynamicCoefficients_[ 5 ] > 1.0E-15 )
    {
        std::cerr<<" Error in Apollo yaw moment coefficient "<<std::endl;
        isCoefficientGeneratorBad_ = true;
    }

    return isCoefficientGeneratorBad_;
}

// End of file.
<|endoftext|>