<commit_before>AliAnalysisTask *AddTask_caklein_LMEEPbPb_AOD(Char_t* outputFileName="LMEEoutput.root",
                                              TString configFile="Config_caklein_LMEEPbPb_AOD.C",
                                              Bool_t getFromAlien=kFALSE,
                                              Bool_t cutlibPreloaded=kFALSE,
                                              Int_t triggerNames=AliVEvent::kINT7,
                                              Int_t collCands=AliVEvent::kINT7,
                                              Int_t eventCut=0,
                                              Int_t wagonnr=0)
{
  Bool_t bESDANA=kFALSE; //Autodetect via InputHandler
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_caklein_LMEEPbPb_AOD", "No analysis manager found.");
    return 0;
  }
  cout << "NEW CLASSES USED" << std::endl;
  //  create task and add it to the manager
  //	gSystem->AddIncludePath("$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE");

  TString configBasePath("$TRAIN_ROOT/caklein_lowmass/");
  TString trainRoot=gSystem->Getenv("TRAIN_ROOT");
  if (trainRoot.IsNull()) configBasePath= "$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE/";

  //Load updated macros from private ALIEN path
  if (getFromAlien //&&
      && (!gSystem->Exec(Form("alien_cp alien:///alice/cern.ch/user/c/cklein/PWGDQ/dielectron/macrosLMEE/%s .", configFile.Data())))
      && (!gSystem->Exec("alien_cp alien:///alice/cern.ch/user/c/cklein/PWGDQ/dielectron/macrosLMEE/LMEECutLib_caklein.C ."))
      ) {
    cout << "Copy config from Alien" << std::endl;
    configBasePath=Form("%s/",gSystem->pwd());
  }

  // TString configFile("Config_caklein_LMEEPbPb_AOD.C");
  TString configLMEECutLib("LMEECutLib_caklein.C");
  TString configFilePath(configBasePath+configFile.Data());
  TString configLMEECutLibPath(configBasePath+configLMEECutLib);

  Bool_t err=kFALSE;
  if (!cutlibPreloaded) { // should not be needed but seems to be...
    std::cout << "Cutlib was not preloaded" << std::endl;
    err |= gROOT->LoadMacro(configLMEECutLibPath.Data());
    err |= gROOT->LoadMacro(configFilePath.Data());
  }
  else{
    std::cout << "Cutlib was preloaded in a previous task" << std::endl;
  }
  // err |= gROOT->LoadMacro(configFilePath.Data());
  if (err) { Error("AddTask_caklein_LMEEPbPb_AOD","Config(s) could not be loaded!"); return 0x0; }

  if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
    ::Info("AddTaskLMEEPbPb2011", "no dedicated AOD configuration");
  }
  else if (mgr->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()){
    ::Info("AddTaskLMEEPbPb2011AOD","switching on ESD specific code");
    bESDANA=kTRUE;
  }

  //Do we have an MC handler?
  Bool_t hasMC = (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler() != 0x0);

  cout << "Everything should be loaded by now" << endl;

  LMEECutLib* cutlib = new LMEECutLib();
  AliAnalysisTaskMultiDielectron *task=new AliAnalysisTaskMultiDielectron(Form("MultiDiEData%d", wagonnr));
  if (!hasMC) task->UsePhysicsSelection();
  task->SetTriggerMask(triggerNames); // Should be not doing ANYTHING!!!!
  task->SelectCollisionCandidates(collCands);

  task->SetEventFilter(cutlib->GetEventCuts(eventCut));
  // Note: event cuts are identical for all analysis 'cutDefinition's that run together!

  //add dielectron analysis with different cuts to the task
  for (Int_t i=0; i<nDie; ++i){ //nDie defined in config file
    //MB
    AliDielectron *diel_low = Config_caklein_LMEEPbPb_AOD(arrNames->At(i)->GetName(),hasMC,bESDANA);
    if(!diel_low)continue;
    task->AddDielectron(diel_low);
    printf("successfully added AliDielectron: %s\n",diel_low->GetName());
  }//loop

  mgr->AddTask(task);

  //create output container
  AliAnalysisDataContainer *coutput1 =
	mgr->CreateContainer(Form("caklein_LMEEPbPb_tree%d", wagonnr),
                       TTree::Class(),
                       AliAnalysisManager::kExchangeContainer,
                       outputFileName);

  AliAnalysisDataContainer *cOutputHist1 =
	mgr->CreateContainer(Form("caklein_LMEEPbPb_out%d", wagonnr),
                       TList::Class(),
                       AliAnalysisManager::kOutputContainer,
                       outputFileName);

  AliAnalysisDataContainer *cOutputHist2 =
	mgr->CreateContainer(Form("caklein_LMEEPbPb_CF%d", wagonnr),
                       TList::Class(),
                       AliAnalysisManager::kOutputContainer,
                       outputFileName);

  AliAnalysisDataContainer *cOutputHist3 =
	mgr->CreateContainer(Form("caklein_EventStatPbPb%d", wagonnr),
                       TH1D::Class(),
                       AliAnalysisManager::kOutputContainer,
                       outputFileName);

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<commit_msg>PWGDQ: Added centrality switch in Addtask<commit_after>AliAnalysisTask *AddTask_caklein_LMEEPbPb_AOD(Char_t* outputFileName="LMEEoutput.root",
                                              TString configFile="Config_caklein_LMEEPbPb_AOD.C",
                                              Bool_t getFromAlien=kFALSE,
                                              Bool_t cutlibPreloaded=kFALSE,
                                              Int_t triggerNames=AliVEvent::kINT7,
                                              Int_t collCands=AliVEvent::kINT7,
                                              Int_t eventCut=0,
                                              Int_t wagonnr=0,
                                              Int_t centrality=4 /* 3=minbias, 2=50-80, 1=10-50, 0=00-10 */)
{
  Bool_t bESDANA=kFALSE; //Autodetect via InputHandler
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_caklein_LMEEPbPb_AOD", "No analysis manager found.");
    return 0;
  }
  cout << "NEW CLASSES USED" << std::endl;
  //  create task and add it to the manager
  //	gSystem->AddIncludePath("$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE");

  TString configBasePath("$TRAIN_ROOT/caklein_lowmass/");
  TString trainRoot=gSystem->Getenv("TRAIN_ROOT");
  if (trainRoot.IsNull()) configBasePath= "$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE/";

  //Load updated macros from private ALIEN path
  if (getFromAlien //&&
      && (!gSystem->Exec(Form("alien_cp alien:///alice/cern.ch/user/c/cklein/PWGDQ/dielectron/macrosLMEE/%s .", configFile.Data())))
      && (!gSystem->Exec("alien_cp alien:///alice/cern.ch/user/c/cklein/PWGDQ/dielectron/macrosLMEE/LMEECutLib_caklein.C ."))
      ) {
    cout << "Copy config from Alien" << std::endl;
    configBasePath=Form("%s/",gSystem->pwd());
  }

  // TString configFile("Config_caklein_LMEEPbPb_AOD.C");
  TString configLMEECutLib("LMEECutLib_caklein.C");
  TString configFilePath(configBasePath+configFile.Data());
  TString configLMEECutLibPath(configBasePath+configLMEECutLib);

  Bool_t err=kFALSE;
  if (!cutlibPreloaded) { // should not be needed but seems to be...
    std::cout << "Cutlib was not preloaded" << std::endl;
    err |= gROOT->LoadMacro(configLMEECutLibPath.Data());
    err |= gROOT->LoadMacro(configFilePath.Data());
  }
  else{
    std::cout << "Cutlib was preloaded in a previous task" << std::endl;
  }
  // err |= gROOT->LoadMacro(configFilePath.Data());
  if (err) { Error("AddTask_caklein_LMEEPbPb_AOD","Config(s) could not be loaded!"); return 0x0; }

  if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
    ::Info("AddTaskLMEEPbPb2011", "no dedicated AOD configuration");
  }
  else if (mgr->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()){
    ::Info("AddTaskLMEEPbPb2011AOD","switching on ESD specific code");
    bESDANA=kTRUE;
  }

  //Do we have an MC handler?
  Bool_t hasMC = (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler() != 0x0);

  cout << "Everything should be loaded by now" << endl;

  LMEECutLib* cutlib = new LMEECutLib();
  AliAnalysisTaskMultiDielectron *task=new AliAnalysisTaskMultiDielectron(Form("MultiDiEData%d", wagonnr));
  if (!hasMC) task->UsePhysicsSelection();
  task->SetTriggerMask(triggerNames); // Should be not doing ANYTHING!!!!
  task->SelectCollisionCandidates(collCands);

  task->SetEventFilter(cutlib->GetEventCuts(eventCut));
  // Note: event cuts are identical for all analysis 'cutDefinition's that run together!

  //add dielectron analysis with different cuts to the task
  for (Int_t i=0; i<nDie; ++i){ //nDie defined in config file
    //MB
    AliDielectron *diel_low = Config_caklein_LMEEPbPb_AOD(arrNames->At(i)->GetName(),hasMC,bESDANA,centrality);
    if(!diel_low)continue;
    task->AddDielectron(diel_low);
    printf("successfully added AliDielectron: %s\n",diel_low->GetName());
  }//loop

  mgr->AddTask(task);

  //create output container
  AliAnalysisDataContainer *coutput1 =
	mgr->CreateContainer(Form("caklein_LMEEPbPb_tree%d", wagonnr),
                       TTree::Class(),
                       AliAnalysisManager::kExchangeContainer,
                       outputFileName);

  AliAnalysisDataContainer *cOutputHist1 =
	mgr->CreateContainer(Form("caklein_LMEEPbPb_out%d", wagonnr),
                       TList::Class(),
                       AliAnalysisManager::kOutputContainer,
                       outputFileName);

  AliAnalysisDataContainer *cOutputHist2 =
	mgr->CreateContainer(Form("caklein_LMEEPbPb_CF%d", wagonnr),
                       TList::Class(),
                       AliAnalysisManager::kOutputContainer,
                       outputFileName);

  AliAnalysisDataContainer *cOutputHist3 =
	mgr->CreateContainer(Form("caklein_EventStatPbPb%d", wagonnr),
                       TH1D::Class(),
                       AliAnalysisManager::kOutputContainer,
                       outputFileName);

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<|endoftext|>


<commit_before>#include "../base/SRC_FIRST.hpp"

#include "tile_renderer.hpp"
#include "window_handle.hpp"

#include "../graphics/opengl/opengl.hpp"
#include "../graphics/opengl/gl_render_context.hpp"
#include "../graphics/opengl/base_texture.hpp"

#include "../graphics/packets_queue.hpp"
#include "../graphics/defines.hpp"

#include "../std/bind.hpp"

#include "../indexer/scales.hpp"

#include "../base/logging.hpp"
#include "../base/condition.hpp"
#include "../base/shared_buffer_manager.hpp"

namespace
{
  class TileStructuresLockGuard
  {
  public:
    TileStructuresLockGuard(TileCache & tileCache, TileSet & tileSet)
      : m_tileCache(tileCache), m_tileSet(tileSet)
    {
      m_tileSet.Lock();
      m_tileCache.Lock();
    }

    ~TileStructuresLockGuard()
    {
      m_tileCache.Unlock();
      m_tileSet.Unlock();
    }

  private:
    TileCache & m_tileCache;
    TileSet & m_tileSet;
  };
}

TileRenderer::TileRenderer(
    size_t tileSize,
    string const & skinName,
    graphics::EDensity density,
    unsigned executorsCount,
    graphics::Color const & bgColor,
    RenderPolicy::TRenderFn const & renderFn,
    shared_ptr<graphics::RenderContext> const & primaryRC,
    shared_ptr<graphics::ResourceManager> const & rm,
    double visualScale,
    graphics::PacketsQueue ** packetsQueues
  ) : m_queue(executorsCount),
      m_tileSize(tileSize),
      m_renderFn(renderFn),
      m_skinName(skinName),
      m_density(density),
      m_bgColor(bgColor),
      m_sequenceID(0),
      m_isExiting(false),
      m_isPaused(false)
{
  m_resourceManager = rm;
  m_primaryContext = primaryRC;

  m_threadData.resize(m_queue.ExecutorsCount());

  LOG(LINFO, ("initializing ", m_queue.ExecutorsCount(), " rendering threads"));

  int tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
  int tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

  for (unsigned i = 0; i < m_threadData.size(); ++i)
  {
    if (!packetsQueues)
      m_threadData[i].m_renderContext.reset(m_primaryContext->createShared());

    Drawer::Params params;

    params.m_resourceManager = m_resourceManager;
    params.m_frameBuffer = make_shared_ptr(new graphics::gl::FrameBuffer());

    params.m_threadSlot = m_resourceManager->renderThreadSlot(i);
    params.m_visualScale = visualScale;
    if (packetsQueues != 0)
      params.m_renderQueue = packetsQueues[i];
    params.m_doUnbindRT = false;
    params.m_isSynchronized = false;
    params.m_skinName = m_skinName;
    params.m_density = m_density;
    params.m_renderContext = m_threadData[i].m_renderContext;
  /*  params.m_isDebugging = true;
    params.m_drawPathes = false ;
    params.m_drawAreas = false;
    params.m_drawTexts = false; */

    m_threadData[i].m_drawerParams = params;
    m_threadData[i].m_drawer = 0;
    m_threadData[i].m_threadSlot = params.m_threadSlot;

    m_threadData[i].m_dummyRT = m_resourceManager->createRenderTarget(2, 2);
    m_threadData[i].m_depthBuffer = make_shared_ptr(new graphics::gl::RenderBuffer(tileWidth, tileHeight, true));
  }

  m_queue.AddInitCommand(bind(&TileRenderer::InitializeThreadGL, this, _1));
  m_queue.AddFinCommand(bind(&TileRenderer::FinalizeThreadGL, this, _1));

  m_queue.Start();
}

TileRenderer::~TileRenderer()
{
  m_isExiting = true;

  //LOG(LDEBUG, ("UVRLOG : Cancel from ~TileRenderer"));
  m_queue.Cancel();

  for (size_t i = 0; i < m_threadData.size(); ++i)
    if (m_threadData[i].m_drawer)
      delete m_threadData[i].m_drawer;
}

void TileRenderer::InitializeThreadGL(core::CommandsQueue::Environment const & env)
{
  LOG(LINFO, ("initializing TileRenderer", env.threadNum(), "on it's own thread"));

  ThreadData & threadData = m_threadData[env.threadNum()];

  int tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
  int tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

  if (threadData.m_renderContext)
  {
    threadData.m_renderContext->makeCurrent();
    threadData.m_renderContext->startThreadDrawing(threadData.m_threadSlot);
  }
  threadData.m_drawer = new Drawer(threadData.m_drawerParams);
  threadData.m_drawer->onSize(tileWidth, tileHeight);
  threadData.m_drawer->screen()->setDepthBuffer(threadData.m_depthBuffer);
}

void TileRenderer::FinalizeThreadGL(core::CommandsQueue::Environment const & env)
{
  ThreadData & threadData = m_threadData[env.threadNum()];

  if (threadData.m_renderContext)
    threadData.m_renderContext->endThreadDrawing(threadData.m_threadSlot);
}

void TileRenderer::ReadPixels(graphics::PacketsQueue * glQueue, core::CommandsQueue::Environment const & env)
{
  ThreadData & threadData = m_threadData[env.threadNum()];

  Drawer * drawer = threadData.m_drawer;

  if (glQueue)
  {
    glQueue->processFn(bind(&TileRenderer::ReadPixels, this, (graphics::PacketsQueue*)0, ref(env)), true);
    return;
  }

  if (!env.isCancelled())
  {
    unsigned tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
    unsigned tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

    shared_ptr<vector<unsigned char> > buf = SharedBufferManager::instance().reserveSharedBuffer(tileWidth * tileHeight * 4);
    drawer->screen()->readPixels(m2::RectU(0, 0, tileWidth, tileHeight), &(buf->at(0)), true);
    SharedBufferManager::instance().freeSharedBuffer(tileWidth * tileHeight * 4, buf);
  }
}

void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
                           Tiler::RectInfo const & rectInfo,
                           int sequenceID)
{
  if (m_isPaused)
    return;

  /// commands from the previous sequence are ignored
  if (sequenceID < m_sequenceID)
  {
    //LOG(LDEBUG, ("UVRLOG : tile not rendered. SequenceID=", sequenceID, " m_SequenceID", m_sequenceID));
    return;
  }

  //LOG(LDEBUG, ("UVRLOG : start render tile m_SequenceID=", m_sequenceID));

  if (HasTile(rectInfo))
    return;

  ThreadData & threadData = m_threadData[env.threadNum()];

  graphics::PacketsQueue * glQueue = threadData.m_drawerParams.m_renderQueue;

  Drawer * drawer = threadData.m_drawer;

  ScreenBase frameScreen;

  unsigned tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
  unsigned tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

  m2::RectI renderRect(1, 1, tileWidth - 1, tileHeight - 1);

  frameScreen.OnSize(renderRect);

  shared_ptr<PaintEvent> paintEvent = make_shared_ptr(new PaintEvent(drawer, &env));

  graphics::TTexturePool * texturePool = m_resourceManager->texturePool(graphics::ERenderTargetTexture);

  shared_ptr<graphics::gl::BaseTexture> tileTarget = texturePool->Reserve();

  if (texturePool->IsCancelled())
    return;

  drawer->screen()->setRenderTarget(tileTarget);

  shared_ptr<graphics::Overlay> tileOverlay(new graphics::Overlay());
  tileOverlay->setCouldOverlap(true);

  drawer->screen()->setOverlay(tileOverlay);

  /// ensuring, that the render target is not bound as a texture

  threadData.m_dummyRT->makeCurrent(glQueue);

  drawer->beginFrame();
  drawer->clear(graphics::Color(m_bgColor.r, m_bgColor.g, m_bgColor.b, 0));
  drawer->screen()->setClipRect(renderRect);
  drawer->clear(m_bgColor);

/*  drawer->clear(graphics::Color(rand() % 32 + 128, rand() % 64 + 128, rand() % 32 + 128, 255));

  std::stringstream out;
  out << rectInfo.m_y << ", " << rectInfo.m_x << ", " << rectInfo.m_tileScale;

  drawer->screen()->drawText(graphics::FontDesc(12, graphics::Color(0, 0, 0, 255), true),
                             renderRect.Center(),
                             graphics::EPosCenter,
                             out.str(),
                             0,
                             false);*/
  frameScreen.SetFromRect(m2::AnyRectD(rectInfo.m_rect));

  m2::RectD selectRect;
  m2::RectD clipRect;

  double const inflationSize = 24 * drawer->VisualScale();
  frameScreen.PtoG(m2::Inflate(m2::RectD(renderRect), inflationSize, inflationSize), clipRect);
  frameScreen.PtoG(m2::RectD(renderRect), selectRect);

  m_renderFn(
        paintEvent,
        frameScreen,
        selectRect,
        clipRect,
        min(scales::GetUpperScale(), rectInfo.m_tileScale),
        rectInfo.m_tileScale <= scales::GetUpperScale()
        );

  drawer->endFrame();

  drawer->screen()->resetOverlay();

  /// filter out the overlay elements that are out of the bound rect for the tile
  if (!env.isCancelled())
    tileOverlay->clip(renderRect);

  drawer->screen()->finish();

  if (m_resourceManager->useReadPixelsToSynchronize())
    ReadPixels(glQueue, env);

  drawer->screen()->unbindRenderTarget();

  if (!env.isCancelled())
  {
    if (glQueue)
      glQueue->completeCommands();

    AddActiveTile(Tile(tileTarget,
                 tileOverlay,
                 frameScreen,
                 rectInfo,
                 0,
                 paintEvent->isEmptyDrawing(),
                 sequenceID));
  }
  else
  {
    if (!m_isExiting)
    {
      if (glQueue)
        glQueue->cancelCommands();

      texturePool->Free(tileTarget);
    }
  }
}

void TileRenderer::AddCommand(Tiler::RectInfo const & rectInfo, int sequenceID, core::CommandsQueue::Chain const & afterTileFns)
{
  SetSequenceID(sequenceID);

  core::CommandsQueue::Chain chain;
  chain.addCommand(bind(&TileRenderer::DrawTile, this, _1, rectInfo, sequenceID));
  chain.addCommand(afterTileFns);

  m_queue.AddCommand(chain);
}

void TileRenderer::CancelCommands()
{
  m_queue.CancelCommands();
}

void TileRenderer::ClearCommands()
{
  m_queue.Clear();
}

void TileRenderer::SetSequenceID(int sequenceID)
{
  m_sequenceID = sequenceID;
}

TileCache & TileRenderer::GetTileCache()
{
  return m_tileCache;
}

void TileRenderer::CacheActiveTile(Tiler::RectInfo const & rectInfo)
{
  TileStructuresLockGuard guard(m_tileCache, m_tileSet);
  if (m_tileSet.HasTile(rectInfo))
  {
    ASSERT(!m_tileCache.HasTile(rectInfo), (""));
    Tile tile = m_tileSet.GetTile(rectInfo);

    if (m_tileCache.CanFit() == 0)
    {
      LOG(LINFO, ("resizing tileCache to", m_tileCache.CacheSize() + 1, "elements"));
      m_tileCache.Resize(m_tileCache.CacheSize() + 1);
    }

    m_tileCache.AddTile(rectInfo, TileCache::Entry(tile, m_resourceManager));
    m_tileSet.RemoveTile(rectInfo);
  }
}

void TileRenderer::WaitForEmptyAndFinished()
{
  m_queue.Join();
}

bool TileRenderer::HasTile(Tiler::RectInfo const & rectInfo)
{
  TileStructuresLockGuard guard(m_tileCache, m_tileSet);

  if (m_tileSet.HasTile(rectInfo))
  {
    m_tileSet.SetTileSequenceID(rectInfo, m_sequenceID);
    return true;
  }
  TileCache & tileCache = GetTileCache();
  if (tileCache.HasTile(rectInfo))
    return true;

  return false;
}

void TileRenderer::SetIsPaused(bool flag)
{
  m_isPaused = flag;
}

void TileRenderer::AddActiveTile(Tile const & tile)
{
  TileStructuresLockGuard lock(m_tileCache, m_tileSet);

  Tiler::RectInfo const & key = tile.m_rectInfo;

  if (m_tileSet.HasTile(key) || m_tileCache.HasTile(key))
    m_resourceManager->texturePool(graphics::ERenderTargetTexture)->Free(tile.m_renderTarget);
  else
  {
    //LOG(LDEBUG, ("UVRLOG : Add tile to set s=", key.m_tileScale, " x=", key.m_x, " y=", key.m_y, " m_SequenceID=", m_sequenceID));
    m_tileSet.AddTile(tile);
  }
}

void TileRenderer::RemoveActiveTile(Tiler::RectInfo const & rectInfo, int sequenceID)
{
  TileStructuresLockGuard lock(m_tileCache, m_tileSet);

  if (m_tileSet.HasTile(rectInfo) && m_tileSet.GetTileSequenceID(rectInfo) <= sequenceID)
  {
    ASSERT(!m_tileCache.HasTile(rectInfo), ("Tile cannot be in tileSet and tileCache at the same time"));
    //LOG(LDEBUG, ("UVRLOG : Remove tile from set s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " m_SequenceID=", m_sequenceID));
    m_resourceManager->texturePool(graphics::ERenderTargetTexture)->Free(m_tileSet.GetTile(rectInfo).m_renderTarget);
    m_tileSet.RemoveTile(rectInfo);
  }
}

size_t TileRenderer::TileSize() const
{
  return m_tileSize;
}
<commit_msg>In this place we use shared_ptr, because it's creating of main Overlay, that control contains elements. Custom deleter, delete overlay with all elements<commit_after>#include "../base/SRC_FIRST.hpp"

#include "tile_renderer.hpp"
#include "window_handle.hpp"

#include "../graphics/opengl/opengl.hpp"
#include "../graphics/opengl/gl_render_context.hpp"
#include "../graphics/opengl/base_texture.hpp"

#include "../graphics/packets_queue.hpp"
#include "../graphics/defines.hpp"

#include "../std/bind.hpp"

#include "../indexer/scales.hpp"

#include "../base/logging.hpp"
#include "../base/condition.hpp"
#include "../base/shared_buffer_manager.hpp"

namespace
{
  class TileStructuresLockGuard
  {
  public:
    TileStructuresLockGuard(TileCache & tileCache, TileSet & tileSet)
      : m_tileCache(tileCache), m_tileSet(tileSet)
    {
      m_tileSet.Lock();
      m_tileCache.Lock();
    }

    ~TileStructuresLockGuard()
    {
      m_tileCache.Unlock();
      m_tileSet.Unlock();
    }

  private:
    TileCache & m_tileCache;
    TileSet & m_tileSet;
  };
}

TileRenderer::TileRenderer(
    size_t tileSize,
    string const & skinName,
    graphics::EDensity density,
    unsigned executorsCount,
    graphics::Color const & bgColor,
    RenderPolicy::TRenderFn const & renderFn,
    shared_ptr<graphics::RenderContext> const & primaryRC,
    shared_ptr<graphics::ResourceManager> const & rm,
    double visualScale,
    graphics::PacketsQueue ** packetsQueues
  ) : m_queue(executorsCount),
      m_tileSize(tileSize),
      m_renderFn(renderFn),
      m_skinName(skinName),
      m_density(density),
      m_bgColor(bgColor),
      m_sequenceID(0),
      m_isExiting(false),
      m_isPaused(false)
{
  m_resourceManager = rm;
  m_primaryContext = primaryRC;

  m_threadData.resize(m_queue.ExecutorsCount());

  LOG(LINFO, ("initializing ", m_queue.ExecutorsCount(), " rendering threads"));

  int tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
  int tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

  for (unsigned i = 0; i < m_threadData.size(); ++i)
  {
    if (!packetsQueues)
      m_threadData[i].m_renderContext.reset(m_primaryContext->createShared());

    Drawer::Params params;

    params.m_resourceManager = m_resourceManager;
    params.m_frameBuffer = make_shared_ptr(new graphics::gl::FrameBuffer());

    params.m_threadSlot = m_resourceManager->renderThreadSlot(i);
    params.m_visualScale = visualScale;
    if (packetsQueues != 0)
      params.m_renderQueue = packetsQueues[i];
    params.m_doUnbindRT = false;
    params.m_isSynchronized = false;
    params.m_skinName = m_skinName;
    params.m_density = m_density;
    params.m_renderContext = m_threadData[i].m_renderContext;
  /*  params.m_isDebugging = true;
    params.m_drawPathes = false ;
    params.m_drawAreas = false;
    params.m_drawTexts = false; */

    m_threadData[i].m_drawerParams = params;
    m_threadData[i].m_drawer = 0;
    m_threadData[i].m_threadSlot = params.m_threadSlot;

    m_threadData[i].m_dummyRT = m_resourceManager->createRenderTarget(2, 2);
    m_threadData[i].m_depthBuffer = make_shared_ptr(new graphics::gl::RenderBuffer(tileWidth, tileHeight, true));
  }

  m_queue.AddInitCommand(bind(&TileRenderer::InitializeThreadGL, this, _1));
  m_queue.AddFinCommand(bind(&TileRenderer::FinalizeThreadGL, this, _1));

  m_queue.Start();
}

TileRenderer::~TileRenderer()
{
  m_isExiting = true;

  //LOG(LDEBUG, ("UVRLOG : Cancel from ~TileRenderer"));
  m_queue.Cancel();

  for (size_t i = 0; i < m_threadData.size(); ++i)
    if (m_threadData[i].m_drawer)
      delete m_threadData[i].m_drawer;
}

void TileRenderer::InitializeThreadGL(core::CommandsQueue::Environment const & env)
{
  LOG(LINFO, ("initializing TileRenderer", env.threadNum(), "on it's own thread"));

  ThreadData & threadData = m_threadData[env.threadNum()];

  int tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
  int tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

  if (threadData.m_renderContext)
  {
    threadData.m_renderContext->makeCurrent();
    threadData.m_renderContext->startThreadDrawing(threadData.m_threadSlot);
  }
  threadData.m_drawer = new Drawer(threadData.m_drawerParams);
  threadData.m_drawer->onSize(tileWidth, tileHeight);
  threadData.m_drawer->screen()->setDepthBuffer(threadData.m_depthBuffer);
}

void TileRenderer::FinalizeThreadGL(core::CommandsQueue::Environment const & env)
{
  ThreadData & threadData = m_threadData[env.threadNum()];

  if (threadData.m_renderContext)
    threadData.m_renderContext->endThreadDrawing(threadData.m_threadSlot);
}

void TileRenderer::ReadPixels(graphics::PacketsQueue * glQueue, core::CommandsQueue::Environment const & env)
{
  ThreadData & threadData = m_threadData[env.threadNum()];

  Drawer * drawer = threadData.m_drawer;

  if (glQueue)
  {
    glQueue->processFn(bind(&TileRenderer::ReadPixels, this, (graphics::PacketsQueue*)0, ref(env)), true);
    return;
  }

  if (!env.isCancelled())
  {
    unsigned tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
    unsigned tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

    shared_ptr<vector<unsigned char> > buf = SharedBufferManager::instance().reserveSharedBuffer(tileWidth * tileHeight * 4);
    drawer->screen()->readPixels(m2::RectU(0, 0, tileWidth, tileHeight), &(buf->at(0)), true);
    SharedBufferManager::instance().freeSharedBuffer(tileWidth * tileHeight * 4, buf);
  }
}

void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
                           Tiler::RectInfo const & rectInfo,
                           int sequenceID)
{
  if (m_isPaused)
    return;

  /// commands from the previous sequence are ignored
  if (sequenceID < m_sequenceID)
  {
    //LOG(LDEBUG, ("UVRLOG : tile not rendered. SequenceID=", sequenceID, " m_SequenceID", m_sequenceID));
    return;
  }

  //LOG(LDEBUG, ("UVRLOG : start render tile m_SequenceID=", m_sequenceID));

  if (HasTile(rectInfo))
    return;

  ThreadData & threadData = m_threadData[env.threadNum()];

  graphics::PacketsQueue * glQueue = threadData.m_drawerParams.m_renderQueue;

  Drawer * drawer = threadData.m_drawer;

  ScreenBase frameScreen;

  unsigned tileWidth = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texWidth;
  unsigned tileHeight = m_resourceManager->params().m_textureParams[graphics::ERenderTargetTexture].m_texHeight;

  m2::RectI renderRect(1, 1, tileWidth - 1, tileHeight - 1);

  frameScreen.OnSize(renderRect);

  shared_ptr<PaintEvent> paintEvent = make_shared_ptr(new PaintEvent(drawer, &env));

  graphics::TTexturePool * texturePool = m_resourceManager->texturePool(graphics::ERenderTargetTexture);

  shared_ptr<graphics::gl::BaseTexture> tileTarget = texturePool->Reserve();

  if (texturePool->IsCancelled())
    return;

  drawer->screen()->setRenderTarget(tileTarget);

  shared_ptr<graphics::Overlay> tileOverlay(new graphics::Overlay(), graphics::Overlay::Deleter());
  tileOverlay->setCouldOverlap(true);

  drawer->screen()->setOverlay(tileOverlay.get());

  /// ensuring, that the render target is not bound as a texture

  threadData.m_dummyRT->makeCurrent(glQueue);

  drawer->beginFrame();
  drawer->clear(graphics::Color(m_bgColor.r, m_bgColor.g, m_bgColor.b, 0));
  drawer->screen()->setClipRect(renderRect);
  drawer->clear(m_bgColor);

/*  drawer->clear(graphics::Color(rand() % 32 + 128, rand() % 64 + 128, rand() % 32 + 128, 255));

  std::stringstream out;
  out << rectInfo.m_y << ", " << rectInfo.m_x << ", " << rectInfo.m_tileScale;

  drawer->screen()->drawText(graphics::FontDesc(12, graphics::Color(0, 0, 0, 255), true),
                             renderRect.Center(),
                             graphics::EPosCenter,
                             out.str(),
                             0,
                             false);*/
  frameScreen.SetFromRect(m2::AnyRectD(rectInfo.m_rect));

  m2::RectD selectRect;
  m2::RectD clipRect;

  double const inflationSize = 24 * drawer->VisualScale();
  frameScreen.PtoG(m2::Inflate(m2::RectD(renderRect), inflationSize, inflationSize), clipRect);
  frameScreen.PtoG(m2::RectD(renderRect), selectRect);

  m_renderFn(
        paintEvent,
        frameScreen,
        selectRect,
        clipRect,
        min(scales::GetUpperScale(), rectInfo.m_tileScale),
        rectInfo.m_tileScale <= scales::GetUpperScale()
        );

  drawer->endFrame();

  drawer->screen()->resetOverlay();

  /// filter out the overlay elements that are out of the bound rect for the tile
  if (!env.isCancelled())
    tileOverlay->clip(renderRect);

  drawer->screen()->finish();

  if (m_resourceManager->useReadPixelsToSynchronize())
    ReadPixels(glQueue, env);

  drawer->screen()->unbindRenderTarget();

  if (!env.isCancelled())
  {
    if (glQueue)
      glQueue->completeCommands();

    AddActiveTile(Tile(tileTarget,
                 tileOverlay,
                 frameScreen,
                 rectInfo,
                 0,
                 paintEvent->isEmptyDrawing(),
                 sequenceID));
  }
  else
  {
    if (!m_isExiting)
    {
      if (glQueue)
        glQueue->cancelCommands();

      texturePool->Free(tileTarget);
    }
  }
}

void TileRenderer::AddCommand(Tiler::RectInfo const & rectInfo, int sequenceID, core::CommandsQueue::Chain const & afterTileFns)
{
  SetSequenceID(sequenceID);

  core::CommandsQueue::Chain chain;
  chain.addCommand(bind(&TileRenderer::DrawTile, this, _1, rectInfo, sequenceID));
  chain.addCommand(afterTileFns);

  m_queue.AddCommand(chain);
}

void TileRenderer::CancelCommands()
{
  m_queue.CancelCommands();
}

void TileRenderer::ClearCommands()
{
  m_queue.Clear();
}

void TileRenderer::SetSequenceID(int sequenceID)
{
  m_sequenceID = sequenceID;
}

TileCache & TileRenderer::GetTileCache()
{
  return m_tileCache;
}

void TileRenderer::CacheActiveTile(Tiler::RectInfo const & rectInfo)
{
  TileStructuresLockGuard guard(m_tileCache, m_tileSet);
  if (m_tileSet.HasTile(rectInfo))
  {
    ASSERT(!m_tileCache.HasTile(rectInfo), (""));
    Tile tile = m_tileSet.GetTile(rectInfo);

    if (m_tileCache.CanFit() == 0)
    {
      LOG(LINFO, ("resizing tileCache to", m_tileCache.CacheSize() + 1, "elements"));
      m_tileCache.Resize(m_tileCache.CacheSize() + 1);
    }

    m_tileCache.AddTile(rectInfo, TileCache::Entry(tile, m_resourceManager));
    m_tileSet.RemoveTile(rectInfo);
  }
}

void TileRenderer::WaitForEmptyAndFinished()
{
  m_queue.Join();
}

bool TileRenderer::HasTile(Tiler::RectInfo const & rectInfo)
{
  TileStructuresLockGuard guard(m_tileCache, m_tileSet);

  if (m_tileSet.HasTile(rectInfo))
  {
    m_tileSet.SetTileSequenceID(rectInfo, m_sequenceID);
    return true;
  }
  TileCache & tileCache = GetTileCache();
  if (tileCache.HasTile(rectInfo))
    return true;

  return false;
}

void TileRenderer::SetIsPaused(bool flag)
{
  m_isPaused = flag;
}

void TileRenderer::AddActiveTile(Tile const & tile)
{
  TileStructuresLockGuard lock(m_tileCache, m_tileSet);

  Tiler::RectInfo const & key = tile.m_rectInfo;

  if (m_tileSet.HasTile(key) || m_tileCache.HasTile(key))
    m_resourceManager->texturePool(graphics::ERenderTargetTexture)->Free(tile.m_renderTarget);
  else
  {
    //LOG(LDEBUG, ("UVRLOG : Add tile to set s=", key.m_tileScale, " x=", key.m_x, " y=", key.m_y, " m_SequenceID=", m_sequenceID));
    m_tileSet.AddTile(tile);
  }
}

void TileRenderer::RemoveActiveTile(Tiler::RectInfo const & rectInfo, int sequenceID)
{
  TileStructuresLockGuard lock(m_tileCache, m_tileSet);

  if (m_tileSet.HasTile(rectInfo) && m_tileSet.GetTileSequenceID(rectInfo) <= sequenceID)
  {
    ASSERT(!m_tileCache.HasTile(rectInfo), ("Tile cannot be in tileSet and tileCache at the same time"));
    //LOG(LDEBUG, ("UVRLOG : Remove tile from set s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " m_SequenceID=", m_sequenceID));
    m_resourceManager->texturePool(graphics::ERenderTargetTexture)->Free(m_tileSet.GetTile(rectInfo).m_renderTarget);
    m_tileSet.RemoveTile(rectInfo);
  }
}

size_t TileRenderer::TileSize() const
{
  return m_tileSize;
}
<|endoftext|>


<commit_before>/*
** Copyright 2011-2012 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <cassert>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/exceptions/shutdown.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/rrd/cached.hh"
#include "com/centreon/broker/rrd/exceptions/open.hh"
#include "com/centreon/broker/rrd/exceptions/update.hh"
#include "com/centreon/broker/rrd/lib.hh"
#include "com/centreon/broker/rrd/output.hh"
#include "com/centreon/broker/storage/metric.hh"
#include "com/centreon/broker/storage/perfdata.hh"
#include "com/centreon/broker/storage/rebuild.hh"
#include "com/centreon/broker/storage/remove_graph.hh"
#include "com/centreon/broker/storage/status.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::rrd;

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Standard constructor.
 *
 *  @param[in] metrics_path Path in which metrics RRD files should be
 *                          written.
 *  @param[in] status_path  Path in which status RRD files should be
 *                          written.
 */
output::output(QString const& metrics_path, QString const& status_path)
  : _backend(new lib),
    _metrics_path(metrics_path),
    _process_out(true),
    _status_path(status_path) {}

/**
 *  Local socket constructor.
 *
 *  @param[in] metrics_path See standard constructor.
 *  @param[in] status_path  See standard constructor.
 *  @param[in] local        Local socket connection parameters.
 */
output::output(
          QString const& metrics_path,
          QString const& status_path,
          QString const& local)
  : _metrics_path(metrics_path),
    _process_out(true),
    _status_path(status_path) {
#if QT_VERSION >= 0x040400
  std::auto_ptr<cached> rrdcached(new cached);
  rrdcached->connect_local(local);
  _backend.reset(rrdcached.release());
#else
  throw (broker::exceptions::msg()
         << "RRD: local connection is not supported on Qt "
         << QT_VERSION_STR);
#endif // Qt version
}

/**
 *  Network socket constructor.
 *
 *  @param[in] metrics_path See standard constructor.
 *  @param[in] status_path  See standard constructor.
 *  @param[in] port         rrdcached listening port.
 */
output::output(QString const& metrics_path,
               QString const& status_path,
               unsigned short port)
  : _metrics_path(metrics_path),
    _process_out(true),
    _status_path(status_path) {
  std::auto_ptr<cached> rrdcached(new cached);
  rrdcached->connect_remote("localhost", port);
  _backend.reset(rrdcached.release());
}

/**
 *  Destructor.
 */
output::~output() {}

/**
 *  Set if output should be processed or not.
 *
 *  @param[in] in  Unused.
 *  @param[in] out Set to true to process output events.
 */
void output::process(bool in, bool out) {
  (void)in;
  _process_out = out;
  return ;
}

/**
 *  Read data.
 *
 *  @param[out] d Cleared.
 */
void output::read(misc::shared_ptr<io::data>& d) {
  d.clear();
  throw (broker::exceptions::msg()
           << "RRD: attempt to read data from an output endpoint");
  return ;
}

/**
 *  Write an event.
 *
 *  @param[in] d Data to write.
 */
void output::write(misc::shared_ptr<io::data> const& d) {
  // Check that data exists and should be processed.
  if (!_process_out)
    throw (io::exceptions::shutdown(true, true)
             << "RRD output is shutdown");
  if (d.isNull())
    return ;

  if (d->type() == "com::centreon::broker::storage::metric") {
    // Debug message.
    misc::shared_ptr<storage::metric>
      e(d.staticCast<storage::metric>());
    logging::debug(logging::medium) << "RRD: new data for metric "
      << e->metric_id << " (time " << e->ctime << ")";

    // Metric path.
    QString metric_path;
    {
      std::ostringstream oss;
      oss << _metrics_path.toStdString()
          << "/" << e->metric_id << ".rrd";
      metric_path = oss.str().c_str();
    }

    // Check that metric is not being rebuild.
    rebuild_cache::iterator it(_metrics_rebuild.find(metric_path));
    if (it == _metrics_rebuild.end()) {
      // Write metrics RRD.
      try {
        _backend->open(metric_path, e->name);
      }
      catch (exceptions::open const& b) {
        _backend->open(
          metric_path,
          e->name,
          e->rrd_len / (e->interval ? e->interval : 60) + 1,
          0,
          e->interval,
          e->value_type);
      }
      std::ostringstream oss;
      if (e->value_type != storage::perfdata::gauge)
        oss << static_cast<long long>(e->value);
      else
        oss << std::fixed << e->value;
      try {
        _backend->update(e->ctime, oss.str().c_str());
      }
      catch (exceptions::update const& b) {
        logging::error(logging::low) << b.what() << " (ignored)";
      }
    }
    else
      // Cache value.
      it->push_back(d);
  }
  else if (d->type() == "com::centreon::broker::storage::status") {
    // Debug message.
    misc::shared_ptr<storage::status>
      e(d.staticCast<storage::status>());
    logging::debug(logging::medium) << "RRD: new status data for index "
      << e->index_id << " (" << e->state << ")";

    // Status path.
    QString status_path;
    {
      std::ostringstream oss;
      oss << _status_path.toStdString()
          << "/" << e->index_id << ".rrd";
      status_path = oss.str().c_str();
    }

    // Check that status is not begin rebuild.
    rebuild_cache::iterator it(_status_rebuild.find(status_path));
    if (it == _status_rebuild.end()) {
      // Write status RRD.
      try {
        _backend->open(status_path, "status");
      }
      catch (exceptions::open const& b) {
        _backend->open(
          status_path,
          "status",
          e->rrd_len / (e->interval ? e->interval : 60),
          0,
          e->interval);
      }
      std::ostringstream oss;
      if (e->state == 0)
        oss << 100;
      else if (e->state == 1)
        oss << 75;
      else if (e->state == 2)
        oss << 0;
      try {
        _backend->update(e->ctime, oss.str().c_str());
      }
      catch (exceptions::update const& b) {
        logging::error(logging::medium) << b.what() << " (ignored)";
      }
    }
    else
      // Cache value.
      it->push_back(d);
  }
  else if (d->type() == "com::centreon::broker::storage::rebuild") {
    // Debug message.
    misc::shared_ptr<storage::rebuild>
      e(d.staticCast<storage::rebuild>());
    logging::debug(logging::medium) << "RRD: rebuild request for "
      << (e->is_index ? "index " : "metric ") << e->id
      << (e->end ? "(end)" : "(start)");

    // Generate path.
    QString path;
    {
      std::ostringstream oss;
      oss << (e->is_index ? _status_path : _metrics_path).toStdString()
          << "/" << e->id << ".rrd";
      path = oss.str().c_str();
    }

    // Rebuild is starting.
    if (!e->end) {
      if (e->is_index)
        _status_rebuild[path];
      else
        _metrics_rebuild[path];
    }
    // Rebuild is ending.
    else {
      // Find cache.
      std::list<misc::shared_ptr<io::data> > l;
      {
        rebuild_cache::iterator it;
        if (e->is_index) {
          it = _status_rebuild.find(path);
          if (it != _status_rebuild.end()) {
            l = *it;
            _status_rebuild.erase(it);
          }
        }
        else {
          it = _metrics_rebuild.find(path);
          if (it != _metrics_rebuild.end()) {
            l = *it;
            _metrics_rebuild.erase(it);
          }
        }
      }

      // Resend cache data.
      while (!l.empty()) {
        write(l.front());
        l.pop_front();
      }
    }
  }
  else if (d->type() == "com::centreon::broker::storage::remove_graph") {
    // Debug message.
    misc::shared_ptr<storage::remove_graph>
      e(d.staticCast<storage::remove_graph>());
    logging::debug(logging::medium) << "RRD: remove graph request for "
      << (e->is_index ? "index " : "metric ") << e->id;

    // Generate path.
    QString path;
    {
      std::ostringstream oss;
      oss << (e->is_index ? _status_path : _metrics_path).toStdString()
          << "/" << e->id << ".rrd";
      path = oss.str().c_str();
    }

    // Remove data from cache.
    rebuild_cache&
      cache(e->is_index ? _status_rebuild : _metrics_rebuild);
    rebuild_cache::iterator it(cache.find(path));
    if (it != cache.end())
      cache.erase(it);

    // Remove file.
    _backend->remove(path);
  }

  return ;
}

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  @brief Copy constructor.
 *
 *  Any call to this constructor will result in a call to abort().
 *
 *  @param[in] o Object to copy.
 */
output::output(output const& o) : io::stream(o) {
  assert(!"RRD output is not copyable");
  abort();
}

/**
 *  @brief Assignment operator.
 *
 *  Any call to this method will result in a call to abort().
 *
 *  @param[in] o Object to copy.
 *
 *  @return This object.
 */
output& output::operator=(output const& o) {
  (void)o;
  assert(!"RRD output is not copyable");
  abort();
  return (*this);
}
<commit_msg>RRD: remove file before rebuilding it.<commit_after>/*
** Copyright 2011-2012 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <cassert>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/exceptions/shutdown.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/rrd/cached.hh"
#include "com/centreon/broker/rrd/exceptions/open.hh"
#include "com/centreon/broker/rrd/exceptions/update.hh"
#include "com/centreon/broker/rrd/lib.hh"
#include "com/centreon/broker/rrd/output.hh"
#include "com/centreon/broker/storage/metric.hh"
#include "com/centreon/broker/storage/perfdata.hh"
#include "com/centreon/broker/storage/rebuild.hh"
#include "com/centreon/broker/storage/remove_graph.hh"
#include "com/centreon/broker/storage/status.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::rrd;

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Standard constructor.
 *
 *  @param[in] metrics_path Path in which metrics RRD files should be
 *                          written.
 *  @param[in] status_path  Path in which status RRD files should be
 *                          written.
 */
output::output(QString const& metrics_path, QString const& status_path)
  : _backend(new lib),
    _metrics_path(metrics_path),
    _process_out(true),
    _status_path(status_path) {}

/**
 *  Local socket constructor.
 *
 *  @param[in] metrics_path See standard constructor.
 *  @param[in] status_path  See standard constructor.
 *  @param[in] local        Local socket connection parameters.
 */
output::output(
          QString const& metrics_path,
          QString const& status_path,
          QString const& local)
  : _metrics_path(metrics_path),
    _process_out(true),
    _status_path(status_path) {
#if QT_VERSION >= 0x040400
  std::auto_ptr<cached> rrdcached(new cached);
  rrdcached->connect_local(local);
  _backend.reset(rrdcached.release());
#else
  throw (broker::exceptions::msg()
         << "RRD: local connection is not supported on Qt "
         << QT_VERSION_STR);
#endif // Qt version
}

/**
 *  Network socket constructor.
 *
 *  @param[in] metrics_path See standard constructor.
 *  @param[in] status_path  See standard constructor.
 *  @param[in] port         rrdcached listening port.
 */
output::output(QString const& metrics_path,
               QString const& status_path,
               unsigned short port)
  : _metrics_path(metrics_path),
    _process_out(true),
    _status_path(status_path) {
  std::auto_ptr<cached> rrdcached(new cached);
  rrdcached->connect_remote("localhost", port);
  _backend.reset(rrdcached.release());
}

/**
 *  Destructor.
 */
output::~output() {}

/**
 *  Set if output should be processed or not.
 *
 *  @param[in] in  Unused.
 *  @param[in] out Set to true to process output events.
 */
void output::process(bool in, bool out) {
  (void)in;
  _process_out = out;
  return ;
}

/**
 *  Read data.
 *
 *  @param[out] d Cleared.
 */
void output::read(misc::shared_ptr<io::data>& d) {
  d.clear();
  throw (broker::exceptions::msg()
           << "RRD: attempt to read data from an output endpoint");
  return ;
}

/**
 *  Write an event.
 *
 *  @param[in] d Data to write.
 */
void output::write(misc::shared_ptr<io::data> const& d) {
  // Check that data exists and should be processed.
  if (!_process_out)
    throw (io::exceptions::shutdown(true, true)
             << "RRD output is shutdown");
  if (d.isNull())
    return ;

  if (d->type() == "com::centreon::broker::storage::metric") {
    // Debug message.
    misc::shared_ptr<storage::metric>
      e(d.staticCast<storage::metric>());
    logging::debug(logging::medium) << "RRD: new data for metric "
      << e->metric_id << " (time " << e->ctime << ")";

    // Metric path.
    QString metric_path;
    {
      std::ostringstream oss;
      oss << _metrics_path.toStdString()
          << "/" << e->metric_id << ".rrd";
      metric_path = oss.str().c_str();
    }

    // Check that metric is not being rebuild.
    rebuild_cache::iterator it(_metrics_rebuild.find(metric_path));
    if (it == _metrics_rebuild.end()) {
      // Write metrics RRD.
      try {
        _backend->open(metric_path, e->name);
      }
      catch (exceptions::open const& b) {
        _backend->open(
          metric_path,
          e->name,
          e->rrd_len / (e->interval ? e->interval : 60) + 1,
          0,
          e->interval,
          e->value_type);
      }
      std::ostringstream oss;
      if (e->value_type != storage::perfdata::gauge)
        oss << static_cast<long long>(e->value);
      else
        oss << std::fixed << e->value;
      try {
        _backend->update(e->ctime, oss.str().c_str());
      }
      catch (exceptions::update const& b) {
        logging::error(logging::low) << b.what() << " (ignored)";
      }
    }
    else
      // Cache value.
      it->push_back(d);
  }
  else if (d->type() == "com::centreon::broker::storage::status") {
    // Debug message.
    misc::shared_ptr<storage::status>
      e(d.staticCast<storage::status>());
    logging::debug(logging::medium) << "RRD: new status data for index "
      << e->index_id << " (" << e->state << ")";

    // Status path.
    QString status_path;
    {
      std::ostringstream oss;
      oss << _status_path.toStdString()
          << "/" << e->index_id << ".rrd";
      status_path = oss.str().c_str();
    }

    // Check that status is not begin rebuild.
    rebuild_cache::iterator it(_status_rebuild.find(status_path));
    if (it == _status_rebuild.end()) {
      // Write status RRD.
      try {
        _backend->open(status_path, "status");
      }
      catch (exceptions::open const& b) {
        _backend->open(
          status_path,
          "status",
          e->rrd_len / (e->interval ? e->interval : 60),
          0,
          e->interval);
      }
      std::ostringstream oss;
      if (e->state == 0)
        oss << 100;
      else if (e->state == 1)
        oss << 75;
      else if (e->state == 2)
        oss << 0;
      try {
        _backend->update(e->ctime, oss.str().c_str());
      }
      catch (exceptions::update const& b) {
        logging::error(logging::medium) << b.what() << " (ignored)";
      }
    }
    else
      // Cache value.
      it->push_back(d);
  }
  else if (d->type() == "com::centreon::broker::storage::rebuild") {
    // Debug message.
    misc::shared_ptr<storage::rebuild>
      e(d.staticCast<storage::rebuild>());
    logging::debug(logging::medium) << "RRD: rebuild request for "
      << (e->is_index ? "index " : "metric ") << e->id
      << (e->end ? "(end)" : "(start)");

    // Generate path.
    QString path;
    {
      std::ostringstream oss;
      oss << (e->is_index ? _status_path : _metrics_path).toStdString()
          << "/" << e->id << ".rrd";
      path = oss.str().c_str();
    }

    // Rebuild is starting.
    if (!e->end) {
      if (e->is_index)
        _status_rebuild[path];
      else
        _metrics_rebuild[path];
      _backend->remove(path);
    }
    // Rebuild is ending.
    else {
      // Find cache.
      std::list<misc::shared_ptr<io::data> > l;
      {
        rebuild_cache::iterator it;
        if (e->is_index) {
          it = _status_rebuild.find(path);
          if (it != _status_rebuild.end()) {
            l = *it;
            _status_rebuild.erase(it);
          }
        }
        else {
          it = _metrics_rebuild.find(path);
          if (it != _metrics_rebuild.end()) {
            l = *it;
            _metrics_rebuild.erase(it);
          }
        }
      }

      // Resend cache data.
      while (!l.empty()) {
        write(l.front());
        l.pop_front();
      }
    }
  }
  else if (d->type() == "com::centreon::broker::storage::remove_graph") {
    // Debug message.
    misc::shared_ptr<storage::remove_graph>
      e(d.staticCast<storage::remove_graph>());
    logging::debug(logging::medium) << "RRD: remove graph request for "
      << (e->is_index ? "index " : "metric ") << e->id;

    // Generate path.
    QString path;
    {
      std::ostringstream oss;
      oss << (e->is_index ? _status_path : _metrics_path).toStdString()
          << "/" << e->id << ".rrd";
      path = oss.str().c_str();
    }

    // Remove data from cache.
    rebuild_cache&
      cache(e->is_index ? _status_rebuild : _metrics_rebuild);
    rebuild_cache::iterator it(cache.find(path));
    if (it != cache.end())
      cache.erase(it);

    // Remove file.
    _backend->remove(path);
  }

  return ;
}

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  @brief Copy constructor.
 *
 *  Any call to this constructor will result in a call to abort().
 *
 *  @param[in] o Object to copy.
 */
output::output(output const& o) : io::stream(o) {
  assert(!"RRD output is not copyable");
  abort();
}

/**
 *  @brief Assignment operator.
 *
 *  Any call to this method will result in a call to abort().
 *
 *  @param[in] o Object to copy.
 *
 *  @return This object.
 */
output& output::operator=(output const& o) {
  (void)o;
  assert(!"RRD output is not copyable");
  abort();
  return (*this);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: srcharg.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: ihi $ $Date: 2007-06-05 18:23:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef UCBDEMO_SRCHARG_HXX
#define UCBDEMO_SRCHARG_HXX

class String;
namespace com { namespace sun { namespace star { namespace ucb {
    struct SearchInfo;
} } } }

//============================================================================
bool parseSearchArgument(String const & rInput,
                         com::sun::star::ucb::SearchInfo & rInfo);

#endif // UCBDEMO_SRCHARG_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.3.72); FILE MERGED 2008/03/31 15:30:34 rt 1.3.72.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: srcharg.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef UCBDEMO_SRCHARG_HXX
#define UCBDEMO_SRCHARG_HXX

class String;
namespace com { namespace sun { namespace star { namespace ucb {
    struct SearchInfo;
} } } }

//============================================================================
bool parseSearchArgument(String const & rInput,
                         com::sun::star::ucb::SearchInfo & rInfo);

#endif // UCBDEMO_SRCHARG_HXX

<|endoftext|>


<commit_before>#include "ClientDataModel.hpp"

#include <graphene/app/api.hpp>
#include <graphene/chain/protocol/protocol.hpp>

#include <fc/rpc/websocket_api.hpp>

#include <QMetaObject>

using namespace graphene::app;

template<typename T>
QString idToString(T id) {
   return QString("%1.%2.%3").arg(T::space_id).arg(T::type_id).arg(ObjectId(id.instance));
}
QString idToString(graphene::db::object_id_type id) {
   return QString("%1.%2.%3").arg(id.space(), id.type(), ObjectId(id.instance()));
}

ChainDataModel::ChainDataModel(fc::thread& t, QObject* parent)
:QObject(parent),m_rpc_thread(&t){}

Asset* ChainDataModel::getAsset(ObjectId id)
{
   auto& by_id_idx = m_assets.get<by_id>();
   auto itr = by_id_idx.find(id);
   if (itr == by_id_idx.end())
   {
      auto result = m_assets.insert(new Asset(id, QString::number(--m_account_query_num), 0, this));
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this,id,result]{ getAssetImpl(idToString(asset_id_type(id)), &*result.first); });
      return *result.first;
   }
   return *itr;
}

Asset* ChainDataModel::getAsset(QString symbol)
{
   auto& by_symbol_idx = m_assets.get<by_symbol_name>();
   auto itr = by_symbol_idx.find(symbol);
   if (itr == by_symbol_idx.end())
   {
      auto result = m_assets.insert(new Asset(--m_account_query_num, symbol, 0, this));
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this,symbol,result](){ getAssetImpl(symbol, &*result.first); });
      return *result.first;
   }
   return *itr;
}

void ChainDataModel::getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer)
{
   try {
      ilog("Fetching asset ${asset}", ("asset", assetIdentifier.toStdString()));
      auto result = m_db_api->lookup_asset_symbols({assetIdentifier.toStdString()});

      // Run in main thread
      Q_EMIT queueExecute([this,result,assetInContainer](){
         ilog("Processing result ${r}", ("r", result));
         auto itr = m_assets.iterator_to(*assetInContainer);

         if (result.size() == 0 || !result.front()) {
            (*itr)->deleteLater();
            m_assets.erase(itr);
         } else {
            m_assets.modify(itr,
                            [=](Asset* a){
               a->setProperty("symbol", QString::fromStdString(result.front()->symbol));
               a->setProperty("id", ObjectId(result.front()->id.instance()));
               a->setProperty("precision", result.front()->precision);
            });
         }
      });
   }
   catch ( const fc::exception& e )
   {
      Q_EMIT exceptionThrown(QString::fromStdString(e.to_string()));
   }
}

void ChainDataModel::getAccountImpl(QString accountIdentifier, Account* const * accountInContainer)
{
   try {
      ilog("Fetching account ${acct}", ("acct", accountIdentifier.toStdString()));
      auto result = m_db_api->get_full_accounts([](const fc::variant& v) {
         idump((v));
      }, {accountIdentifier.toStdString()});
      fc::variant_object accountPackage;

      if (result.count(accountIdentifier.toStdString())) {
         accountPackage = result.begin()->second.as<variant_object>();

         // Fetch all necessary assets
         auto balances = accountPackage["balances"].as<vector<account_balance_object>>();
         QList<asset_id_type> assetsToFetch;
         QList<Asset* const *> assetPlaceholders;
         assetsToFetch.reserve(balances.size());
         // Get list of asset IDs the account has a balance in
         std::transform(balances.begin(), balances.end(), std::back_inserter(assetsToFetch),
                        [](const account_balance_object& b) { return b.asset_type; });
         auto function = [this,&assetsToFetch,&assetPlaceholders] {
            auto itr = assetsToFetch.begin();
            const auto& assets_by_id = m_assets.get<by_id>();
            // Filter out assets I already have, create placeholders for the ones I don't.
            while (itr != assetsToFetch.end()) {
               if (assets_by_id.count(itr->instance))
                  itr = assetsToFetch.erase(itr);
               else {
                  assetPlaceholders.push_back(&*m_assets.insert(new Asset(itr->instance, QString(), 0, this)).first);
                  ++itr;
               }
            }
         };
         QMetaObject::invokeMethod(parent(), "execute", Qt::BlockingQueuedConnection,
                                   Q_ARG(const std::function<void()>&, function));
         assert(assetsToFetch.size() == assetPlaceholders.size());

         // Blocking call to fetch and complete initialization for all the assets
         for (int i = 0; i < assetsToFetch.size(); ++i)
            getAssetImpl(idToString(assetsToFetch[i]), assetPlaceholders[i]);
      }

      // Run in main thread
      Q_EMIT queueExecute([this,accountPackage,accountInContainer](){
         ilog("Processing result ${r}", ("r", accountPackage));
         auto itr = m_accounts.iterator_to(*accountInContainer);

         if (!accountPackage.size()) {
            (*itr)->deleteLater();
            m_accounts.erase(itr);
         } else {
            m_accounts.modify(itr, [=](Account* a){
               account_object account = accountPackage["account"].as<account_object>();
               a->setProperty("id", ObjectId(account.id.instance()));
               a->setProperty("name", QString::fromStdString(account.name));

               // Set balances
               QList<Balance*> balances;
               auto balanceObjects = accountPackage["balances"].as<vector<account_balance_object>>();
               std::transform(balanceObjects.begin(), balanceObjects.end(), std::back_inserter(balances),
                              [this](const account_balance_object& b) {
                  Balance* bal = new Balance;
                  bal->setParent(this);
                  bal->setProperty("amount", QVariant::fromValue(b.balance.value));
                  bal->setProperty("type", QVariant::fromValue(getAsset(ObjectId(b.asset_type.instance))));
                  return bal;
               });
               a->setBalances(balances);
            });
         }
      });
   }
   catch (const fc::exception& e)
   {
      Q_EMIT exceptionThrown(QString::fromStdString(e.to_string()));
   }
}

Account* ChainDataModel::getAccount(ObjectId id)
{
   auto& by_id_idx = m_accounts.get<by_id>();
   auto itr = by_id_idx.find(id);
   if( itr == by_id_idx.end() )
   {
      auto tmp = new Account(id, tr("Account #%1").arg(--m_account_query_num), this);
      auto result = m_accounts.insert(tmp);
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this, id, result]{getAccountImpl(idToString(account_id_type(id)), &*result.first);});
      return *result.first;
   }
   return *itr;
}

Account* ChainDataModel::getAccount(QString name)
{
   auto& by_name_idx = m_accounts.get<by_account_name>();
   auto itr = by_name_idx.find(name);
   if( itr == by_name_idx.end() )
   {
      auto tmp = new Account(--m_account_query_num, name, this);
      auto result = m_accounts.insert(tmp);
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this, name, result]{getAccountImpl(name, &*result.first);});
      return *result.first;
   }
   return *itr;
}

QQmlListProperty<Balance> Account::balances()
{
   auto count = [](QQmlListProperty<Balance>* list) {
      return reinterpret_cast<Account*>(list->data)->m_balances.size();
   };
   auto at = [](QQmlListProperty<Balance>* list, int index) {
      return reinterpret_cast<Account*>(list->data)->m_balances[index];
   };

   return QQmlListProperty<Balance>(this, this, count, at);
}

GrapheneApplication::GrapheneApplication(QObject* parent)
:QObject(parent),m_thread("app")
{
   connect(this, &GrapheneApplication::queueExecute,
           this, &GrapheneApplication::execute);

   m_model = new ChainDataModel(m_thread, this);

   connect(m_model, &ChainDataModel::queueExecute,
           this, &GrapheneApplication::execute);

   connect(m_model, &ChainDataModel::exceptionThrown,
           this, &GrapheneApplication::exceptionThrown);
}

GrapheneApplication::~GrapheneApplication()
{
}

void GrapheneApplication::setIsConnected(bool v)
{
   if (v != m_isConnected)
   {
      m_isConnected = v;
      Q_EMIT isConnectedChanged(m_isConnected);
   }
}

void GrapheneApplication::start(QString apiurl, QString user, QString pass)
{
   if (!m_thread.is_current())
   {
      m_done = m_thread.async([=](){ return start(apiurl, user, pass); });
      return;
   }
   try {
      m_client = std::make_shared<fc::http::websocket_client>();
      ilog("connecting...${s}", ("s",apiurl.toStdString()));
      auto con = m_client->connect(apiurl.toStdString());
      m_connectionClosed = con->closed.connect([this]{queueExecute([this]{setIsConnected(false);});});
      auto apic = std::make_shared<fc::rpc::websocket_api_connection>(*con);
      auto remote_api = apic->get_remote_api<login_api>(1);
      auto db_api = apic->get_remote_api<database_api>(0);
      if (!remote_api->login(user.toStdString(), pass.toStdString()))
      {
         elog("login failed");
         Q_EMIT loginFailed();
         return;
      }

      ilog("connecting...");
      queueExecute([=](){
         m_model->setDatabaseAPI(db_api);
      });

      queueExecute([=](){ setIsConnected(true); });
   } catch (const fc::exception& e)
   {
      Q_EMIT exceptionThrown(QString::fromStdString(e.to_string()));
   }
}
Q_SLOT void GrapheneApplication::execute(const std::function<void()>& func)const
{
   func();
}
<commit_msg>[GUI] Fix build following e4c29cbe787584a3e20ce628052bac0a7abedd82<commit_after>#include "ClientDataModel.hpp"

#include <graphene/app/api.hpp>
#include <graphene/chain/protocol/protocol.hpp>

#include <fc/rpc/websocket_api.hpp>

#include <QMetaObject>

using namespace graphene::app;

template<typename T>
QString idToString(T id) {
   return QString("%1.%2.%3").arg(T::space_id).arg(T::type_id).arg(ObjectId(id.instance));
}
QString idToString(graphene::db::object_id_type id) {
   return QString("%1.%2.%3").arg(id.space(), id.type(), ObjectId(id.instance()));
}

ChainDataModel::ChainDataModel(fc::thread& t, QObject* parent)
:QObject(parent),m_rpc_thread(&t){}

Asset* ChainDataModel::getAsset(ObjectId id)
{
   auto& by_id_idx = m_assets.get<by_id>();
   auto itr = by_id_idx.find(id);
   if (itr == by_id_idx.end())
   {
      auto result = m_assets.insert(new Asset(id, QString::number(--m_account_query_num), 0, this));
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this,id,result]{ getAssetImpl(idToString(asset_id_type(id)), &*result.first); });
      return *result.first;
   }
   return *itr;
}

Asset* ChainDataModel::getAsset(QString symbol)
{
   auto& by_symbol_idx = m_assets.get<by_symbol_name>();
   auto itr = by_symbol_idx.find(symbol);
   if (itr == by_symbol_idx.end())
   {
      auto result = m_assets.insert(new Asset(--m_account_query_num, symbol, 0, this));
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this,symbol,result](){ getAssetImpl(symbol, &*result.first); });
      return *result.first;
   }
   return *itr;
}

void ChainDataModel::getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer)
{
   try {
      ilog("Fetching asset ${asset}", ("asset", assetIdentifier.toStdString()));
      auto result = m_db_api->lookup_asset_symbols({assetIdentifier.toStdString()});

      // Run in main thread
      Q_EMIT queueExecute([this,result,assetInContainer](){
         ilog("Processing result ${r}", ("r", result));
         auto itr = m_assets.iterator_to(*assetInContainer);

         if (result.size() == 0 || !result.front()) {
            (*itr)->deleteLater();
            m_assets.erase(itr);
         } else {
            m_assets.modify(itr,
                            [=](Asset* a){
               a->setProperty("symbol", QString::fromStdString(result.front()->symbol));
               a->setProperty("id", ObjectId(result.front()->id.instance()));
               a->setProperty("precision", result.front()->precision);
            });
         }
      });
   }
   catch ( const fc::exception& e )
   {
      Q_EMIT exceptionThrown(QString::fromStdString(e.to_string()));
   }
}

void ChainDataModel::getAccountImpl(QString accountIdentifier, Account* const * accountInContainer)
{
   try {
      ilog("Fetching account ${acct}", ("acct", accountIdentifier.toStdString()));
      auto result = m_db_api->get_full_accounts([](const fc::variant& v) {
         idump((v));
      }, {accountIdentifier.toStdString()});
      fc::optional<full_account> accountPackage;

      if (result.count(accountIdentifier.toStdString())) {
         accountPackage = result.at(accountIdentifier.toStdString());

         // Fetch all necessary assets
         QList<asset_id_type> assetsToFetch;
         QList<Asset* const *> assetPlaceholders;
         assetsToFetch.reserve(accountPackage->balances.size());
         // Get list of asset IDs the account has a balance in
         std::transform(accountPackage->balances.begin(), accountPackage->balances.end(), std::back_inserter(assetsToFetch),
                        [](const account_balance_object& b) { return b.asset_type; });
         auto function = [this,&assetsToFetch,&assetPlaceholders] {
            auto itr = assetsToFetch.begin();
            const auto& assets_by_id = m_assets.get<by_id>();
            // Filter out assets I already have, create placeholders for the ones I don't.
            while (itr != assetsToFetch.end()) {
               if (assets_by_id.count(itr->instance))
                  itr = assetsToFetch.erase(itr);
               else {
                  assetPlaceholders.push_back(&*m_assets.insert(new Asset(itr->instance, QString(), 0, this)).first);
                  ++itr;
               }
            }
         };
         QMetaObject::invokeMethod(parent(), "execute", Qt::BlockingQueuedConnection,
                                   Q_ARG(const std::function<void()>&, function));
         assert(assetsToFetch.size() == assetPlaceholders.size());

         // Blocking call to fetch and complete initialization for all the assets
         for (int i = 0; i < assetsToFetch.size(); ++i)
            getAssetImpl(idToString(assetsToFetch[i]), assetPlaceholders[i]);
      }

      // Run in main thread
      Q_EMIT queueExecute([this,accountPackage,accountInContainer](){
         ilog("Processing result ${r}", ("r", accountPackage));
         auto itr = m_accounts.iterator_to(*accountInContainer);

         if (!accountPackage.valid()) {
            (*itr)->deleteLater();
            m_accounts.erase(itr);
         } else {
            m_accounts.modify(itr, [=](Account* a){
               a->setProperty("id", ObjectId(accountPackage->account.id.instance()));
               a->setProperty("name", QString::fromStdString(accountPackage->account.name));

               // Set balances
               QList<Balance*> balances;
               std::transform(accountPackage->balances.begin(), accountPackage->balances.end(), std::back_inserter(balances),
                              [this](const account_balance_object& b) {
                  Balance* bal = new Balance;
                  bal->setParent(this);
                  bal->setProperty("amount", QVariant::fromValue(b.balance.value));
                  bal->setProperty("type", QVariant::fromValue(getAsset(ObjectId(b.asset_type.instance))));
                  return bal;
               });
               a->setBalances(balances);
            });
         }
      });
   }
   catch (const fc::exception& e)
   {
      Q_EMIT exceptionThrown(QString::fromStdString(e.to_string()));
   }
}

Account* ChainDataModel::getAccount(ObjectId id)
{
   auto& by_id_idx = m_accounts.get<by_id>();
   auto itr = by_id_idx.find(id);
   if( itr == by_id_idx.end() )
   {
      auto tmp = new Account(id, tr("Account #%1").arg(--m_account_query_num), this);
      auto result = m_accounts.insert(tmp);
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this, id, result]{getAccountImpl(idToString(account_id_type(id)), &*result.first);});
      return *result.first;
   }
   return *itr;
}

Account* ChainDataModel::getAccount(QString name)
{
   auto& by_name_idx = m_accounts.get<by_account_name>();
   auto itr = by_name_idx.find(name);
   if( itr == by_name_idx.end() )
   {
      auto tmp = new Account(--m_account_query_num, name, this);
      auto result = m_accounts.insert(tmp);
      assert(result.second);

      // Run in RPC thread
      m_rpc_thread->async([this, name, result]{getAccountImpl(name, &*result.first);});
      return *result.first;
   }
   return *itr;
}

QQmlListProperty<Balance> Account::balances()
{
   auto count = [](QQmlListProperty<Balance>* list) {
      return reinterpret_cast<Account*>(list->data)->m_balances.size();
   };
   auto at = [](QQmlListProperty<Balance>* list, int index) {
      return reinterpret_cast<Account*>(list->data)->m_balances[index];
   };

   return QQmlListProperty<Balance>(this, this, count, at);
}

GrapheneApplication::GrapheneApplication(QObject* parent)
:QObject(parent),m_thread("app")
{
   connect(this, &GrapheneApplication::queueExecute,
           this, &GrapheneApplication::execute);

   m_model = new ChainDataModel(m_thread, this);

   connect(m_model, &ChainDataModel::queueExecute,
           this, &GrapheneApplication::execute);

   connect(m_model, &ChainDataModel::exceptionThrown,
           this, &GrapheneApplication::exceptionThrown);
}

GrapheneApplication::~GrapheneApplication()
{
}

void GrapheneApplication::setIsConnected(bool v)
{
   if (v != m_isConnected)
   {
      m_isConnected = v;
      Q_EMIT isConnectedChanged(m_isConnected);
   }
}

void GrapheneApplication::start(QString apiurl, QString user, QString pass)
{
   if (!m_thread.is_current())
   {
      m_done = m_thread.async([=](){ return start(apiurl, user, pass); });
      return;
   }
   try {
      m_client = std::make_shared<fc::http::websocket_client>();
      ilog("connecting...${s}", ("s",apiurl.toStdString()));
      auto con = m_client->connect(apiurl.toStdString());
      m_connectionClosed = con->closed.connect([this]{queueExecute([this]{setIsConnected(false);});});
      auto apic = std::make_shared<fc::rpc::websocket_api_connection>(*con);
      auto remote_api = apic->get_remote_api<login_api>(1);
      auto db_api = apic->get_remote_api<database_api>(0);
      if (!remote_api->login(user.toStdString(), pass.toStdString()))
      {
         elog("login failed");
         Q_EMIT loginFailed();
         return;
      }

      ilog("connecting...");
      queueExecute([=](){
         m_model->setDatabaseAPI(db_api);
      });

      queueExecute([=](){ setIsConnected(true); });
   } catch (const fc::exception& e)
   {
      Q_EMIT exceptionThrown(QString::fromStdString(e.to_string()));
   }
}
Q_SLOT void GrapheneApplication::execute(const std::function<void()>& func)const
{
   func();
}
<|endoftext|>


<commit_before>/*
Andrew Nguyen
Joshua Womack
CPSC323
Assignment 2 - Syntax Analyzer

*/

#include "LA.h"
using namespace std;

void Rat16F();
void OptFuncDef();
void FuncDef();
void Func();
void OptParamList();
void ParamList();
void Parameter();
void Qualifier();
void Body();
void OptDecList();
void DecList();
void Declaration();
void IDs();
void StatementList();
void Statement();
void Compound();
void Assign();
void If();
void Return();
void Write();
void Read();
void While();
void Condition();
void Relop();
void Expression();
void ExpressionPrime();
void Term();
void TermPrime();
void Factor();
void Primary();
void Empty();
void lexAdv();

int                     tokenIndex = 0;             //Index used to step through token vector
bool                    printSwitch = true;
vector<tokenData>       tokens;                     //vector to hold tokens as they are being inputted
vector<tokenData>       tokenList;                  //vector that holds all tokens once they have been read in initially
tokenData               currentToken;

int main()
{
	bool				    wroteHeader = true;     //NOT NEEDED ANYMORE?
	ifstream			    ifget;
	LA                      lex;
	string				    current = "";
	string				    infilepath = "";
	string				    outfilepath = "";

	//Input file to read from
/*
	cout << "Before you begin, make sure the input test file is in\nthe same folder as the .exe of this program.\n";
	cout << "----------------------------------------------------------------------\n";
	cout << "Please enter the file name and extension of the input file (input.txt).\n";
	cout << "Input: ";
	getline(cin, infilepath);
	cout << "You entered: " << infilepath << endl << endl;

	//Output file to write to
	cout << "Please enter the file and extension of the output file (output.txt).\n";
	cout << "Input: ";
	getline(cin, outfilepath);
	cout << "You entered: " << outfilepath << endl << endl;

	//Open file for reading
	ifget.open(infilepath);
*/
	infilepath = "/home/joshua/Git/323-syntaxAnalyzer/input.txt";
	outfilepath = "/home/joshua/Git/323-syntaxAnalyzer/output.txt";
	ifget.open(infilepath);

	//Catch issue with opening file
	if (!ifget)
	{
		cout << "Error. Unable to read file." << endl;
		system("pause");
		return -1;
	}

	//While not end of file, read every line.
	while (getline(ifget, current))
	{
		if (!wroteHeader)
		{
			lex.printHeader(outfilepath);
			wroteHeader = true;
		}

		tokens = lex.lexer(current);
		tokenList.insert(tokenList.end(), tokens.begin(), tokens.end());
		tokens.clear();
	}

	ifget.close();
	//lex.printTokens(tokenList, outfilepath);

    /*
     * New stuff goes here
     */
	Rat16F();

	system("pause");
	return 0;
}

void lexAdv() {
	if (tokenIndex < tokenList.size())
	{
		currentToken = tokenList[tokenIndex];
		if (printSwitch)
		{
			cout << left << setw(7) << "\nToken: " << left << setw(20) << currentToken.token
				 << left << setw(8) << "Lexeme: " << left << setw(20) << currentToken.lexeme << endl;
		}
		tokenIndex++;
	}
}

void Rat16F()
{
	lexAdv();
	if (printSwitch)
		cout << "\t<Rat16F> ::= $$ <Opt Function Definitions>\n\t\t\t\t $$ <Opt Declaration List> <Statement List> $$\n";

	if (currentToken.lexeme == "$$")
	{
		lexAdv();
		OptFuncDef();
		if (currentToken.lexeme == "$$")
		{
			lexAdv();
			OptDecList();
			StatementList();
			if (currentToken.lexeme == "$$")
				cout << "The End.\n";
		}
	}
}

void OptFuncDef()
{
	if (printSwitch)
		cout << "\t<Opt Function Definition> ::= <Function Definitions> | <Empty>\n";

	if (currentToken.lexeme == "function")
	{
		lexAdv();
		FuncDef();
	}
	else
		Empty();
}

void FuncDef()
{
	if (printSwitch)
		cout << "\t<Function Definitions> ::= <Function> | <Function> <Function Definitions>\n";

	while (currentToken.lexeme == "function")
	{
		Func();
	}
}

void Func()
{
	if (printSwitch)
		cout << "\t<Function> ::= function <Identifier> [ <Opt Paramenter List> ] <Opt Declaration List> <Body>\n";

	lexAdv();

	if (currentToken.token == "IDENTIFIER")
	{
		lexAdv();
		if (currentToken.lexeme == "[")
		{
			lexAdv();
			OptParamList();
			if (currentToken.lexeme == "]")
			{
				lexAdv();
				OptDecList();
				Body();
			}
		}
	}
}

void OptParamList()
{
	if (printSwitch)
		cout << "\t<Opt Parameter List> ::= <Parameter List> | <Empty>\n";

	if (currentToken.token == "IDENTIFIER")
	{
		ParamList();
	}
	else
	{
		Empty();
	}
}

void ParamList()
{
	if (printSwitch)
		cout << "\t<Parameter List> ::= <Parameter> | <Parameter>, <Parameter List>\n";

	if (currentToken.token == "IDENTIFIER")
	{
		lexAdv();
		if (currentToken.lexeme == ",")
		{
			lexAdv();
			ParamList();
		}
	}
}

void Parameter()
{
	if (printSwitch)
		cout << "\t<Parameter> ::= <IDs> : <Qualifier>\n";

	IDs();
	if (currentToken.lexeme == ":")
	{
		lexAdv();
		Qualifier();
	}
}

void Qualifier()
{
	if (printSwitch)
		cout << "\t<Qualifier> ::= integer | boolean | real\n";

	if (currentToken.lexeme == "integer" || currentToken.lexeme == "boolean" || currentToken.lexeme == "real")
		lexAdv();
	else
	{
		cout << "Oops, you broke it. Expected 'integer', 'boolean', or 'real'\n";
		exit(-1);
	}
}

void Body()
{
	if (printSwitch)
		cout << "\t<Body> ::= { <Statement List> }\n";
}

void OptDecList()
{
	if (printSwitch)
		cout << "\t<Opt Declaration List> ::= <Declaration List> | <Empty>\n";
	if (currentToken.lexeme == "integer" || currentToken.lexeme == "boolean" || currentToken.lexeme == "real")
	{
		DecList();
	}
	else
	{
		Empty();
	}
}

void DecList()
{
	if (printSwitch)
		cout << "\t<Declaration List> ::= <Declaration>; | <Declaration> ; <Declaration List>\n";

	Declaration();
	if (currentToken.lexeme == ";")
	{
		lexAdv();
		DecList();
	}

}

void Declaration()
{
	if (printSwitch)
		cout << "\t<Declaration> ::= <Qualifier> <IDs>\n";

	Qualifier();
	IDs();
}

void IDs()
{
	if (printSwitch)
		cout << "\t<IDs> ::= <Identifier> | <Identifier>, <IDs>\n";

	if (currentToken.token == "IDENTIFIER")
	{
		lexAdv();
		if (currentToken.lexeme == ",")
		{
			lexAdv();
			IDs();
		}
	}
}

void StatementList()
{
	if (printSwitch)
		cout << "\t<Statement List> ::= <Statement> | <Statement> <Statement List>\n";
}

void Statement()
{
	if (printSwitch)
		cout << "\t<Statement> ::= <Compound> | <Assign> | <If> | <Return> | <Write> | <Read> | <While>\n";
}

void Compound()
{
	if (printSwitch)
		cout << "\t<Compound> ::= {<Statement List>}\n";
}

void Assign()
{
	if (printSwitch)
		cout << "\t<Assign> ::= <Identifier> := <Expression>;\n";
}

void If()
{
	if (printSwitch)
		cout << "\t<If> ::= if (<Condition>) <Statement> endif | if (<Condition>) <Statement> else <Statement> endif\n";
}

void Return()
{
	if (printSwitch)
		cout << "\t<Return> ::= return; | return <Expression>;\n";
}

void Write()
{
	if (printSwitch)
		cout << "\t<Write> ::= print (<Expressions>);\n";
}

void Read()
{
	if (printSwitch)
		cout << "\t<Read> ::= read (<IDs>);\n";
}

void While()
{
	if (printSwitch)
		cout << "\t<While> ::= while (<Condition>) <Statement>\n";
}

void Condition()
{
	if (printSwitch)
		cout << "\t<Condition> ::= <Expression> <Relop> <Expression>\n";
}

void Relop()
{
	if (printSwitch)
		cout << "\t<Relop> ::= = | /= | > | < | => | <=\n";
}

void Expression()
{
	if (printSwitch)
		cout << "\t<Expression> ::= <Term> <Expression Prime>\n";
}

void ExpressionPrime()
{
	if (printSwitch)
		cout << "\t<Expression Prime> ::= + <Term> <Expression Prime> | - <Term> <Expression Prime> | <Empty>\n";
}

void Term()
{
	if (printSwitch)
		cout << "\t<Term> ::= <Factor> <Term Prime>\n";
}

void TermPrime()
{
	if (printSwitch)
		cout <<  "\t<Term Prime> ::= * <Factor> <Term Prime> | / <Factor> <Term Prime> | <Empty>\n";
}

void Factor()
{
	if (printSwitch)
		cout << "\t<Factor> ::= - <Primary> | <Primary>\n";
}

void Primary()
{
	if (printSwitch)
		cout << "\t<Primary> ::= <Identifier> | <Integer> | <Idetifier> [<IDs>] | (<Expression>) | <Real> | true | false\n";
}

void Empty()
{
	if (printSwitch)
		cout << "\t<Empty> ::= epsilon\n";

}

<commit_msg>Chugging along with the plethora of functions.<commit_after>/*
Andrew Nguyen
Joshua Womack
CPSC323
Assignment 2 - Syntax Analyzer

*/

#include "LA.h"
using namespace std;

void Rat16F();
void OptFuncDef();
void FuncDef();
void Func();
void OptParamList();
void ParamList();
void Parameter();
void Qualifier();
void Body();
void OptDecList();
void DecList();
void Declaration();
void IDs();
void StatementList();
void Statement();
void Compound();
void Assign();
void If();
void Return();
void Write();
void Read();
void While();
void Condition();
void Relop();
void Expression();
void ExpressionPrime();
void Term();
void TermPrime();
void Factor();
void Primary();
void Empty();
void lexAdv();

int                     tokenIndex = 0;             //Index used to step through token vector
bool                    printSwitch = true;
vector<tokenData>       tokens;                     //vector to hold tokens as they are being inputted
vector<tokenData>       tokenList;                  //vector that holds all tokens once they have been read in initially
tokenData               currentToken;

int main()
{
	bool				    wroteHeader = true;     //NOT NEEDED ANYMORE?
	ifstream			    ifget;
	LA                      lex;
	string				    current = "";
	string				    infilepath = "";
	string				    outfilepath = "";

	//Input file to read from
/*
	cout << "Before you begin, make sure the input test file is in\nthe same folder as the .exe of this program.\n";
	cout << "----------------------------------------------------------------------\n";
	cout << "Please enter the file name and extension of the input file (input.txt).\n";
	cout << "Input: ";
	getline(cin, infilepath);
	cout << "You entered: " << infilepath << endl << endl;

	//Output file to write to
	cout << "Please enter the file and extension of the output file (output.txt).\n";
	cout << "Input: ";
	getline(cin, outfilepath);
	cout << "You entered: " << outfilepath << endl << endl;

	//Open file for reading
	ifget.open(infilepath);
*/
	infilepath = "/home/joshua/Git/323-syntaxAnalyzer/input.txt";
	outfilepath = "/home/joshua/Git/323-syntaxAnalyzer/output.txt";
	ifget.open(infilepath);

	//Catch issue with opening file
	if (!ifget)
	{
		cout << "Error. Unable to read file." << endl;
		system("pause");
		return -1;
	}

	//While not end of file, read every line.
	while (getline(ifget, current))
	{
		if (!wroteHeader)
		{
			lex.printHeader(outfilepath);
			wroteHeader = true;
		}

		tokens = lex.lexer(current);
		tokenList.insert(tokenList.end(), tokens.begin(), tokens.end());
		tokens.clear();
	}

	ifget.close();
	//lex.printTokens(tokenList, outfilepath);

    /*
     * New stuff goes here
     */
	Rat16F();

	system("pause");
	return 0;
}

void lexAdv() {
	if (tokenIndex < tokenList.size())
	{
		currentToken = tokenList[tokenIndex];
		if (printSwitch)
		{
			cout << left << setw(7) << "\nToken: " << left << setw(20) << currentToken.token
				 << left << setw(8) << "Lexeme: " << left << setw(20) << currentToken.lexeme << endl;
		}
		tokenIndex++;
	}
}

void Rat16F()
{
	lexAdv();
	if (printSwitch)
		cout << "\t<Rat16F> ::= $$ <Opt Function Definitions>\n\t\t\t\t $$ <Opt Declaration List> <Statement List> $$\n";

	if (currentToken.lexeme == "$$")
	{
		lexAdv();
		OptFuncDef();
		if (currentToken.lexeme == "$$")
		{
			lexAdv();
			OptDecList();
			StatementList();
			if (currentToken.lexeme == "$$")
				cout << "The End.\n";
		}
	}
}

void OptFuncDef()
{
	if (printSwitch)
		cout << "\t<Opt Function Definition> ::= <Function Definitions> | <Empty>\n";

	if (currentToken.lexeme == "function")
	{
		lexAdv();
		FuncDef();
	}
	else
		Empty();
}

void FuncDef()
{
	if (printSwitch)
		cout << "\t<Function Definitions> ::= <Function> | <Function> <Function Definitions>\n";

	while (currentToken.lexeme == "function")
	{
		Func();
	}
}

void Func()
{
	if (printSwitch)
		cout << "\t<Function> ::= function <Identifier> [ <Opt Paramenter List> ] <Opt Declaration List> <Body>\n";

	lexAdv();

	if (currentToken.token == "IDENTIFIER")
	{
		lexAdv();
		if (currentToken.lexeme == "[")
		{
			lexAdv();
			OptParamList();
			if (currentToken.lexeme == "]")
			{
				lexAdv();
				OptDecList();
				Body();
			}
		}
	}
}

void OptParamList()
{
	if (printSwitch)
		cout << "\t<Opt Parameter List> ::= <Parameter List> | <Empty>\n";

	if (currentToken.token == "IDENTIFIER")
	{
		ParamList();
	}
	else
	{
		Empty();
	}
}

void ParamList()
{
	if (printSwitch)
		cout << "\t<Parameter List> ::= <Parameter> | <Parameter>, <Parameter List>\n";

	if (currentToken.token == "IDENTIFIER")
	{
		lexAdv();
		if (currentToken.lexeme == ",")
		{
			lexAdv();
			ParamList();
		}
	}
}

void Parameter()
{
	if (printSwitch)
		cout << "\t<Parameter> ::= <IDs> : <Qualifier>\n";

	IDs();
	if (currentToken.lexeme == ":")
	{
		lexAdv();
		Qualifier();
	}
}

void Body()
{
	if (printSwitch)
		cout << "\t<Body> ::= { <Statement List> }\n";

	if (currentToken.lexeme == "{")
	{
		lexAdv();
		StatementList();
	}
	else
	{
		cout << "Syntax Error";
		exit(-1);
	}
}

void OptDecList()
{
	if (printSwitch)
		cout << "\t<Opt Declaration List> ::= <Declaration List> | <Empty>\n";

	if (currentToken.lexeme == "{")
		Empty();
	else if (currentToken.lexeme == "integer" || currentToken.lexeme == "boolean" || currentToken.lexeme == "real")
		DecList();
	else
	{
		cout << "Syntax Error";
		exit(-1);
	}
}

void DecList()
{
	if (printSwitch)
		cout << "\t<Declaration List> ::= <Declaration>; | <Declaration> ; <Declaration List>\n";

		Declaration();
		if (currentToken.lexeme == ";")
			lexAdv();
			if (currentToken.lexeme != "{")
				DecList();
}

void Declaration()
{
	if (printSwitch)
		cout << "\t<Declaration> ::= <Qualifier> <IDs>\n";

	Qualifier();
	IDs();
}

void Qualifier()
{
	if (printSwitch)
		cout << "\t<Qualifier> ::= integer | boolean | real\n";

	if (currentToken.lexeme == "integer" || currentToken.lexeme == "boolean" || currentToken.lexeme == "real")
		lexAdv();
	else
	{
		cout << "Oops, you broke it. Expected 'integer', 'boolean', or 'real'\n";
		exit(-1);
	}
}

void IDs()
{
	if (printSwitch)
		cout << "\t<IDs> ::= <Identifier> | <Identifier>, <IDs>\n";

	if (currentToken.token == "IDENTIFIER")
	{
		lexAdv();
		if (currentToken.lexeme == ",")
		{
			lexAdv();
			IDs();
		}
	}
}

void StatementList()
{
	if (printSwitch)
		cout << "\t<Statement List> ::= <Statement> | <Statement> <Statement List>\n";

/*
	if (currentToken.token == "IDENTIFIER")
	{
		lexAdv();
		if (currentToken.lexeme == "[")
		{
			lexAdv();
			OptParamList();
			if (currentToken.lexeme == "]")
			{
				lexAdv();
				OptDecList();
				Body();
			}
		}
	}
*/
}

void Statement()
{
	if (printSwitch)
		cout << "\t<Statement> ::= <Compound> | <Assign> | <If> | <Return> | <Write> | <Read> | <While>\n";
}

void Compound()
{
	if (printSwitch)
		cout << "\t<Compound> ::= {<Statement List>}\n";
}

void Assign()
{
	if (printSwitch)
		cout << "\t<Assign> ::= <Identifier> := <Expression>;\n";
}

void If()
{
	if (printSwitch)
		cout << "\t<If> ::= if (<Condition>) <Statement> endif | if (<Condition>) <Statement> else <Statement> endif\n";
}

void Return()
{
	if (printSwitch)
		cout << "\t<Return> ::= return; | return <Expression>;\n";
}

void Write()
{
	if (printSwitch)
		cout << "\t<Write> ::= print (<Expressions>);\n";
}

void Read()
{
	if (printSwitch)
		cout << "\t<Read> ::= read (<IDs>);\n";
}

void While()
{
	if (printSwitch)
		cout << "\t<While> ::= while (<Condition>) <Statement>\n";
}

void Condition()
{
	if (printSwitch)
		cout << "\t<Condition> ::= <Expression> <Relop> <Expression>\n";
}

void Relop()
{
	if (printSwitch)
		cout << "\t<Relop> ::= = | /= | > | < | => | <=\n";
}

void Expression()
{
	if (printSwitch)
		cout << "\t<Expression> ::= <Term> <Expression Prime>\n";
}

void ExpressionPrime()
{
	if (printSwitch)
		cout << "\t<Expression Prime> ::= + <Term> <Expression Prime> | - <Term> <Expression Prime> | <Empty>\n";
}

void Term()
{
	if (printSwitch)
		cout << "\t<Term> ::= <Factor> <Term Prime>\n";
}

void TermPrime()
{
	if (printSwitch)
		cout <<  "\t<Term Prime> ::= * <Factor> <Term Prime> | / <Factor> <Term Prime> | <Empty>\n";
}

void Factor()
{
	if (printSwitch)
		cout << "\t<Factor> ::= - <Primary> | <Primary>\n";
}

void Primary()
{
	if (printSwitch)
		cout << "\t<Primary> ::= <Identifier> | <Integer> | <Idetifier> [<IDs>] | (<Expression>) | <Real> | true | false\n";
}

void Empty()
{
	if (printSwitch)
		cout << "\t<Empty> ::= epsilon\n";

}

<|endoftext|>


<commit_before>#ifndef OSRM_UNIT_TEST_ARGS
#define OSRM_UNIT_TEST_ARGS

#include <string>
#include <vector>
#include <iostream>

inline std::vector<std::string> get_args()
{
    // Split off argv[0], store actual positional arguments in args
    const auto argc = boost::unit_test::framework::master_test_suite().argc - 1;
    const auto argv = boost::unit_test::framework::master_test_suite().argv + 1;

    if (argc == 0)
    {
        std::cout << "You must provide a path to the test data, please see the unit testing docs" << std::endl;
    }

    return {argv, argv + argc};
}

#endif
<commit_msg>add error logging for missing osrm file to library tests (#3704)<commit_after>#ifndef OSRM_UNIT_TEST_ARGS
#define OSRM_UNIT_TEST_ARGS

#include "util/log.hpp"
#include <boost/filesystem.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <iostream>

inline std::vector<std::string> get_args()
{
    osrm::util::LogPolicy::GetInstance().Unmute();
    if ((boost::unit_test::framework::master_test_suite().argc != 2) ||
        (!boost::filesystem::is_regular_file(
            boost::unit_test::framework::master_test_suite().argv[1])))
    {
        osrm::util::Log(logERROR) << "Please provide valid input osrm file";
        osrm::util::Log(logERROR) << "Usage: "
                                  << boost::unit_test::framework::master_test_suite().argv[0]
                                  << " /path/to/input_osrm_file" << std::endl;
        std::exit(EXIT_FAILURE);
    }

    // Split off argv[0], store actual positional arguments in args
    const auto argc = boost::unit_test::framework::master_test_suite().argc - 1;
    const auto argv = boost::unit_test::framework::master_test_suite().argv + 1;

    if (argc == 0)
    {
        std::cout << "You must provide a path to the test data, please see the unit testing docs" << std::endl;
    }

    return {argv, argv + argc};
}

#endif
<|endoftext|>


<commit_before>#include "DxLib.h"
#include <fstream>
#include <string>
#include <vector>

const int NORMAL = 0;
const int GRAPH_NUM = 1759;
struct Graph
{
	int graph;
	bool fin_flag = true;;
};
// WinMain֐
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	ChangeWindowMode(TRUE);
	// ʃ[h̐ݒ
	SetGraphMode(640, 480, 16);

	// cwCu
	if (DxLib_Init() == -1) return -1;

	const int graph_start = 1401;
	const int graph_end = 1687;
	int num = 0;
	std::string numname;
	const std::string filename_num(" 9502-");
	const std::string filetype(".bmp");
	const std::string graph_directory("Rmai_graph/");
	std::string filename;
	std::vector<int> graph;

	int soundBGM, soundVoice;
	soundBGM = LoadSoundMem("077 44444-44444.wav");
	soundVoice = LoadSoundMem("078 006-00005.wav");
	for (int i = graph_start; i <= graph_end; i++) {
		if (num < 10) {
			numname = "00" + std::to_string(num);
		}
		else if (num < 100) {
			numname = "0" + std::to_string(num);
		}
		else {
			numname = std::to_string(num);
		}
		filename = graph_directory + std::to_string(i) + filename_num + numname + filetype;
		char* file = new char[filename.size() + 1];
		std::char_traits<char>::copy(file, filename.c_str(), filename.size() + 1);
		graph.push_back(LoadGraph(file));
		++num;
	}

	int gr = LoadGraph("Rmai_graph/1401 9502-000.bmp");
	std::vector<int>::iterator itr = graph.begin();
	int  count = 0;

	// OtBbN̕`𗠉ʂɃZbg
	SetDrawScreen(DX_SCREEN_BACK);

	PlaySoundMem(soundBGM, DX_PLAYTYPE_LOOP, true);
	PlaySoundMem(soundVoice, DX_PLAYTYPE_BACK, true);

	while (1)
	{
		// ʂ(^ɂ)
		ClearDrawScreen();

		if (itr == graph.end())	itr = graph.begin();

		DrawGraph(0, 0, *itr, false);

		++count;
		if (count > 1) {
			++itr;
			count = 0;
		}

		// ʂ̓e\ʂɃRs[
		ScreenFlip();

		// Windows L̖ʓ|ȏcwCuɂ点
		// -1 ԂĂ烋[v𔲂
		if (ProcessMessage() < 0) break;

		// drbL[Ă烋[v甲
		if (CheckHitKey(KEY_INPUT_ESCAPE)) break;
	}

	// cwCugp̏I
	DxLib_End();

	// \tg̏I
	return 0;
}<commit_msg>c++の内容を削除<commit_after>#include "DxLib.h"
#include <fstream>
#include <string>
#include <vector>

const int NORMAL = 0;
const int GRAPH_NUM = 1759;
struct Graph
{
	int graph;
	bool fin_flag = true;;
};
// WinMain֐
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	ChangeWindowMode(TRUE);
	// ʃ[h̐ݒ
	SetGraphMode(640, 480, 16);

	// cwCu
	if (DxLib_Init() == -1) return -1;

	// OtBbN̕`𗠉ʂɃZbg
	SetDrawScreen(DX_SCREEN_BACK);

	while (1)
	{
		// ʂ(^ɂ)
		ClearDrawScreen();

		// ʂ̓e\ʂɃRs[
		ScreenFlip();

		// Windows L̖ʓ|ȏcwCuɂ点
		// -1 ԂĂ烋[v𔲂
		if (ProcessMessage() < 0) break;

		// drbL[Ă烋[v甲
		if (CheckHitKey(KEY_INPUT_ESCAPE)) break;
	}

	// cwCugp̏I
	DxLib_End();

	// \tg̏I
	return 0;
}<|endoftext|>