<commit_before>//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Decl class and subclasses.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Decl.h"
#include "clang/Lex/IdentifierTable.h"
using namespace clang;

// temporary statistics gathering
static unsigned nFuncs = 0;
static unsigned nBlockVars = 0;
static unsigned nFileVars = 0;
static unsigned nParmVars = 0;
static unsigned nSUC = 0;
static unsigned nEnumConst = 0;
static unsigned nEnumDecls = 0;
static unsigned nTypedef = 0;
static unsigned nFieldDecls = 0;
static unsigned nInterfaceDecls = 0;
static bool StatSwitch = false;

const char *Decl::getDeclKindName() {
  switch (DeclKind) {
  default: assert(0 && "Unknown decl kind!");
  case Typedef:
    return "Typedef";
  case Function:
    return "Function";
  case BlockVariable:
    return "BlockVariable";
  case FileVariable:
    return "FileVariable";
  case ParmVariable:
    return "ParmVariable";
  case EnumConstant:
    return "EnumConstant";
  case ObjcInterface:
    return "ObjcInterface";
  case ObjcClass:
    return "ObjcClass";
  case ObjcMethod:
    return "ObjcMethod";
  case ObjcProtoMethod:
    return "ObjcProtoMethod";
  case ObjcProtocol:
    return "ObjcProtocol";
  case Struct:
    return "Struct";
  case Union:
    return "Union";
  case Class:
    return "Class";
  case Enum:
    return "Enum";
  }
}

bool Decl::CollectingStats(bool enable) {
  if (enable) StatSwitch = true;
	return StatSwitch;
}

void Decl::PrintStats() {
  fprintf(stderr, "*** Decl Stats:\n");
  fprintf(stderr, "  %d decls total.\n",
	  int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
	      nEnumDecls+nEnumConst+nTypedef));
  fprintf(stderr, "    %d function decls, %d each (%d bytes)\n",
	  nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
  fprintf(stderr, "    %d block variable decls, %d each (%d bytes)\n",
	  nBlockVars, (int)sizeof(BlockVarDecl),
	  int(nBlockVars*sizeof(BlockVarDecl)));
  fprintf(stderr, "    %d file variable decls, %d each (%d bytes)\n",
	  nFileVars, (int)sizeof(FileVarDecl),
	  int(nFileVars*sizeof(FileVarDecl)));
  fprintf(stderr, "    %d parameter variable decls, %d each (%d bytes)\n",
	  nParmVars, (int)sizeof(ParmVarDecl),
	  int(nParmVars*sizeof(ParmVarDecl)));
  fprintf(stderr, "    %d field decls, %d each (%d bytes)\n",
	  nFieldDecls, (int)sizeof(FieldDecl),
	  int(nFieldDecls*sizeof(FieldDecl)));
  fprintf(stderr, "    %d struct/union/class decls, %d each (%d bytes)\n",
	  nSUC, (int)sizeof(RecordDecl),
	  int(nSUC*sizeof(RecordDecl)));
  fprintf(stderr, "    %d enum decls, %d each (%d bytes)\n",
	  nEnumDecls, (int)sizeof(EnumDecl),
	  int(nEnumDecls*sizeof(EnumDecl)));
  fprintf(stderr, "    %d enum constant decls, %d each (%d bytes)\n",
	  nEnumConst, (int)sizeof(EnumConstantDecl),
	  int(nEnumConst*sizeof(EnumConstantDecl)));
  fprintf(stderr, "    %d typedef decls, %d each (%d bytes)\n",
	  nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
  fprintf(stderr, "Total bytes = %d\n",
	  int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
	      nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
	      nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
	      nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
	      nTypedef*sizeof(TypedefDecl)));
}

void Decl::addDeclKind(const Kind k) {
  switch (k) {
    case Typedef:
      nTypedef++;
      break;
    case Function:
      nFuncs++;
      break;
    case BlockVariable:
      nBlockVars++;
      break;
    case FileVariable:
      nFileVars++;
      break;
    case ParmVariable:
      nParmVars++;
      break;
    case EnumConstant:
      nEnumConst++;
      break;
    case Field:
      nFieldDecls++;
      break;
    case Struct:
    case Union:
    case Class:
      nSUC++;
      break;
    case Enum:
      nEnumDecls++;
      break;
    case ObjcInterface:
      nInterfaceDecls++;
      break;
  }
}

// Out-of-line virtual method providing a home for Decl.
Decl::~Decl() {
}

const char *FieldDecl::getName() const {
  if (const IdentifierInfo *II = getIdentifier())
    return II->getName();
  return "";
}

const char *ScopedDecl::getName() const {
  if (const IdentifierInfo *II = getIdentifier())
    return II->getName();
  return "";
}

FunctionDecl::~FunctionDecl() {
  delete[] ParamInfo;
}

unsigned FunctionDecl::getNumParams() const {
  return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
}

void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
  assert(ParamInfo == 0 && "Already has param info!");
  assert(NumParams == getNumParams() && "Parameter count mismatch!");

  // Zero params -> null pointer.
  if (NumParams) {
    ParamInfo = new ParmVarDecl*[NumParams];
    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
  }
}

/// defineBody - When created, RecordDecl's correspond to a forward declared
/// record.  This method is used to mark the decl as being defined, with the
/// specified contents.
void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
  assert(!isDefinition() && "Cannot redefine record!");
  setDefinition(true);
  NumMembers = numMembers;
  if (numMembers) {
    Members = new FieldDecl*[numMembers];
    memcpy(Members, members, numMembers*sizeof(Decl*));
  }
}

FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
  if (Members == 0 || NumMembers < 0)
    return 0;

  // linear search. When C++ classes come along, will likely need to revisit.
  for (int i = 0; i < NumMembers; ++i) {
    if (Members[i]->getIdentifier() == name)
      return Members[i];
  }
  return 0;
}

void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
		       unsigned NumParams) {
  assert(ParamInfo == 0 && "Already has param info!");

  // Zero params -> null pointer.
  if (NumParams) {
    ParamInfo = new ParmVarDecl*[NumParams];
    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
    NumMethodParams = NumParams;
  }
}

ObjcMethodDecl::~ObjcMethodDecl() {
  delete[] ParamInfo;
}

/// ObjcAddInstanceVariablesToClass - Inserts instance variables
/// into ObjcInterfaceDecl's fields.
///
void ObjcInterfaceDecl::ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
					   		unsigned numIvars) {
  NumIvars = numIvars;
  if (numIvars) {
    Ivars = new ObjcIvarDecl*[numIvars];
    memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
  }
}

/// addObjcMethods - Insert instance and methods declarations into
/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
///
void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods,
				       unsigned numInsMembers,
                                       ObjcMethodDecl **clsMethods,
                                       unsigned numClsMembers) {
  NumInsMethods = numInsMembers;
  if (numInsMembers) {
    InsMethods = new ObjcMethodDecl*[numInsMembers];
    memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
  }
  NumClsMethods = numClsMembers;
  if (numClsMembers) {
    ClsMethods = new ObjcMethodDecl*[numClsMembers];
    memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
  }
}

<commit_msg>decl counting isn't implemented yet for objc.  -stats probably crashes for it. Patch by Justin Handville<commit_after>//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Decl class and subclasses.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Decl.h"
#include "clang/Lex/IdentifierTable.h"
using namespace clang;

// temporary statistics gathering
static unsigned nFuncs = 0;
static unsigned nBlockVars = 0;
static unsigned nFileVars = 0;
static unsigned nParmVars = 0;
static unsigned nSUC = 0;
static unsigned nEnumConst = 0;
static unsigned nEnumDecls = 0;
static unsigned nTypedef = 0;
static unsigned nFieldDecls = 0;
static unsigned nInterfaceDecls = 0;
static bool StatSwitch = false;

const char *Decl::getDeclKindName() {
  switch (DeclKind) {
  default: assert(0 && "Unknown decl kind!");
  case Typedef:
    return "Typedef";
  case Function:
    return "Function";
  case BlockVariable:
    return "BlockVariable";
  case FileVariable:
    return "FileVariable";
  case ParmVariable:
    return "ParmVariable";
  case EnumConstant:
    return "EnumConstant";
  case ObjcInterface:
    return "ObjcInterface";
  case ObjcClass:
    return "ObjcClass";
  case ObjcMethod:
    return "ObjcMethod";
  case ObjcProtoMethod:
    return "ObjcProtoMethod";
  case ObjcProtocol:
    return "ObjcProtocol";
  case Struct:
    return "Struct";
  case Union:
    return "Union";
  case Class:
    return "Class";
  case Enum:
    return "Enum";
  }
}

bool Decl::CollectingStats(bool enable) {
  if (enable) StatSwitch = true;
	return StatSwitch;
}

void Decl::PrintStats() {
  fprintf(stderr, "*** Decl Stats:\n");
  fprintf(stderr, "  %d decls total.\n",
	  int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
	      nEnumDecls+nEnumConst+nTypedef));
  fprintf(stderr, "    %d function decls, %d each (%d bytes)\n",
	  nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
  fprintf(stderr, "    %d block variable decls, %d each (%d bytes)\n",
	  nBlockVars, (int)sizeof(BlockVarDecl),
	  int(nBlockVars*sizeof(BlockVarDecl)));
  fprintf(stderr, "    %d file variable decls, %d each (%d bytes)\n",
	  nFileVars, (int)sizeof(FileVarDecl),
	  int(nFileVars*sizeof(FileVarDecl)));
  fprintf(stderr, "    %d parameter variable decls, %d each (%d bytes)\n",
	  nParmVars, (int)sizeof(ParmVarDecl),
	  int(nParmVars*sizeof(ParmVarDecl)));
  fprintf(stderr, "    %d field decls, %d each (%d bytes)\n",
	  nFieldDecls, (int)sizeof(FieldDecl),
	  int(nFieldDecls*sizeof(FieldDecl)));
  fprintf(stderr, "    %d struct/union/class decls, %d each (%d bytes)\n",
	  nSUC, (int)sizeof(RecordDecl),
	  int(nSUC*sizeof(RecordDecl)));
  fprintf(stderr, "    %d enum decls, %d each (%d bytes)\n",
	  nEnumDecls, (int)sizeof(EnumDecl),
	  int(nEnumDecls*sizeof(EnumDecl)));
  fprintf(stderr, "    %d enum constant decls, %d each (%d bytes)\n",
	  nEnumConst, (int)sizeof(EnumConstantDecl),
	  int(nEnumConst*sizeof(EnumConstantDecl)));
  fprintf(stderr, "    %d typedef decls, %d each (%d bytes)\n",
	  nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
  fprintf(stderr, "Total bytes = %d\n",
	  int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
	      nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
	      nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
	      nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
	      nTypedef*sizeof(TypedefDecl)));
}

void Decl::addDeclKind(const Kind k) {
  switch (k) {
    case Typedef:
      nTypedef++;
      break;
    case Function:
      nFuncs++;
      break;
    case BlockVariable:
      nBlockVars++;
      break;
    case FileVariable:
      nFileVars++;
      break;
    case ParmVariable:
      nParmVars++;
      break;
    case EnumConstant:
      nEnumConst++;
      break;
    case Field:
      nFieldDecls++;
      break;
    case Struct:
    case Union:
    case Class:
      nSUC++;
      break;
    case Enum:
      nEnumDecls++;
      break;
    case ObjcInterface:
      nInterfaceDecls++;
      break;
    case ObjcClass:
    case ObjcMethod:
    case ObjcProtoMethod:
    case ObjcProtocol:
    case ObjcIvar:
      assert(0 && "FIXME: Count these decls!");
      break;
  }
}

// Out-of-line virtual method providing a home for Decl.
Decl::~Decl() {
}

const char *FieldDecl::getName() const {
  if (const IdentifierInfo *II = getIdentifier())
    return II->getName();
  return "";
}

const char *ScopedDecl::getName() const {
  if (const IdentifierInfo *II = getIdentifier())
    return II->getName();
  return "";
}

FunctionDecl::~FunctionDecl() {
  delete[] ParamInfo;
}

unsigned FunctionDecl::getNumParams() const {
  return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
}

void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
  assert(ParamInfo == 0 && "Already has param info!");
  assert(NumParams == getNumParams() && "Parameter count mismatch!");

  // Zero params -> null pointer.
  if (NumParams) {
    ParamInfo = new ParmVarDecl*[NumParams];
    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
  }
}

/// defineBody - When created, RecordDecl's correspond to a forward declared
/// record.  This method is used to mark the decl as being defined, with the
/// specified contents.
void RecordDecl::defineBody(FieldDecl **members, unsigned numMembers) {
  assert(!isDefinition() && "Cannot redefine record!");
  setDefinition(true);
  NumMembers = numMembers;
  if (numMembers) {
    Members = new FieldDecl*[numMembers];
    memcpy(Members, members, numMembers*sizeof(Decl*));
  }
}

FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
  if (Members == 0 || NumMembers < 0)
    return 0;

  // linear search. When C++ classes come along, will likely need to revisit.
  for (int i = 0; i < NumMembers; ++i) {
    if (Members[i]->getIdentifier() == name)
      return Members[i];
  }
  return 0;
}

void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
		       unsigned NumParams) {
  assert(ParamInfo == 0 && "Already has param info!");

  // Zero params -> null pointer.
  if (NumParams) {
    ParamInfo = new ParmVarDecl*[NumParams];
    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
    NumMethodParams = NumParams;
  }
}

ObjcMethodDecl::~ObjcMethodDecl() {
  delete[] ParamInfo;
}

/// ObjcAddInstanceVariablesToClass - Inserts instance variables
/// into ObjcInterfaceDecl's fields.
///
void ObjcInterfaceDecl::ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars,
					   		unsigned numIvars) {
  NumIvars = numIvars;
  if (numIvars) {
    Ivars = new ObjcIvarDecl*[numIvars];
    memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*));
  }
}

/// addObjcMethods - Insert instance and methods declarations into
/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
///
void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods,
				       unsigned numInsMembers,
                                       ObjcMethodDecl **clsMethods,
                                       unsigned numClsMembers) {
  NumInsMethods = numInsMembers;
  if (numInsMembers) {
    InsMethods = new ObjcMethodDecl*[numInsMembers];
    memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
  }
  NumClsMethods = numClsMembers;
  if (numClsMembers) {
    ClsMethods = new ObjcMethodDecl*[numClsMembers];
    memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
  }
}

<|endoftext|>


<commit_before>//
//  AppOnMap.cpp
//  ExampleApp
//

#include "AppOnMap.h"
#include "EegeoWorld.h"
#include "GlobeCameraTouchController.h"
#include "RenderCamera.h"
#include "GlobeCameraController.h"
#include "GlobeCameraInterestPointProvider.h"
#include "GlobeCameraController.h"
#include "CameraHelpers.h"
#include "WeatherController.h"
#include "NativeUIFactories.h"

#include "DebugSphereExample.h"
#include "ScreenUnprojectExample.h"
#include "LoadModelExample.h"
#include "EnvironmentNotifierExample.h"
#include "WebRequestExample.h"
#include "FileIOExample.h"
#include "NavigationGraphExample.h"
#include "ModifiedRenderingExample.h"
#include "ToggleTrafficExample.h"
#include "ResourceSpatialQueryExample.h"
#include "EnvironmentFlatteningExample.h"
#include "SearchExample.h"
#include "KeyboardInputExample.h"
#include "PODAnimationExample.h"
#include "Pick3DObjectExample.h"
#include "ScreenPickExample.h"

MyApp::MyApp(Eegeo::Camera::GlobeCamera::GlobeCameraInterestPointProvider& globeCameraInterestPointProvider,
             ExampleTypes::Examples selectedExample)
: m_globeCameraController(NULL)
, m_cameraTouchController(NULL)
, m_globeCameraInterestPointProvider(globeCameraInterestPointProvider)
, m_selectedExampleType(selectedExample)
, pExample(NULL)
{
    Eegeo_ASSERT(&m_globeCameraInterestPointProvider != NULL);
}

MyApp::~MyApp()
{
    pExample->Suspend();
    delete pExample;
    delete m_globeCameraController;
    delete m_cameraTouchController;
}

void MyApp::OnStart ()
{
    Eegeo_ASSERT(&World() != NULL);

    Eegeo::EegeoWorld& eegeoWorld = World();

    Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration touchControllerConfig = Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration::CreateDefault();

    // override default configuration to enable two-finger pan gesture to control additional camera pitch
    touchControllerConfig.tiltEnabled = true;

    m_cameraTouchController = new Eegeo::Camera::GlobeCamera::GlobeCameraTouchController(touchControllerConfig);

    const bool useLowSpecSettings = false;
    Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration globeCameraControllerConfig = Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration::CreateDefault(useLowSpecSettings);

    m_globeCameraController = new Eegeo::Camera::GlobeCamera::GlobeCameraController(eegeoWorld.GetTerrainHeightProvider(),
                                                                                eegeoWorld.GetEnvironmentFlatteningService(),
                                                                                eegeoWorld.GetResourceCeilingProvider(),
                                                                                *m_cameraTouchController,
                                                                                globeCameraControllerConfig);

    Eegeo::Camera::RenderCamera* renderCamera = m_globeCameraController->GetCamera();
    const Eegeo::Rendering::RenderContext& renderContext = eegeoWorld.GetRenderContext();
    renderCamera->SetViewport(0.f, 0.f, renderContext.GetScreenWidth(), renderContext.GetScreenHeight());
    eegeoWorld.SetCamera(renderCamera);

    m_globeCameraInterestPointProvider.SetGlobeCamera(m_globeCameraController);

    float interestPointLatitudeDegrees = 37.7858f;
    float interestPointLongitudeDegrees = -122.401f;
    float interestPointAltitudeMeters = 2.7;

    Eegeo::Space::LatLongAltitude location = Eegeo::Space::LatLongAltitude(interestPointLatitudeDegrees,
                                                                           interestPointLongitudeDegrees,
                                                                           interestPointAltitudeMeters,
                                                                           Eegeo::Space::LatLongUnits::Degrees);

    float cameraControllerOrientationDegrees = 0.0f;
    float cameraControllerDistanceFromInterestPointMeters = 1781.0f;

    Eegeo::Space::EcefTangentBasis cameraInterestBasis;
    Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(location.ToECEF(), cameraControllerOrientationDegrees, cameraInterestBasis);

    m_globeCameraController->SetView(cameraInterestBasis, cameraControllerDistanceFromInterestPointMeters);

    eegeoWorld.GetWeatherController().SetWeather(Eegeo::Weather::Sunny, 1.0f);

    Eegeo::Search::Service::SearchService* searchService = NULL;

    if (eegeoWorld.IsSearchServiceAvailable())
    {
        searchService = &eegeoWorld.GetSearchService();
    }

    pExample = CreateExample(m_selectedExampleType,
                             eegeoWorld.GetRenderContext(),
                             location,
                             eegeoWorld.GetCameraProvider(),
                             *m_globeCameraController,
                             *m_cameraTouchController,
                             eegeoWorld.GetTerrainHeightProvider(),
                             eegeoWorld.GetTextureLoader(),
                             eegeoWorld.GetFileIO(),
                             eegeoWorld.GetTerrainStreaming(),
                             eegeoWorld.GetWebRequestFactory(),
                             eegeoWorld.GetNavigationGraphRepository(),
                             eegeoWorld.GetBuildingMeshPool(),
                             eegeoWorld.GetShadowMeshPool(),
                             eegeoWorld.GetStreamingVolume(),
                             eegeoWorld.GetGlobalLighting(),
                             eegeoWorld.GetGlobalFogging(),
                             eegeoWorld.GetTrafficSimulation(),
                             eegeoWorld.GetResourceSpatialQueryService(),
                             eegeoWorld.GetEnvironmentFlatteningService(),
                             searchService,
                             eegeoWorld.GetNativeUIFactories(),
                             eegeoWorld.GetInterestPointProvider());

    pExample->Start();
}

void MyApp::Update (float dt)
{
    Eegeo::EegeoWorld& eegeoWorld = World();

    eegeoWorld.EarlyUpdate(dt);

    m_cameraTouchController->Update(dt);
    m_globeCameraController->Update(dt);

    eegeoWorld.Update(dt);
    pExample->Update();
}

void MyApp::Draw (float dt)
{
    Eegeo::Rendering::GLState& glState = World().GetRenderContext().GetGLState();
    glState.ClearColor(0.8f, 0.8f, 0.8f, 1.f);
    World().Draw(dt);
    pExample->Draw();
}

void MyApp::JumpTo(double latitudeDegrees, double longitudeDegrees, double altitudeMetres, double headingDegrees, double distanceToInterestMetres)
{
    Eegeo::dv3 interestPoint = Eegeo::Space::LatLongAltitude(latitudeDegrees, longitudeDegrees, altitudeMetres, Eegeo::Space::LatLongUnits::Degrees).ToECEF();

    Eegeo::Space::EcefTangentBasis interestBasis;

    Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(interestPoint, headingDegrees, interestBasis);

    m_globeCameraController->SetView(interestBasis, distanceToInterestMetres);
}

Examples::IExample* MyApp::CreateExample(ExampleTypes::Examples example,
                                         Eegeo::Rendering::RenderContext& renderContext,
                                         Eegeo::Space::LatLongAltitude interestLocation,
                                         Eegeo::Camera::ICameraProvider& cameraProvider,
                                         Eegeo::Camera::GlobeCamera::GlobeCameraController& globeCameraController,
                                         Eegeo::ITouchController& cameraTouchController,
                                         Eegeo::Resources::Terrain::Heights::TerrainHeightProvider& terrainHeightProvider,
                                         Eegeo::Helpers::ITextureFileLoader& textureLoader,
                                         Eegeo::Helpers::IFileIO& fileIO,
                                         Eegeo::Resources::Terrain::TerrainStreaming& terrainStreaming,
                                         Eegeo::Web::IWebLoadRequestFactory& webRequestFactory,
                                         Eegeo::Resources::Roads::Navigation::NavigationGraphRepository& navigationGraphs,
                                         Eegeo::Resources::MeshPool<Eegeo::Rendering::RenderableItem*>& buildingPool,
                                         Eegeo::Resources::MeshPool<Eegeo::Rendering::RenderableItem*>& shadowPool,
                                         Eegeo::Streaming::IStreamingVolume& visibleVolume,
                                         Eegeo::Lighting::GlobalLighting& lighting,
                                         Eegeo::Lighting::GlobalFogging& fogging,
                                         Eegeo::Traffic::TrafficSimulation& trafficSimulation,
                                         Eegeo::Resources::ResourceSpatialQueryService& resourceSpatialQueryService,
                                         Eegeo::Rendering::EnvironmentFlatteningService& environmentFlatteningService,
                                         Eegeo::Search::Service::SearchService* searchService,
                                         Eegeo::UI::NativeUIFactories& nativeInputFactories,
                                         Eegeo::Location::IInterestPointProvider& interestPointProvider)
{
    switch(example)
    {
        case ExampleTypes::LoadModel:
            return new Examples::LoadModelExample(renderContext,
                                                  interestLocation,
                                                  fileIO,
                                                  textureLoader,
                                                  fogging);
        case ExampleTypes::ScreenUnproject:
        case ExampleTypes::TerrainHeightQuery:
            return new Examples::ScreenUnprojectExample(renderContext,
                                                        cameraProvider,
                                                        terrainHeightProvider);

        case ExampleTypes::ScreenPick:
            return new Examples::ScreenPickExample(renderContext,
                                                   cameraProvider,
                                                   terrainHeightProvider);

        case ExampleTypes::DebugSphere:
            return new Examples::DebugSphereExample(renderContext,
                                                    interestLocation);
        case ExampleTypes::EnvironmentNotifier:
            return new Examples::EnvironmentNotifierExample(renderContext,
                                                            terrainStreaming);
        case ExampleTypes::WebRequest:
            return new Examples::WebRequestExample(webRequestFactory);

        case ExampleTypes::FileIO:
            return new Examples::FileIOExample(fileIO);

        case ExampleTypes::NavigationGraph:
            return new Examples::NavigationGraphExample(renderContext,
                                                        navigationGraphs);

        case ExampleTypes::ModifiedRendering:
            return new Examples::ModifiedRenderingExample(renderContext,
                                                          cameraProvider,
                                                          interestPointProvider,
                                                          visibleVolume,
                                                          lighting,
                                                          buildingPool,
                                                          shadowPool);

        case ExampleTypes::ToggleTraffic:
            return new Examples::ToggleTrafficExample(trafficSimulation);

        case ExampleTypes::ResourceSpatialQuery:
            return new Examples::ResourceSpatialQueryExample(resourceSpatialQueryService,
                                                             interestPointProvider);

        case ExampleTypes::EnvironmentFlattening:
            return new Examples::EnvironmentFlatteningExample(environmentFlatteningService);

        case ExampleTypes::Search:
            Eegeo_ASSERT(searchService != NULL, "Cannot run Search example, you must set up here.com Credentials in ViewController.mm");
            return new Examples::SearchExample(*searchService, interestPointProvider);

        case ExampleTypes::KeyboardInput:
            return new Examples::KeyboardInputExample(nativeInputFactories.IKeyboardInputFactory());

        case ExampleTypes::PODAnimation:
            return new Examples::PODAnimationExample(renderContext,
                                                     fileIO,
                                                     textureLoader,
                                                     fogging);
        case ExampleTypes::Pick3DObject:
            return new Examples::Pick3DObjectExample(renderContext,
                                                     interestLocation,
                                                     cameraProvider);

    }
}

void MyApp::Event_TouchRotate(const AppInterface::RotateData& data)
{
    if(!pExample->Event_TouchRotate(data))
    {
        m_cameraTouchController->Event_TouchRotate(data);
    }
}

void MyApp::Event_TouchRotate_Start(const AppInterface::RotateData& data)
{
    if(!pExample->Event_TouchRotate_Start(data))
    {
        m_cameraTouchController->Event_TouchRotate_Start(data);
    }
}

void MyApp::Event_TouchRotate_End(const AppInterface::RotateData& data)
{
    if(!pExample->Event_TouchRotate_End(data))
    {
        m_cameraTouchController->Event_TouchRotate_End(data);
    }
}

void MyApp::Event_TouchPinch(const AppInterface::PinchData& data)
{
    if(!pExample->Event_TouchPinch(data))
    {
        m_cameraTouchController->Event_TouchPinch(data);
    }
}

void MyApp::Event_TouchPinch_Start(const AppInterface::PinchData& data)
{
    if(!pExample->Event_TouchPinch_Start(data))
    {
        m_cameraTouchController->Event_TouchPinch_Start(data);
    }
}

void MyApp::Event_TouchPinch_End(const AppInterface::PinchData& data)
{
    if(!pExample->Event_TouchPinch_End(data))
    {
        m_cameraTouchController->Event_TouchPinch_End(data);
    }
}

void MyApp::Event_TouchPan(const AppInterface::PanData& data)
{
    if(!pExample->Event_TouchPan(data))
    {
        m_cameraTouchController->Event_TouchPan(data);
    }
}

void MyApp::Event_TouchPan_Start(const AppInterface::PanData& data)
{
    if(!pExample->Event_TouchPan_Start(data))
    {
        m_cameraTouchController->Event_TouchPan_Start(data);
    }
}

void MyApp::Event_TouchPan_End(const AppInterface::PanData& data)
{
    if(!pExample->Event_TouchPan_End(data))
    {
        m_cameraTouchController->Event_TouchPan_End(data);
    }
}

void MyApp::Event_TouchTap(const AppInterface::TapData& data)
{
    if(!pExample->Event_TouchTap(data))
    {
        m_cameraTouchController->Event_TouchTap(data);
    }
}

void MyApp::Event_TouchDoubleTap(const AppInterface::TapData& data)
{
    if(!pExample->Event_TouchDoubleTap(data))
    {
        m_cameraTouchController->Event_TouchDoubleTap(data);
    }
}

void MyApp::Event_TouchDown(const AppInterface::TouchData& data)
{
    if(!pExample->Event_TouchDown(data))
    {
        m_cameraTouchController->Event_TouchDown(data);
    }
}

void MyApp::Event_TouchMove(const AppInterface::TouchData& data)
{
    if(!pExample->Event_TouchMove(data))
    {
        m_cameraTouchController->Event_TouchMove(data);
    }
}

void MyApp::Event_TouchUp(const AppInterface::TouchData& data)
{
    if(!pExample->Event_TouchUp(data))
    {
        m_cameraTouchController->Event_TouchUp(data);
    }
}

<commit_msg>Update lat long creation to use factory methods. Buddy: Malc B<commit_after>//
//  AppOnMap.cpp
//  ExampleApp
//

#include "AppOnMap.h"
#include "EegeoWorld.h"
#include "GlobeCameraTouchController.h"
#include "RenderCamera.h"
#include "GlobeCameraController.h"
#include "GlobeCameraInterestPointProvider.h"
#include "GlobeCameraController.h"
#include "CameraHelpers.h"
#include "WeatherController.h"
#include "NativeUIFactories.h"

#include "DebugSphereExample.h"
#include "ScreenUnprojectExample.h"
#include "LoadModelExample.h"
#include "EnvironmentNotifierExample.h"
#include "WebRequestExample.h"
#include "FileIOExample.h"
#include "NavigationGraphExample.h"
#include "ModifiedRenderingExample.h"
#include "ToggleTrafficExample.h"
#include "ResourceSpatialQueryExample.h"
#include "EnvironmentFlatteningExample.h"
#include "SearchExample.h"
#include "KeyboardInputExample.h"
#include "PODAnimationExample.h"
#include "Pick3DObjectExample.h"
#include "ScreenPickExample.h"

MyApp::MyApp(Eegeo::Camera::GlobeCamera::GlobeCameraInterestPointProvider& globeCameraInterestPointProvider,
             ExampleTypes::Examples selectedExample)
: m_globeCameraController(NULL)
, m_cameraTouchController(NULL)
, m_globeCameraInterestPointProvider(globeCameraInterestPointProvider)
, m_selectedExampleType(selectedExample)
, pExample(NULL)
{
    Eegeo_ASSERT(&m_globeCameraInterestPointProvider != NULL);
}

MyApp::~MyApp()
{
    pExample->Suspend();
    delete pExample;
    delete m_globeCameraController;
    delete m_cameraTouchController;
}

void MyApp::OnStart ()
{
    Eegeo_ASSERT(&World() != NULL);

    Eegeo::EegeoWorld& eegeoWorld = World();

    Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration touchControllerConfig = Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration::CreateDefault();

    // override default configuration to enable two-finger pan gesture to control additional camera pitch
    touchControllerConfig.tiltEnabled = true;

    m_cameraTouchController = new Eegeo::Camera::GlobeCamera::GlobeCameraTouchController(touchControllerConfig);

    const bool useLowSpecSettings = false;
    Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration globeCameraControllerConfig = Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration::CreateDefault(useLowSpecSettings);

    m_globeCameraController = new Eegeo::Camera::GlobeCamera::GlobeCameraController(eegeoWorld.GetTerrainHeightProvider(),
                                                                                eegeoWorld.GetEnvironmentFlatteningService(),
                                                                                eegeoWorld.GetResourceCeilingProvider(),
                                                                                *m_cameraTouchController,
                                                                                globeCameraControllerConfig);

    Eegeo::Camera::RenderCamera* renderCamera = m_globeCameraController->GetCamera();
    const Eegeo::Rendering::RenderContext& renderContext = eegeoWorld.GetRenderContext();
    renderCamera->SetViewport(0.f, 0.f, renderContext.GetScreenWidth(), renderContext.GetScreenHeight());
    eegeoWorld.SetCamera(renderCamera);

    m_globeCameraInterestPointProvider.SetGlobeCamera(m_globeCameraController);

    float interestPointLatitudeDegrees = 37.7858f;
    float interestPointLongitudeDegrees = -122.401f;
    float interestPointAltitudeMeters = 2.7;

    Eegeo::Space::LatLongAltitude location = Eegeo::Space::LatLongAltitude::FromDegrees(interestPointLatitudeDegrees,
                                                                                interestPointLongitudeDegrees,
                                                                                interestPointAltitudeMeters);

    float cameraControllerOrientationDegrees = 0.0f;
    float cameraControllerDistanceFromInterestPointMeters = 1781.0f;

    Eegeo::Space::EcefTangentBasis cameraInterestBasis;
    Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(location.ToECEF(), cameraControllerOrientationDegrees, cameraInterestBasis);

    m_globeCameraController->SetView(cameraInterestBasis, cameraControllerDistanceFromInterestPointMeters);

    eegeoWorld.GetWeatherController().SetWeather(Eegeo::Weather::Sunny, 1.0f);

    Eegeo::Search::Service::SearchService* searchService = NULL;

    if (eegeoWorld.IsSearchServiceAvailable())
    {
        searchService = &eegeoWorld.GetSearchService();
    }

    pExample = CreateExample(m_selectedExampleType,
                             eegeoWorld.GetRenderContext(),
                             location,
                             eegeoWorld.GetCameraProvider(),
                             *m_globeCameraController,
                             *m_cameraTouchController,
                             eegeoWorld.GetTerrainHeightProvider(),
                             eegeoWorld.GetTextureLoader(),
                             eegeoWorld.GetFileIO(),
                             eegeoWorld.GetTerrainStreaming(),
                             eegeoWorld.GetWebRequestFactory(),
                             eegeoWorld.GetNavigationGraphRepository(),
                             eegeoWorld.GetBuildingMeshPool(),
                             eegeoWorld.GetShadowMeshPool(),
                             eegeoWorld.GetStreamingVolume(),
                             eegeoWorld.GetGlobalLighting(),
                             eegeoWorld.GetGlobalFogging(),
                             eegeoWorld.GetTrafficSimulation(),
                             eegeoWorld.GetResourceSpatialQueryService(),
                             eegeoWorld.GetEnvironmentFlatteningService(),
                             searchService,
                             eegeoWorld.GetNativeUIFactories(),
                             eegeoWorld.GetInterestPointProvider());

    pExample->Start();
}

void MyApp::Update (float dt)
{
    Eegeo::EegeoWorld& eegeoWorld = World();

    eegeoWorld.EarlyUpdate(dt);

    m_cameraTouchController->Update(dt);
    m_globeCameraController->Update(dt);

    eegeoWorld.Update(dt);
    pExample->Update();
}

void MyApp::Draw (float dt)
{
    Eegeo::Rendering::GLState& glState = World().GetRenderContext().GetGLState();
    glState.ClearColor(0.8f, 0.8f, 0.8f, 1.f);
    World().Draw(dt);
    pExample->Draw();
}

void MyApp::JumpTo(double latitudeDegrees, double longitudeDegrees, double altitudeMetres, double headingDegrees, double distanceToInterestMetres)
{
    Eegeo::dv3 interestPoint = Eegeo::Space::LatLongAltitude::FromDegrees(latitudeDegrees, longitudeDegrees, altitudeMetres).ToECEF();

    Eegeo::Space::EcefTangentBasis interestBasis;

    Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(interestPoint, headingDegrees, interestBasis);

    m_globeCameraController->SetView(interestBasis, distanceToInterestMetres);
}

Examples::IExample* MyApp::CreateExample(ExampleTypes::Examples example,
                                         Eegeo::Rendering::RenderContext& renderContext,
                                         Eegeo::Space::LatLongAltitude interestLocation,
                                         Eegeo::Camera::ICameraProvider& cameraProvider,
                                         Eegeo::Camera::GlobeCamera::GlobeCameraController& globeCameraController,
                                         Eegeo::ITouchController& cameraTouchController,
                                         Eegeo::Resources::Terrain::Heights::TerrainHeightProvider& terrainHeightProvider,
                                         Eegeo::Helpers::ITextureFileLoader& textureLoader,
                                         Eegeo::Helpers::IFileIO& fileIO,
                                         Eegeo::Resources::Terrain::TerrainStreaming& terrainStreaming,
                                         Eegeo::Web::IWebLoadRequestFactory& webRequestFactory,
                                         Eegeo::Resources::Roads::Navigation::NavigationGraphRepository& navigationGraphs,
                                         Eegeo::Resources::MeshPool<Eegeo::Rendering::RenderableItem*>& buildingPool,
                                         Eegeo::Resources::MeshPool<Eegeo::Rendering::RenderableItem*>& shadowPool,
                                         Eegeo::Streaming::IStreamingVolume& visibleVolume,
                                         Eegeo::Lighting::GlobalLighting& lighting,
                                         Eegeo::Lighting::GlobalFogging& fogging,
                                         Eegeo::Traffic::TrafficSimulation& trafficSimulation,
                                         Eegeo::Resources::ResourceSpatialQueryService& resourceSpatialQueryService,
                                         Eegeo::Rendering::EnvironmentFlatteningService& environmentFlatteningService,
                                         Eegeo::Search::Service::SearchService* searchService,
                                         Eegeo::UI::NativeUIFactories& nativeInputFactories,
                                         Eegeo::Location::IInterestPointProvider& interestPointProvider)
{
    switch(example)
    {
        case ExampleTypes::LoadModel:
            return new Examples::LoadModelExample(renderContext,
                                                  interestLocation,
                                                  fileIO,
                                                  textureLoader,
                                                  fogging);
        case ExampleTypes::ScreenUnproject:
        case ExampleTypes::TerrainHeightQuery:
            return new Examples::ScreenUnprojectExample(renderContext,
                                                        cameraProvider,
                                                        terrainHeightProvider);

        case ExampleTypes::ScreenPick:
            return new Examples::ScreenPickExample(renderContext,
                                                   cameraProvider,
                                                   terrainHeightProvider);

        case ExampleTypes::DebugSphere:
            return new Examples::DebugSphereExample(renderContext,
                                                    interestLocation);
        case ExampleTypes::EnvironmentNotifier:
            return new Examples::EnvironmentNotifierExample(renderContext,
                                                            terrainStreaming);
        case ExampleTypes::WebRequest:
            return new Examples::WebRequestExample(webRequestFactory);

        case ExampleTypes::FileIO:
            return new Examples::FileIOExample(fileIO);

        case ExampleTypes::NavigationGraph:
            return new Examples::NavigationGraphExample(renderContext,
                                                        navigationGraphs);

        case ExampleTypes::ModifiedRendering:
            return new Examples::ModifiedRenderingExample(renderContext,
                                                          cameraProvider,
                                                          interestPointProvider,
                                                          visibleVolume,
                                                          lighting,
                                                          buildingPool,
                                                          shadowPool);

        case ExampleTypes::ToggleTraffic:
            return new Examples::ToggleTrafficExample(trafficSimulation);

        case ExampleTypes::ResourceSpatialQuery:
            return new Examples::ResourceSpatialQueryExample(resourceSpatialQueryService,
                                                             interestPointProvider);

        case ExampleTypes::EnvironmentFlattening:
            return new Examples::EnvironmentFlatteningExample(environmentFlatteningService);

        case ExampleTypes::Search:
            Eegeo_ASSERT(searchService != NULL, "Cannot run Search example, you must set up here.com Credentials in ViewController.mm");
            return new Examples::SearchExample(*searchService, interestPointProvider);

        case ExampleTypes::KeyboardInput:
            return new Examples::KeyboardInputExample(nativeInputFactories.IKeyboardInputFactory());

        case ExampleTypes::PODAnimation:
            return new Examples::PODAnimationExample(renderContext,
                                                     fileIO,
                                                     textureLoader,
                                                     fogging);
        case ExampleTypes::Pick3DObject:
            return new Examples::Pick3DObjectExample(renderContext,
                                                     interestLocation,
                                                     cameraProvider);

    }
}

void MyApp::Event_TouchRotate(const AppInterface::RotateData& data)
{
    if(!pExample->Event_TouchRotate(data))
    {
        m_cameraTouchController->Event_TouchRotate(data);
    }
}

void MyApp::Event_TouchRotate_Start(const AppInterface::RotateData& data)
{
    if(!pExample->Event_TouchRotate_Start(data))
    {
        m_cameraTouchController->Event_TouchRotate_Start(data);
    }
}

void MyApp::Event_TouchRotate_End(const AppInterface::RotateData& data)
{
    if(!pExample->Event_TouchRotate_End(data))
    {
        m_cameraTouchController->Event_TouchRotate_End(data);
    }
}

void MyApp::Event_TouchPinch(const AppInterface::PinchData& data)
{
    if(!pExample->Event_TouchPinch(data))
    {
        m_cameraTouchController->Event_TouchPinch(data);
    }
}

void MyApp::Event_TouchPinch_Start(const AppInterface::PinchData& data)
{
    if(!pExample->Event_TouchPinch_Start(data))
    {
        m_cameraTouchController->Event_TouchPinch_Start(data);
    }
}

void MyApp::Event_TouchPinch_End(const AppInterface::PinchData& data)
{
    if(!pExample->Event_TouchPinch_End(data))
    {
        m_cameraTouchController->Event_TouchPinch_End(data);
    }
}

void MyApp::Event_TouchPan(const AppInterface::PanData& data)
{
    if(!pExample->Event_TouchPan(data))
    {
        m_cameraTouchController->Event_TouchPan(data);
    }
}

void MyApp::Event_TouchPan_Start(const AppInterface::PanData& data)
{
    if(!pExample->Event_TouchPan_Start(data))
    {
        m_cameraTouchController->Event_TouchPan_Start(data);
    }
}

void MyApp::Event_TouchPan_End(const AppInterface::PanData& data)
{
    if(!pExample->Event_TouchPan_End(data))
    {
        m_cameraTouchController->Event_TouchPan_End(data);
    }
}

void MyApp::Event_TouchTap(const AppInterface::TapData& data)
{
    if(!pExample->Event_TouchTap(data))
    {
        m_cameraTouchController->Event_TouchTap(data);
    }
}

void MyApp::Event_TouchDoubleTap(const AppInterface::TapData& data)
{
    if(!pExample->Event_TouchDoubleTap(data))
    {
        m_cameraTouchController->Event_TouchDoubleTap(data);
    }
}

void MyApp::Event_TouchDown(const AppInterface::TouchData& data)
{
    if(!pExample->Event_TouchDown(data))
    {
        m_cameraTouchController->Event_TouchDown(data);
    }
}

void MyApp::Event_TouchMove(const AppInterface::TouchData& data)
{
    if(!pExample->Event_TouchMove(data))
    {
        m_cameraTouchController->Event_TouchMove(data);
    }
}

void MyApp::Event_TouchUp(const AppInterface::TouchData& data)
{
    if(!pExample->Event_TouchUp(data))
    {
        m_cameraTouchController->Event_TouchUp(data);
    }
}

<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 */
#include <cstdint>
#include <cstring>

#include <array>
#include <limits>
#include <stdexcept>
#include <vector>

#include <adios2.h>
#include <adios2/common/ADIOSTypes.h>

#include <gtest/gtest.h>

std::string engineName; // comes from command line

class ADIOSSelectionTest : public ::testing::Test
{
public:
    ADIOSSelectionTest() = default;
};

void copySelection3D(const double *a, const adios2::Dims &shape,
                     const adios2::Dims &start, const adios2::Dims &count,
                     double *b)
{
    /*std::cout << " copy Block: shape = " << adios2::ToString(shape)
              << " start = " << adios2::ToString(start)
              << " count = " << adios2::ToString(count) << std::endl;*/
    double *bp = b;
    for (size_t x = 0; x < count[0]; ++x)
    {
        for (size_t y = 0; y < count[1]; ++y)
        {
            for (size_t z = 0; z < count[2]; ++z)
            {
                const size_t aidx = (start[0] + x) * shape[1] * shape[2] +
                                    (start[1] + y) * shape[2] + start[2] + z;
                /*if (x == 0 && y == 0 && z == 0)
                {
                    std::cout << " idx of pos = " << adios2::ToString({x, y, z})
                              << " => " << aidx << ", a = " << a[aidx]
                              << std::endl;
                }*/
                *bp = a[aidx];
                ++bp;
            }
        }
    }
}

bool compareSelection3D(const double *a, const adios2::Dims &shape,
                        const adios2::Dims &start, const adios2::Dims &count,
                        double *b, adios2::Dims &firstNonEqPoint)
{
    std::cout << " compare Block: shape = " << adios2::ToString(shape)
              << " start = " << adios2::ToString(start)
              << " count = " << adios2::ToString(count) << std::endl;
    double *bp = b;
    for (size_t x = 0; x < count[0]; ++x)
    {
        for (size_t y = 0; y < count[1]; ++y)
        {
            for (size_t z = 0; z < count[2]; ++z)
            {
                const size_t aidx = (start[0] + x) * shape[1] * shape[2] +
                                    (start[1] + y) * shape[2] + start[2] + z;

                if (*bp != a[aidx])
                {
                    firstNonEqPoint = {x, y, z};
                    return false;
                }
                ++bp;
            }
        }
    }
    return true;
}

TEST_F(ADIOSSelectionTest, 3D)
{
    constexpr size_t DIM1 = 15;
    constexpr size_t DIM2 = 12;
    constexpr size_t DIM3 = 9;
    const std::string filename = "ADIOSSelection3D.bp";
    const adios2::Dims shape = {DIM1, DIM2, DIM3};
    const adios2::Dims count = {5, 4, 3};
    double a[DIM1 * DIM2 * DIM3];

    double *ap = a;
    for (size_t x = 1; x <= DIM1; ++x)
    {
        for (size_t y = 1; y <= DIM2; ++y)
        {
            for (size_t z = 1; z <= DIM3; ++z)
            {
                *ap = x * 1.0 + y / 100.0 + z / 1000.0;
                ++ap;
            }
        }
    }
    /* ./bin/bpls -la testing/adios2/engine/bp/bp4/ADIOSSelection3D.bp
        -d a -n 9 -f "%6.3f"
    */

    adios2::ADIOS adios;
    // Write test data using BP
    {
        adios2::IO ioWrite = adios.DeclareIO("TestIOWrite");
        if (!engineName.empty())
        {
            ioWrite.SetEngine(engineName);
        }
        else
        {
            // Create the BP Engine
            ioWrite.SetEngine("BPFile");
        }

        adios2::Engine engine = ioWrite.Open(filename, adios2::Mode::Write);
        adios2::Dims start{0, 0, 0};
        double b[count[0] * count[1] * count[2]];

        adios2::Variable<double> var =
            ioWrite.DefineVariable<double>("a", shape, start, count);

        /*adios2::Variable<double> vara1 =
            ioWrite.DefineVariable<double>("a1", shape, start, shape);*/

        engine.BeginStep();
        /*engine.Put(vara1, a);*/

        for (size_t x = 0; x < DIM1; x += count[0])
        {
            for (size_t y = 0; y < DIM2; y += count[1])
            {
                for (size_t z = 0; z < DIM3; z += count[2])
                {
                    start = {x, y, z};
                    copySelection3D(a, shape, start, count, b);
                    var.SetSelection({start, count});
                    engine.Put(var, b, adios2::Mode::Sync);
                }
            }
        }

        engine.EndStep();
        engine.Close();
    }

    // Read data
    {
        adios2::IO ioRead = adios.DeclareIO("TestIORead");
        ioRead.SetEngine("File");
        adios2::Engine engine = ioRead.Open(filename, adios2::Mode::Read);
        EXPECT_TRUE(engine);
        engine.BeginStep();
        adios2::Variable<double> var = ioRead.InquireVariable<double>("a");
        EXPECT_TRUE(var);
        adios2::Dims s{0, 0, 0};
        adios2::Dims c = shape;
        adios2::Dims firstNonMatch{0, 0, 0};
        std::vector<double> res;

        /* Entire array */
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), DIM1 * DIM2 * DIM3);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Single block in the center */
        s = {5, 4, 3};
        c = count;
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Two blocks in X direction */
        s = {5, 4, 3};
        c = {2 * count[0], count[1], count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Three blocks in Y direction */
        s = {5, 0, 3};
        c = {count[0], 3 * count[1], count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Two blocks in Z direction */
        s = {5, 4, 0};
        c = {count[0], count[1], 2 * count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Four blocks in X-Z direction */
        s = {5, 4, 3};
        c = {2 * count[0], count[1], 2 * count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* 8 blocks in X-Y-Z direction */
        s = {5, 4, 3};
        c = {2 * count[0], 2 * count[1], 2 * count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /*
         *   Partial blocks
         */

        /* center part of single block in center */
        s = {6, 5, 4};
        c = {count[0] - 2, count[1] - 2, count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into two blocks in X direction */
        s = {6, 5, 4};
        c = {2 * count[0] - 2, count[1] - 1, count[2] - 1};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into two blocks in Y direction */
        s = {6, 5, 4};
        c = {count[0] - 1, 2 * count[1] - 2, count[2] - 1};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into three blocks in Y direction
           while contiguous in Z direction, making the read of the
           center of the three blocks as a single contiguous 4xYxZ copy */
        s = {6, 1, 3};
        c = {count[0] - 1, 3 * count[1] - 2, count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into two blocks in Z direction */
        s = {6, 5, 4};
        c = {count[0] - 1, count[1] - 1, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into four blocks in X-Y direction */
        s = {1, 5, 4};
        c = {2 * count[0] - 2, 2 * count[1] - 2, count[2] - 1};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into four blocks in X-Z direction */
        s = {1, 5, 4};
        c = {2 * count[0] - 2, count[1] - 2, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into four blocks in Y-Z direction */
        s = {6, 5, 4};
        c = {count[0] - 2, 2 * count[1] - 2, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into six blocks in X-Z direction */
        s = {1, 5, 4};
        c = {3 * count[0] - 2, count[1] - 2, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Center block plus 1 in each direction, cutting into all blocks */
        /* ./bin/bpls -la testing/adios2/engine/bp/bp4/ADIOSSelection3D.bp
            -d a  -f "%6.3f " -s "4,3,2" -c "7,6,5" -n 5
        */
        s = {4, 3, 2};
        c = {count[0] + 2, count[1] + 2, count[2] + 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        engine.EndStep();
        engine.Close();
    }
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    if (argc > 1)
    {
        engineName = std::string(argv[1]);
    }
    int result = RUN_ALL_TESTS();
    return result;
}
<commit_msg>fix windows build<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 */
#include <cstdint>
#include <cstring>

#include <array>
#include <limits>
#include <stdexcept>
#include <vector>

#include <adios2.h>
#include <adios2/common/ADIOSTypes.h>

#include <gtest/gtest.h>

std::string engineName; // comes from command line

class ADIOSSelectionTest : public ::testing::Test
{
public:
    ADIOSSelectionTest() = default;
};

void copySelection3D(const double *a, const adios2::Dims &shape,
                     const adios2::Dims &start, const adios2::Dims &count,
                     double *b)
{
    /*std::cout << " copy Block: shape = " << adios2::ToString(shape)
              << " start = " << adios2::ToString(start)
              << " count = " << adios2::ToString(count) << std::endl;*/
    double *bp = b;
    for (size_t x = 0; x < count[0]; ++x)
    {
        for (size_t y = 0; y < count[1]; ++y)
        {
            for (size_t z = 0; z < count[2]; ++z)
            {
                const size_t aidx = (start[0] + x) * shape[1] * shape[2] +
                                    (start[1] + y) * shape[2] + start[2] + z;
                /*if (x == 0 && y == 0 && z == 0)
                {
                    std::cout << " idx of pos = " << adios2::ToString({x, y, z})
                              << " => " << aidx << ", a = " << a[aidx]
                              << std::endl;
                }*/
                *bp = a[aidx];
                ++bp;
            }
        }
    }
}

bool compareSelection3D(const double *a, const adios2::Dims &shape,
                        const adios2::Dims &start, const adios2::Dims &count,
                        double *b, adios2::Dims &firstNonEqPoint)
{
    std::cout << " compare Block: shape = " << adios2::ToString(shape)
              << " start = " << adios2::ToString(start)
              << " count = " << adios2::ToString(count) << std::endl;
    double *bp = b;
    for (size_t x = 0; x < count[0]; ++x)
    {
        for (size_t y = 0; y < count[1]; ++y)
        {
            for (size_t z = 0; z < count[2]; ++z)
            {
                const size_t aidx = (start[0] + x) * shape[1] * shape[2] +
                                    (start[1] + y) * shape[2] + start[2] + z;

                if (*bp != a[aidx])
                {
                    firstNonEqPoint = {x, y, z};
                    return false;
                }
                ++bp;
            }
        }
    }
    return true;
}

TEST_F(ADIOSSelectionTest, 3D)
{
    constexpr size_t C1 = 5;
    constexpr size_t C2 = 4;
    constexpr size_t C3 = 3;
    constexpr size_t DIM1 = 3 * C1;
    constexpr size_t DIM2 = 3 * C2;
    constexpr size_t DIM3 = 3 * C3;
    const std::string filename = "ADIOSSelection3D.bp";
    const adios2::Dims shape = {DIM1, DIM2, DIM3};
    const adios2::Dims count = {C1, C2, C3};
    double a[DIM1 * DIM2 * DIM3];

    double *ap = a;
    for (size_t x = 1; x <= DIM1; ++x)
    {
        for (size_t y = 1; y <= DIM2; ++y)
        {
            for (size_t z = 1; z <= DIM3; ++z)
            {
                *ap = x * 1.0 + y / 100.0 + z / 1000.0;
                ++ap;
            }
        }
    }
    /* ./bin/bpls -la testing/adios2/engine/bp/bp4/ADIOSSelection3D.bp
        -d a -n 9 -f "%6.3f"
    */

    adios2::ADIOS adios;
    // Write test data using BP
    {
        adios2::IO ioWrite = adios.DeclareIO("TestIOWrite");
        if (!engineName.empty())
        {
            ioWrite.SetEngine(engineName);
        }
        else
        {
            // Create the BP Engine
            ioWrite.SetEngine("BPFile");
        }

        adios2::Engine engine = ioWrite.Open(filename, adios2::Mode::Write);
        adios2::Dims start{0, 0, 0};
        double b[C1 * C2 * C3];

        adios2::Variable<double> var =
            ioWrite.DefineVariable<double>("a", shape, start, count);

        /*adios2::Variable<double> vara1 =
            ioWrite.DefineVariable<double>("a1", shape, start, shape);*/

        engine.BeginStep();
        /*engine.Put(vara1, a);*/

        for (size_t x = 0; x < DIM1; x += count[0])
        {
            for (size_t y = 0; y < DIM2; y += count[1])
            {
                for (size_t z = 0; z < DIM3; z += count[2])
                {
                    start = {x, y, z};
                    copySelection3D(a, shape, start, count, b);
                    var.SetSelection({start, count});
                    engine.Put(var, b, adios2::Mode::Sync);
                }
            }
        }

        engine.EndStep();
        engine.Close();
    }

    // Read data
    {
        adios2::IO ioRead = adios.DeclareIO("TestIORead");
        ioRead.SetEngine("File");
        adios2::Engine engine = ioRead.Open(filename, adios2::Mode::Read);
        EXPECT_TRUE(engine);
        engine.BeginStep();
        adios2::Variable<double> var = ioRead.InquireVariable<double>("a");
        EXPECT_TRUE(var);
        adios2::Dims s{0, 0, 0};
        adios2::Dims c = shape;
        adios2::Dims firstNonMatch{0, 0, 0};
        std::vector<double> res;

        /* Entire array */
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), DIM1 * DIM2 * DIM3);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Single block in the center */
        s = {5, 4, 3};
        c = count;
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Two blocks in X direction */
        s = {5, 4, 3};
        c = {2 * count[0], count[1], count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Three blocks in Y direction */
        s = {5, 0, 3};
        c = {count[0], 3 * count[1], count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Two blocks in Z direction */
        s = {5, 4, 0};
        c = {count[0], count[1], 2 * count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Four blocks in X-Z direction */
        s = {5, 4, 3};
        c = {2 * count[0], count[1], 2 * count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* 8 blocks in X-Y-Z direction */
        s = {5, 4, 3};
        c = {2 * count[0], 2 * count[1], 2 * count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /*
         *   Partial blocks
         */

        /* center part of single block in center */
        s = {6, 5, 4};
        c = {count[0] - 2, count[1] - 2, count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into two blocks in X direction */
        s = {6, 5, 4};
        c = {2 * count[0] - 2, count[1] - 1, count[2] - 1};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into two blocks in Y direction */
        s = {6, 5, 4};
        c = {count[0] - 1, 2 * count[1] - 2, count[2] - 1};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into three blocks in Y direction
           while contiguous in Z direction, making the read of the
           center of the three blocks as a single contiguous 4xYxZ copy */
        s = {6, 1, 3};
        c = {count[0] - 1, 3 * count[1] - 2, count[2]};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into two blocks in Z direction */
        s = {6, 5, 4};
        c = {count[0] - 1, count[1] - 1, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into four blocks in X-Y direction */
        s = {1, 5, 4};
        c = {2 * count[0] - 2, 2 * count[1] - 2, count[2] - 1};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into four blocks in X-Z direction */
        s = {1, 5, 4};
        c = {2 * count[0] - 2, count[1] - 2, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into four blocks in Y-Z direction */
        s = {6, 5, 4};
        c = {count[0] - 2, 2 * count[1] - 2, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* partial selection cutting into six blocks in X-Z direction */
        s = {1, 5, 4};
        c = {3 * count[0] - 2, count[1] - 2, 2 * count[2] - 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        /* Center block plus 1 in each direction, cutting into all blocks */
        /* ./bin/bpls -la testing/adios2/engine/bp/bp4/ADIOSSelection3D.bp
            -d a  -f "%6.3f " -s "4,3,2" -c "7,6,5" -n 5
        */
        s = {4, 3, 2};
        c = {count[0] + 2, count[1] + 2, count[2] + 2};
        var.SetSelection({s, c});
        engine.Get<double>(var, res, adios2::Mode::Sync);
        EXPECT_EQ(res.size(), c[0] * c[1] * c[2]);
        EXPECT_TRUE(
            compareSelection3D(a, shape, s, c, res.data(), firstNonMatch));

        engine.EndStep();
        engine.Close();
    }
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    if (argc > 1)
    {
        engineName = std::string(argv[1]);
    }
    int result = RUN_ALL_TESTS();
    return result;
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/idle_timer.h"
#include "base/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::Time;
using base::TimeDelta;
using base::IdleTimer;

namespace {

// We Mock the GetLastInputInfo function to return
// the time stored here.
static Time mock_timer_started;

bool MockIdleTimeSource(int32 *milliseconds_interval_since_last_event) {
  TimeDelta delta = Time::Now() - mock_timer_started;
  *milliseconds_interval_since_last_event =
      static_cast<int32>(delta.InMilliseconds());
  return true;
}

// TestIdle task fires after 100ms of idle time.
class TestIdleTask : public IdleTimer {
 public:
  TestIdleTask(bool repeat)
      : IdleTimer(TimeDelta::FromMilliseconds(100), repeat),
        idle_counter_(0) {
        set_idle_time_source(MockIdleTimeSource);
  }

  int get_idle_counter() { return idle_counter_; }

  virtual void OnIdle() {
    idle_counter_++;
  }

 private:
  int idle_counter_;
};

// A task to help us quit the test.
class TestFinishedTask {
 public:
  TestFinishedTask() {}
  void Run() {
    MessageLoop::current()->Quit();
  }
};

// A timer which resets the idle clock.
class ResetIdleTask {
 public:
  ResetIdleTask() {}
  void Run() {
    mock_timer_started = Time::Now();
  }
};

class IdleTimerTest : public testing::Test {
 private:
  // IdleTimer requires a UI message loop on the current thread.
  MessageLoopForUI message_loop_;
};

///////////////////////////////////////////////////////////////////////////////
// NoRepeat tests:
// A non-repeating idle timer will fire once on idle, and
// then will not fire again unless it goes non-idle first.

TEST_F(IdleTimerTest, NoRepeatIdle) {
  // Create an IdleTimer, which should fire once after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Verify that we fired exactly once.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(false);

  TestFinishedTask finish_task;
  base::OneShotTimer<TestFinishedTask> timer;
  timer.Start(TimeDelta::FromSeconds(1), &finish_task, &TestFinishedTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  EXPECT_EQ(test_task.get_idle_counter(), 1);
}

TEST_F(IdleTimerTest, NoRepeatFlipIdleOnce) {
  // Create an IdleTimer, which should fire once after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a timer to reset once, idle after 500ms.
  // Verify that we fired exactly twice.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(false);

  TestFinishedTask finish_task;
  ResetIdleTask reset_task;

  base::OneShotTimer<TestFinishedTask> t1;
  t1.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
           &TestFinishedTask::Run);

  base::OneShotTimer<ResetIdleTask> t2;
  t2.Start(TimeDelta::FromMilliseconds(500), &reset_task,
           &ResetIdleTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  EXPECT_EQ(test_task.get_idle_counter(), 2);
}

TEST_F(IdleTimerTest, NoRepeatNotIdle) {
  // Create an IdleTimer, which should fire once after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a timer to reset idle every 50ms.
  // Verify that we never fired.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(false);

  TestFinishedTask finish_task;
  ResetIdleTask reset_task;

  base::OneShotTimer<TestFinishedTask> t;
  t.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
          &TestFinishedTask::Run);

  base::RepeatingTimer<ResetIdleTask> reset_timer;
  reset_timer.Start(TimeDelta::FromMilliseconds(50), &reset_task,
                    &ResetIdleTask::Run);

  test_task.Start();

  MessageLoop::current()->Run();

  reset_timer.Stop();

  EXPECT_EQ(test_task.get_idle_counter(), 0);
}

///////////////////////////////////////////////////////////////////////////////
// Repeat tests:
// A repeating idle timer will fire repeatedly on each interval, as long
// as it has been idle.  So, if the machine remains idle, it will continue
// firing over and over.

TEST_F(IdleTimerTest, Repeat) {
  // Create an IdleTimer, which should fire repeatedly after 100ms.
  // Create a Quit timer which will fire after 1.05s.
  // Verify that we fired 10 times.
  mock_timer_started = Time::Now();
  TestIdleTask test_task(true);

  TestFinishedTask finish_task;

  base::OneShotTimer<TestFinishedTask> t;
  t.Start(TimeDelta::FromMilliseconds(1050), &finish_task,
          &TestFinishedTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  // In a perfect world, the idle_counter should be 10.  However,
  // since timers aren't guaranteed to fire perfectly, this can
  // be less.  Just expect more than 5 and no more than 10.
  EXPECT_GT(test_task.get_idle_counter(), 5);
  EXPECT_LE(test_task.get_idle_counter(), 10);
}

// TODO(darin):  http://code.google.com/p/chromium/issues/detail?id=3780
TEST_F(IdleTimerTest, DISABLED_RepeatIdleReset) {
  // Create an IdleTimer, which should fire repeatedly after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a reset timer, which fires after 550ms
  // Verify that we fired 9 times.
  mock_timer_started = Time::Now();
  TestIdleTask test_task(true);

  ResetIdleTask reset_task;
  TestFinishedTask finish_task;

  base::OneShotTimer<TestFinishedTask> t1;
  t1.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
           &TestFinishedTask::Run);

  base::OneShotTimer<ResetIdleTask> t2;
  t2.Start(TimeDelta::FromMilliseconds(550), &reset_task,
           &ResetIdleTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  // In a perfect world, the idle_counter should be 9.  However,
  // since timers aren't guaranteed to fire perfectly, this can
  // be less.  Just expect more than 5 and no more than 9.
  EXPECT_GT(test_task.get_idle_counter(), 5);
  EXPECT_LE(test_task.get_idle_counter(), 9);
}

TEST_F(IdleTimerTest, RepeatNotIdle) {
  // Create an IdleTimer, which should fire repeatedly after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a timer to reset idle every 50ms.
  // Verify that we never fired.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(true);

  TestFinishedTask finish_task;
  ResetIdleTask reset_task;

  base::OneShotTimer<TestFinishedTask> t;
  t.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
          &TestFinishedTask::Run);

  base::RepeatingTimer<ResetIdleTask> reset_timer;
  reset_timer.Start(TimeDelta::FromMilliseconds(50), &reset_task,
                    &ResetIdleTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  reset_timer.Stop();

  EXPECT_EQ(test_task.get_idle_counter(), 0);
}

}  // namespace
<commit_msg>Weee. More TODO(darin)s. :)<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/idle_timer.h"
#include "base/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::Time;
using base::TimeDelta;
using base::IdleTimer;

namespace {

// We Mock the GetLastInputInfo function to return
// the time stored here.
static Time mock_timer_started;

bool MockIdleTimeSource(int32 *milliseconds_interval_since_last_event) {
  TimeDelta delta = Time::Now() - mock_timer_started;
  *milliseconds_interval_since_last_event =
      static_cast<int32>(delta.InMilliseconds());
  return true;
}

// TestIdle task fires after 100ms of idle time.
class TestIdleTask : public IdleTimer {
 public:
  TestIdleTask(bool repeat)
      : IdleTimer(TimeDelta::FromMilliseconds(100), repeat),
        idle_counter_(0) {
        set_idle_time_source(MockIdleTimeSource);
  }

  int get_idle_counter() { return idle_counter_; }

  virtual void OnIdle() {
    idle_counter_++;
  }

 private:
  int idle_counter_;
};

// A task to help us quit the test.
class TestFinishedTask {
 public:
  TestFinishedTask() {}
  void Run() {
    MessageLoop::current()->Quit();
  }
};

// A timer which resets the idle clock.
class ResetIdleTask {
 public:
  ResetIdleTask() {}
  void Run() {
    mock_timer_started = Time::Now();
  }
};

class IdleTimerTest : public testing::Test {
 private:
  // IdleTimer requires a UI message loop on the current thread.
  MessageLoopForUI message_loop_;
};

///////////////////////////////////////////////////////////////////////////////
// NoRepeat tests:
// A non-repeating idle timer will fire once on idle, and
// then will not fire again unless it goes non-idle first.

TEST_F(IdleTimerTest, NoRepeatIdle) {
  // Create an IdleTimer, which should fire once after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Verify that we fired exactly once.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(false);

  TestFinishedTask finish_task;
  base::OneShotTimer<TestFinishedTask> timer;
  timer.Start(TimeDelta::FromSeconds(1), &finish_task, &TestFinishedTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  EXPECT_EQ(test_task.get_idle_counter(), 1);
}

TEST_F(IdleTimerTest, NoRepeatFlipIdleOnce) {
  // Create an IdleTimer, which should fire once after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a timer to reset once, idle after 500ms.
  // Verify that we fired exactly twice.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(false);

  TestFinishedTask finish_task;
  ResetIdleTask reset_task;

  base::OneShotTimer<TestFinishedTask> t1;
  t1.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
           &TestFinishedTask::Run);

  base::OneShotTimer<ResetIdleTask> t2;
  t2.Start(TimeDelta::FromMilliseconds(500), &reset_task,
           &ResetIdleTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  EXPECT_EQ(test_task.get_idle_counter(), 2);
}

// TODO(darin): http://crbug.com/3704
TEST_F(IdleTimerTest, DISABLED_NoRepeatNotIdle) {
  // Create an IdleTimer, which should fire once after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a timer to reset idle every 50ms.
  // Verify that we never fired.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(false);

  TestFinishedTask finish_task;
  ResetIdleTask reset_task;

  base::OneShotTimer<TestFinishedTask> t;
  t.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
          &TestFinishedTask::Run);

  base::RepeatingTimer<ResetIdleTask> reset_timer;
  reset_timer.Start(TimeDelta::FromMilliseconds(50), &reset_task,
                    &ResetIdleTask::Run);

  test_task.Start();

  MessageLoop::current()->Run();

  reset_timer.Stop();

  EXPECT_EQ(test_task.get_idle_counter(), 0);
}

///////////////////////////////////////////////////////////////////////////////
// Repeat tests:
// A repeating idle timer will fire repeatedly on each interval, as long
// as it has been idle.  So, if the machine remains idle, it will continue
// firing over and over.

TEST_F(IdleTimerTest, Repeat) {
  // Create an IdleTimer, which should fire repeatedly after 100ms.
  // Create a Quit timer which will fire after 1.05s.
  // Verify that we fired 10 times.
  mock_timer_started = Time::Now();
  TestIdleTask test_task(true);

  TestFinishedTask finish_task;

  base::OneShotTimer<TestFinishedTask> t;
  t.Start(TimeDelta::FromMilliseconds(1050), &finish_task,
          &TestFinishedTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  // In a perfect world, the idle_counter should be 10.  However,
  // since timers aren't guaranteed to fire perfectly, this can
  // be less.  Just expect more than 5 and no more than 10.
  EXPECT_GT(test_task.get_idle_counter(), 5);
  EXPECT_LE(test_task.get_idle_counter(), 10);
}

// TODO(darin):  http://crbug.com/3780
TEST_F(IdleTimerTest, DISABLED_RepeatIdleReset) {
  // Create an IdleTimer, which should fire repeatedly after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a reset timer, which fires after 550ms
  // Verify that we fired 9 times.
  mock_timer_started = Time::Now();
  TestIdleTask test_task(true);

  ResetIdleTask reset_task;
  TestFinishedTask finish_task;

  base::OneShotTimer<TestFinishedTask> t1;
  t1.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
           &TestFinishedTask::Run);

  base::OneShotTimer<ResetIdleTask> t2;
  t2.Start(TimeDelta::FromMilliseconds(550), &reset_task,
           &ResetIdleTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  // In a perfect world, the idle_counter should be 9.  However,
  // since timers aren't guaranteed to fire perfectly, this can
  // be less.  Just expect more than 5 and no more than 9.
  EXPECT_GT(test_task.get_idle_counter(), 5);
  EXPECT_LE(test_task.get_idle_counter(), 9);
}

// TODO(darin): http://crbug.com/3704
TEST_F(IdleTimerTest, DISABLED_RepeatNotIdle) {
  // Create an IdleTimer, which should fire repeatedly after 100ms.
  // Create a Quit timer which will fire after 1s.
  // Create a timer to reset idle every 50ms.
  // Verify that we never fired.

  mock_timer_started = Time::Now();
  TestIdleTask test_task(true);

  TestFinishedTask finish_task;
  ResetIdleTask reset_task;

  base::OneShotTimer<TestFinishedTask> t;
  t.Start(TimeDelta::FromMilliseconds(1000), &finish_task,
          &TestFinishedTask::Run);

  base::RepeatingTimer<ResetIdleTask> reset_timer;
  reset_timer.Start(TimeDelta::FromMilliseconds(50), &reset_task,
                    &ResetIdleTask::Run);

  test_task.Start();
  MessageLoop::current()->Run();

  reset_timer.Stop();

  EXPECT_EQ(test_task.get_idle_counter(), 0);
}

}  // namespace
<|endoftext|>