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

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// this program performs local monitoring on a GDC by running the HLT code   //
//                                                                           //
// If an argument is given, this is taken as the name of a date file which   //
// is used instead of the local node.                                        //
// The program can be stopped by pressing CTRL-C.                            //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <TError.h>
#include <TSysEvtHandler.h>
#ifdef ALI_DATE
#include <TROOT.h>
#include <TSystem.h>
#include <TDatime.h>
#include "AliRawReaderDate.h"
#include "event.h"
#include "monitor.h"
#include <AliHLTStandardIncludes.h>
#include <AliHLTTransform.h>
#include <AliHLTMemHandler.h>
#include <AliHLTTrackArray.h>
#include <AliHLTHoughMaxFinder.h>
#include <AliHLTHoughBaseTransformer.h>
#include <AliHLTHough.h>
#include <AliHLTBenchmark.h>
#include <AliKalmanTrack.h>
#include "AliITSgeom.h"
#include "AliMagF.h"
#include "AliMagFMaps.h"
#include <AliHLTITSclusterer.h>
#include <AliHLTITSVertexerZ.h>
#include <AliHLTITStracker.h>
#endif

//_____________________________________________________________________________
class AliGDCInterruptHandler : public TSignalHandler {
public:
  AliGDCInterruptHandler();
  Bool_t Notify() {fStop = kTRUE; return kTRUE;};
  Bool_t Stop() const {return fStop;};
private:
  Bool_t fStop;  // CTRL-C pressed
};

//_____________________________________________________________________________
AliGDCInterruptHandler::AliGDCInterruptHandler() :
  TSignalHandler(kSigInterrupt, kFALSE)
{
  fStop = kFALSE;
};

//_____________________________________________________________________________
#ifdef ALI_DATE
int main(int argc, char** argv)
{
  // set ROOT in batch mode
  gROOT->SetBatch();

  // open a log file
  FILE* file = fopen("monitorGDC.log", "w");

  TDatime time;

  // get data from a file or online from this node
  Int_t status = 0;
  if (argc > 1) {
    status = monitorSetDataSource(argv[1]);
  } else {
    status = monitorSetDataSource(":");
  }
  if (status) ::Fatal("monitorSetDataSource", monitorDecodeError(status));

  // monitor only a sample of physics events
  char* table[] = {"Physics event", "yes", NULL};
  status = monitorDeclareTable(table);
  if (status) ::Fatal("monitorDeclareTable", monitorDecodeError(status));

  // declare this monitoring program to DATE
  status = monitorDeclareMp("GDC physics monitoring");
  if (status) ::Fatal("monitorDeclareMp", monitorDecodeError(status));

  // initialize HLT transformations
  if (!AliHLTTransform::Init("./", kFALSE)) {
    ::Fatal("AliHLTTransform::Init", "HLT initialization failed");
  }
  AliESD *esd = new AliESD;
  //  AliKalmanTrack::SetConvConst(
  //     1000/0.299792458/AliHLTTransform::GetSolenoidField()
  //  );
  AliITSgeom *geom = new AliITSgeom();
  geom->ReadNewFile("$ALICE_ROOT/ITS/ITSgeometry_vPPRasymmFMD.det");
  if (!geom) return 1;
  Int_t sfield = 0;
  switch ((Int_t)(AliHLTTransform::GetSolenoidField()+0.5)) {
  case 2:
    sfield = AliMagFMaps::k2kG;
    break;
  case 4:
    sfield = AliMagFMaps::k4kG;
    break;
  case 5:
    sfield = AliMagFMaps::k5kG;
    break;
  default:
    ::Fatal("AliHLTTransform::GetSolenoidField", "Incorrect magnetic field");
  }
  AliMagF* field = new AliMagFMaps("Maps","Maps", 2, 1., 10., sfield);
  AliTracker::SetFieldMap(field,kTRUE);

  // Init PID
  AliPID pid;

  // create the signal handler
  AliGDCInterruptHandler* handler = new AliGDCInterruptHandler;
  gSystem->AddSignalHandler(handler);

  // endless loop
  void* ptr = NULL;
  while (!handler->Stop()) {
    // get the next event
    status = monitorGetEventDynamic(&ptr);
    if (status == (Int_t)MON_ERR_EOF) break;
    if (status) ::Fatal("monitorGetEventDynamic", monitorDecodeError(status));

    // if no new event
    if (!ptr) {
      gSystem->Sleep(1000);   // sleep for 1 second
      continue;
    }

    AliRawReaderDate rawReader(ptr);
    //    if ((rawReader.GetAttributes()[0] & 0x02) != 0) {

    //      Int_t errorCode = rawReader.CheckData();
    Int_t errorCode = 0;
      if (errorCode && (errorCode != AliRawReader::kErrSize)) {
	time.Set();
	if (file) fprintf(file, "%s\n", time.AsString());
	if (file) fprintf(file, "run: %d  event: %d %d\n",
			  rawReader.GetRunNumber(),
			  rawReader.GetEventId()[0],
			  rawReader.GetEventId()[1]);
	fprintf(file, "ERROR: %d\n\n", errorCode);

      } else {

	AliHLTBenchmark *fBenchmark = new AliHLTBenchmark();
	fBenchmark->Start("Overall timing");

	// ITS clusterer and vertexer
	fBenchmark->Start("ITS Clusterer");
	AliHLTITSclusterer clusterer(geom);
	AliRawReader *itsrawreader=new AliRawReaderDate(ptr);
	TTree* treeClusters = new TTree("TreeL3ITSclusters"," "); //make a tree
	clusterer.Digits2Clusters(itsrawreader,treeClusters);
	fBenchmark->Stop("ITS Clusterer");

	AliHLTITSVertexerZ vertexer;
	AliESDVertex *vertex = vertexer.FindVertexForCurrentEvent(geom,treeClusters);
	Double_t vtxPos[3];
	Double_t vtxErr[3]={0.005,0.005,0.010};
	vertex->GetXYZ(vtxPos);
	//	vertex->GetSigmaXYZ(vtxErr);
	esd->SetVertex(vertex);

	// TPC Hough reconstruction
	Float_t ptmin = 0.1*AliHLTTransform::GetSolenoidField();
	Float_t zvertex = vtxPos[2];

	// Run the Hough Transformer
	fBenchmark->Start("Init");
	AliHLTHough *hough1 = new AliHLTHough();

	hough1->SetThreshold(4);
	hough1->CalcTransformerParams(ptmin);
	hough1->SetPeakThreshold(70,-1);
	//	printf("Pointer is %x\n",ptr);
	hough1->Init("./", kFALSE, 100, kFALSE,4,0,(Char_t*)ptr,zvertex);
	hough1->SetAddHistograms();
	fBenchmark->Stop("Init");

	fBenchmark->Start("Init");
	AliHLTHough *hough2 = new AliHLTHough();

	hough2->SetThreshold(4);
	hough2->CalcTransformerParams(ptmin);
	hough2->SetPeakThreshold(70,-1);
	//	printf("Pointer is %x\n",ptr);
	hough2->Init("./", kFALSE, 100, kFALSE,4,0,(Char_t*)ptr,zvertex);
	hough2->SetAddHistograms();
	fBenchmark->Stop("Init");

	Int_t nglobaltracks = 0;
	/*
	hough1->StartProcessInThread(0,17);
	hough2->StartProcessInThread(18,35);

	//	gSystem->Sleep(20000);
	if(hough1->WaitForThreadFinish())
	  ::Fatal("AliHLTHough::WaitForThreadFinish"," Can not join the required thread! ");
	if(hough2->WaitForThreadFinish())
	  ::Fatal("AliHLTHough::WaitForThreadFinish"," Can not join the required thread! ");

	gSystem->MakeDirectory("hough1");
	hough1->WriteTracks("./hough1");
	gSystem->MakeDirectory("hough2");
	hough2->WriteTracks("./hough2");
	*/

	for(int slice=0; slice<=17; slice++)
	{
	  //	  cout<<"Processing slice "<<slice<<endl;
	  fBenchmark->Start("ReadData");
	  hough1->ReadData(slice,0);
	  fBenchmark->Stop("ReadData");
	  fBenchmark->Start("Transform");
	  hough1->Transform();
	  fBenchmark->Stop("Transform");
	  hough1->AddAllHistogramsRows();
	  hough1->FindTrackCandidatesRow();
	  fBenchmark->Start("AddTracks");
	  hough1->AddTracks();
	  fBenchmark->Stop("AddTracks");

	  //	  AliHLTTrackArray* tracks = (AliHLTTrackArray*)hough1->GetTracks(0);
	  //	  nglobaltracks += tracks->GetNTracks();
	}
	for(int slice=18; slice<=35; slice++)
	{
	  //	  cout<<"Processing slice "<<slice<<endl;
	  fBenchmark->Start("ReadData");
	  hough2->ReadData(slice,0);
	  fBenchmark->Stop("ReadData");
	  fBenchmark->Start("Transform");
	  hough2->Transform();
	  fBenchmark->Stop("Transform");
	  hough2->AddAllHistogramsRows();
	  hough2->FindTrackCandidatesRow();
	  fBenchmark->Start("AddTracks");
	  hough2->AddTracks();
	  fBenchmark->Stop("AddTracks");

	  //	  AliHLTTrackArray* tracks = (AliHLTTrackArray*)hough2->GetTracks(0);
	  //	  nglobaltracks += tracks->GetNTracks();
	}

	nglobaltracks += hough1->FillESD(esd);
	nglobaltracks += hough2->FillESD(esd);

	// ITS tracker
	AliHLTITStracker itsTracker(geom);
	itsTracker.SetVertex(vtxPos,vtxErr);

	itsTracker.LoadClusters(treeClusters);
	itsTracker.Clusters2Tracks(esd);
	itsTracker.UnloadClusters();

	fBenchmark->Stop("Overall timing");
	time.Set();
	if (file) fprintf(file, "%s\n", time.AsString());
	if (file) fprintf(file, "run: %d  event: %d %d\n",
			  rawReader.GetRunNumber(),
			  rawReader.GetEventId()[0],
			  rawReader.GetEventId()[1]);
	if (errorCode) fprintf(file, "ERROR: %d\n", errorCode);

	if (file) fprintf(file, "Hough Transformer found %d tracks\n",nglobaltracks);

	hough1->DoBench("hough1");
	hough2->DoBench("hough2");
	fBenchmark->Analyze("overall");
	if (file) {
	  FILE* bench = fopen("hough1.dat", "r");
	  while (bench && !feof(bench)) {
	    char buffer[256];
	    if (!fgets(buffer, 256, bench)) break;
	    fprintf(file, "%s", buffer);
	  }
	  fclose(bench);
	}
	if (file) {
	  FILE* bench = fopen("hough2.dat", "r");
	  while (bench && !feof(bench)) {
	    char buffer[256];
	    if (!fgets(buffer, 256, bench)) break;
	    fprintf(file, "%s", buffer);
	  }
	  fclose(bench);
	}
	if (file) {
	  FILE* bench = fopen("overall.dat", "r");
	  while (bench && !feof(bench)) {
	    char buffer[256];
	    if (!fgets(buffer, 256, bench)) break;
	    fprintf(file, "%s", buffer);
	  }
	  fclose(bench);
	  fprintf(file, "\n\n");
	}

	delete hough1;
	delete hough2;

	esd->Reset();
      }
    //    }

    /*
    // read run, event, detector, DDL numbers and data size
    AliRawReaderDate rawReader(ptr);
    time.Set();
    printf("\n%s\n", time.AsString());
    printf("run: %d  event: %d %d\n", rawReader.GetRunNumber(),
	   rawReader.GetEventId()[0], rawReader.GetEventId()[1]);
    while (rawReader.ReadMiniHeader()) {
      printf(" detector: %d   DDL: %d  size: %d\n",
	     rawReader.GetDetectorID(), rawReader.GetDDLID(),
	     rawReader.GetDataSize());
    }

    */

    gSystem->Sleep(100);   // sleep for 0.1 second
    free(ptr);

    gSystem->ProcessEvents();
    if (file) fflush(file);

  }

  gSystem->RemoveSignalHandler(handler);
  if (file) fclose(file);

  return 0;
}

#else
int main(int /*argc*/, char** /*argv*/)
{
  ::Fatal("main", "this program was compiled without DATE");

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

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// this program performs local monitoring on a GDC by running the HLT code   //
//                                                                           //
// If an argument is given, this is taken as the name of a date file which   //
// is used instead of the local node.                                        //
// The program can be stopped by pressing CTRL-C.                            //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <TError.h>
#include <TSysEvtHandler.h>
#ifdef ALI_DATE
#include <TROOT.h>
#include <TSystem.h>
#include <TDatime.h>
#include "AliRawReaderDate.h"
#include "event.h"
#include "monitor.h"
#include <AliHLTStandardIncludes.h>
#include <AliHLTTransform.h>
#include <AliHLTMemHandler.h>
#include <AliHLTTrackArray.h>
#include <AliHLTHoughMaxFinder.h>
#include <AliHLTHoughBaseTransformer.h>
#include <AliHLTHough.h>
#include <AliHLTBenchmark.h>
#include <AliKalmanTrack.h>
#include "AliITSgeomTGeo.h"
#include "AliMagF.h"
#include "AliMagFMaps.h"
#include <AliHLTITSclusterer.h>
#include <AliHLTITSVertexerZ.h>
#include <AliHLTITStracker.h>
#endif

//_____________________________________________________________________________
class AliGDCInterruptHandler : public TSignalHandler {
public:
  AliGDCInterruptHandler();
  Bool_t Notify() {fStop = kTRUE; return kTRUE;};
  Bool_t Stop() const {return fStop;};
private:
  Bool_t fStop;  // CTRL-C pressed
};

//_____________________________________________________________________________
AliGDCInterruptHandler::AliGDCInterruptHandler() :
  TSignalHandler(kSigInterrupt, kFALSE)
{
  fStop = kFALSE;
};

//_____________________________________________________________________________
#ifdef ALI_DATE
int main(int argc, char** argv)
{
  // set ROOT in batch mode
  gROOT->SetBatch();

  // open a log file
  FILE* file = fopen("monitorGDC.log", "w");

  TDatime time;

  // get data from a file or online from this node
  Int_t status = 0;
  if (argc > 1) {
    status = monitorSetDataSource(argv[1]);
  } else {
    status = monitorSetDataSource(":");
  }
  if (status) ::Fatal("monitorSetDataSource", monitorDecodeError(status));

  // monitor only a sample of physics events
  char* table[] = {"Physics event", "yes", NULL};
  status = monitorDeclareTable(table);
  if (status) ::Fatal("monitorDeclareTable", monitorDecodeError(status));

  // declare this monitoring program to DATE
  status = monitorDeclareMp("GDC physics monitoring");
  if (status) ::Fatal("monitorDeclareMp", monitorDecodeError(status));

  // initialize HLT transformations
  if (!AliHLTTransform::Init("./", kFALSE)) {
    ::Fatal("AliHLTTransform::Init", "HLT initialization failed");
  }
  AliESD *esd = new AliESD;
  //  AliKalmanTrack::SetConvConst(
  //     1000/0.299792458/AliHLTTransform::GetSolenoidField()
  //  );
  AliITSgeomTGeo *geom = new AliITSgeomTGeo();
  geom->ReadNewFile("$ALICE_ROOT/ITS/ITSgeometry_vPPRasymmFMD.det");
  if (!geom) return 1;
  Int_t sfield = 0;
  switch ((Int_t)(AliHLTTransform::GetSolenoidField()+0.5)) {
  case 2:
    sfield = AliMagFMaps::k2kG;
    break;
  case 4:
    sfield = AliMagFMaps::k4kG;
    break;
  case 5:
    sfield = AliMagFMaps::k5kG;
    break;
  default:
    ::Fatal("AliHLTTransform::GetSolenoidField", "Incorrect magnetic field");
  }
  AliMagF* field = new AliMagFMaps("Maps","Maps", 2, 1., 10., sfield);
  AliTracker::SetFieldMap(field,kTRUE);

  // Init PID
  AliPID pid;

  // create the signal handler
  AliGDCInterruptHandler* handler = new AliGDCInterruptHandler;
  gSystem->AddSignalHandler(handler);

  // endless loop
  void* ptr = NULL;
  while (!handler->Stop()) {
    // get the next event
    status = monitorGetEventDynamic(&ptr);
    if (status == (Int_t)MON_ERR_EOF) break;
    if (status) ::Fatal("monitorGetEventDynamic", monitorDecodeError(status));

    // if no new event
    if (!ptr) {
      gSystem->Sleep(1000);   // sleep for 1 second
      continue;
    }

    AliRawReaderDate rawReader(ptr);
    //    if ((rawReader.GetAttributes()[0] & 0x02) != 0) {

    //      Int_t errorCode = rawReader.CheckData();
    Int_t errorCode = 0;
      if (errorCode && (errorCode != AliRawReader::kErrSize)) {
	time.Set();
	if (file) fprintf(file, "%s\n", time.AsString());
	if (file) fprintf(file, "run: %d  event: %d %d\n",
			  rawReader.GetRunNumber(),
			  rawReader.GetEventId()[0],
			  rawReader.GetEventId()[1]);
	fprintf(file, "ERROR: %d\n\n", errorCode);

      } else {

	AliHLTBenchmark *fBenchmark = new AliHLTBenchmark();
	fBenchmark->Start("Overall timing");

	// ITS clusterer and vertexer
	fBenchmark->Start("ITS Clusterer");
	AliHLTITSclusterer clusterer(geom);
	AliRawReader *itsrawreader=new AliRawReaderDate(ptr);
	TTree* treeClusters = new TTree("TreeL3ITSclusters"," "); //make a tree
	clusterer.Digits2Clusters(itsrawreader,treeClusters);
	fBenchmark->Stop("ITS Clusterer");

	AliHLTITSVertexerZ vertexer;
	AliESDVertex *vertex = vertexer.FindVertexForCurrentEvent(geom,treeClusters);
	Double_t vtxPos[3];
	Double_t vtxErr[3]={0.005,0.005,0.010};
	vertex->GetXYZ(vtxPos);
	//	vertex->GetSigmaXYZ(vtxErr);
	esd->SetVertex(vertex);

	// TPC Hough reconstruction
	Float_t ptmin = 0.1*AliHLTTransform::GetSolenoidField();
	Float_t zvertex = vtxPos[2];

	// Run the Hough Transformer
	fBenchmark->Start("Init");
	AliHLTHough *hough1 = new AliHLTHough();

	hough1->SetThreshold(4);
	hough1->CalcTransformerParams(ptmin);
	hough1->SetPeakThreshold(70,-1);
	//	printf("Pointer is %x\n",ptr);
	hough1->Init("./", kFALSE, 100, kFALSE,4,0,(Char_t*)ptr,zvertex);
	hough1->SetAddHistograms();
	fBenchmark->Stop("Init");

	fBenchmark->Start("Init");
	AliHLTHough *hough2 = new AliHLTHough();

	hough2->SetThreshold(4);
	hough2->CalcTransformerParams(ptmin);
	hough2->SetPeakThreshold(70,-1);
	//	printf("Pointer is %x\n",ptr);
	hough2->Init("./", kFALSE, 100, kFALSE,4,0,(Char_t*)ptr,zvertex);
	hough2->SetAddHistograms();
	fBenchmark->Stop("Init");

	Int_t nglobaltracks = 0;
	/*
	hough1->StartProcessInThread(0,17);
	hough2->StartProcessInThread(18,35);

	//	gSystem->Sleep(20000);
	if(hough1->WaitForThreadFinish())
	  ::Fatal("AliHLTHough::WaitForThreadFinish"," Can not join the required thread! ");
	if(hough2->WaitForThreadFinish())
	  ::Fatal("AliHLTHough::WaitForThreadFinish"," Can not join the required thread! ");

	gSystem->MakeDirectory("hough1");
	hough1->WriteTracks("./hough1");
	gSystem->MakeDirectory("hough2");
	hough2->WriteTracks("./hough2");
	*/

	for(int slice=0; slice<=17; slice++)
	{
	  //	  cout<<"Processing slice "<<slice<<endl;
	  fBenchmark->Start("ReadData");
	  hough1->ReadData(slice,0);
	  fBenchmark->Stop("ReadData");
	  fBenchmark->Start("Transform");
	  hough1->Transform();
	  fBenchmark->Stop("Transform");
	  hough1->AddAllHistogramsRows();
	  hough1->FindTrackCandidatesRow();
	  fBenchmark->Start("AddTracks");
	  hough1->AddTracks();
	  fBenchmark->Stop("AddTracks");

	  //	  AliHLTTrackArray* tracks = (AliHLTTrackArray*)hough1->GetTracks(0);
	  //	  nglobaltracks += tracks->GetNTracks();
	}
	for(int slice=18; slice<=35; slice++)
	{
	  //	  cout<<"Processing slice "<<slice<<endl;
	  fBenchmark->Start("ReadData");
	  hough2->ReadData(slice,0);
	  fBenchmark->Stop("ReadData");
	  fBenchmark->Start("Transform");
	  hough2->Transform();
	  fBenchmark->Stop("Transform");
	  hough2->AddAllHistogramsRows();
	  hough2->FindTrackCandidatesRow();
	  fBenchmark->Start("AddTracks");
	  hough2->AddTracks();
	  fBenchmark->Stop("AddTracks");

	  //	  AliHLTTrackArray* tracks = (AliHLTTrackArray*)hough2->GetTracks(0);
	  //	  nglobaltracks += tracks->GetNTracks();
	}

	nglobaltracks += hough1->FillESD(esd);
	nglobaltracks += hough2->FillESD(esd);

	// ITS tracker
	AliHLTITStracker itsTracker(geom);
	itsTracker.SetVertex(vtxPos,vtxErr);

	itsTracker.LoadClusters(treeClusters);
	itsTracker.Clusters2Tracks(esd);
	itsTracker.UnloadClusters();

	fBenchmark->Stop("Overall timing");
	time.Set();
	if (file) fprintf(file, "%s\n", time.AsString());
	if (file) fprintf(file, "run: %d  event: %d %d\n",
			  rawReader.GetRunNumber(),
			  rawReader.GetEventId()[0],
			  rawReader.GetEventId()[1]);
	if (errorCode) fprintf(file, "ERROR: %d\n", errorCode);

	if (file) fprintf(file, "Hough Transformer found %d tracks\n",nglobaltracks);

	hough1->DoBench("hough1");
	hough2->DoBench("hough2");
	fBenchmark->Analyze("overall");
	if (file) {
	  FILE* bench = fopen("hough1.dat", "r");
	  while (bench && !feof(bench)) {
	    char buffer[256];
	    if (!fgets(buffer, 256, bench)) break;
	    fprintf(file, "%s", buffer);
	  }
	  fclose(bench);
	}
	if (file) {
	  FILE* bench = fopen("hough2.dat", "r");
	  while (bench && !feof(bench)) {
	    char buffer[256];
	    if (!fgets(buffer, 256, bench)) break;
	    fprintf(file, "%s", buffer);
	  }
	  fclose(bench);
	}
	if (file) {
	  FILE* bench = fopen("overall.dat", "r");
	  while (bench && !feof(bench)) {
	    char buffer[256];
	    if (!fgets(buffer, 256, bench)) break;
	    fprintf(file, "%s", buffer);
	  }
	  fclose(bench);
	  fprintf(file, "\n\n");
	}

	delete hough1;
	delete hough2;

	esd->Reset();
      }
    //    }

    /*
    // read run, event, detector, DDL numbers and data size
    AliRawReaderDate rawReader(ptr);
    time.Set();
    printf("\n%s\n", time.AsString());
    printf("run: %d  event: %d %d\n", rawReader.GetRunNumber(),
	   rawReader.GetEventId()[0], rawReader.GetEventId()[1]);
    while (rawReader.ReadMiniHeader()) {
      printf(" detector: %d   DDL: %d  size: %d\n",
	     rawReader.GetDetectorID(), rawReader.GetDDLID(),
	     rawReader.GetDataSize());
    }

    */

    gSystem->Sleep(100);   // sleep for 0.1 second
    free(ptr);

    gSystem->ProcessEvents();
    if (file) fflush(file);

  }

  gSystem->RemoveSignalHandler(handler);
  if (file) fclose(file);

  return 0;
}

#else
int main(int /*argc*/, char** /*argv*/)
{
  ::Fatal("main", "this program was compiled without DATE");

  return 1;
}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2010 MQWeb - Franky Braem
 *
 * Licensed under the EUPL, Version 1.1 or  as soon they
 * will be approved by the European Commission - subsequent
 * versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the
 * Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://joinup.ec.europa.eu/software/page/eupl
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the Licence is
 * distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the Licence for the specific language governing
 * permissions and limitations under the Licence.
 */
#include <MQ/MQFunctions.h>
#include <MQ/MQException.h>

#include <Poco/ScopedLock.h>
#include <Poco/Logger.h>
#include <Poco/NumberFormatter.h>

#ifdef __linux__
#include <string.h>
#endif

namespace MQ
{

Poco::Mutex MQFunctions::_MQIMutex;

MQFunctions::MQFunctions() :
    _connFn(NULL)
  , _connxFn(NULL)
  , _openFn(NULL)
  , _closeFn(NULL)
  , _putFn(NULL)
  , _getFn(NULL)
  , _discFn(NULL)
  , _inqFn(NULL)
{
}

MQFunctions::~MQFunctions()
{
  if ( _dll.isLoaded() )
  {
    _dll.unload();
  }
}

void MQFunctions::loadLibrary(const std::string& mqLibrary)
{
  if ( ! _dll.isLoaded() )
  {
     _dll.load(mqLibrary);
  }

  _connFn = (ConnFn) _dll.getSymbol("MQCONN");
  _connxFn = (ConnxFn) _dll.getSymbol("MQCONNX");
  _openFn = (OpenFn) _dll.getSymbol("MQOPEN");
  _closeFn = (CloseFn) _dll.getSymbol("MQCLOSE");
  _putFn = (PutFn) _dll.getSymbol("MQPUT");
  _getFn = (GetFn) _dll.getSymbol("MQGET");
  _discFn = (DiscFn) _dll.getSymbol("MQDISC");
  _inqFn = (InqFn) _dll.getSymbol("MQINQ");
}

void MQFunctions::conn(char* qmgrName, MQHCONN* hconn, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_connFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _connFn(qmgrName, hconn, cc, rc);

  trace(qmgrName, "MQCONN", cc, rc);
}

MQHCONN MQFunctions::conn(const std::string& qmgrName)
{
  MQCHAR48 name;
  strncpy(name, qmgrName.c_str(), sizeof(MQCHAR48));

  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;
  MQHCONN qmgr = 0;

  conn(name, &qmgr, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException(qmgrName, "MQCONN", cc, rc);
  }

  return qmgr;
}

void MQFunctions::connx(char* qmgrName, MQCNO* connectOpts, MQHCONN* hconn, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_connxFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _connxFn(qmgrName, connectOpts, hconn, cc, rc);

  trace(qmgrName, "MQCONNX", cc, rc);
}

MQHCONN MQFunctions::connx(const std::string& qmgrName, MQCNO* connectOpts)
{
  MQCHAR48 name;
  memset(name, '0', sizeof(MQCHAR48));
  strncpy(name, qmgrName.c_str(), sizeof(MQCHAR48));

  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;
  MQHCONN qmgr = 0;

  connx(name, connectOpts, &qmgr, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException(qmgrName, "MQCONNX", cc, rc);
  }

  return qmgr;
}

void MQFunctions::open(MQHCONN conn, MQOD* od, MQLONG options, MQHOBJ* obj, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_openFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _openFn(conn, od, options, obj, cc, rc);

  Poco::Logger& logger = Poco::Logger::get("mq");
  if ( logger.trace() )
  {
	std::string name(od->ObjectName, MQ_OBJECT_NAME_LENGTH);
	size_t zero = name.find_first_of('\0');
	if ( zero != std::string::npos ) // MQ Strings can have only 0's
	{
		name = name.substr(0, zero);
	}
	else
	{
		name.erase(name.find_last_not_of(" \n\r\t")+1); // trim
	}
	trace(name, "MQOPEN", cc, rc);
  }
}

MQHOBJ MQFunctions::open(MQHCONN conn, MQOD* od, MQLONG options)
{
  MQHOBJ obj = 0;

  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;
  open(conn, od, options, &obj, &cc, &rc);

  if ( cc != MQCC_OK )
  {
	std::string name(od->ObjectName, MQ_OBJECT_NAME_LENGTH);
	if ( name.find_first_not_of('\0') == std::string::npos ) // MQ Strings can have only 0's
	{
		name = "";
	}
	else
	{
		name.erase(name.find_last_not_of(" \n\r\t")+1); // trim
	}

    throw MQException(name, "MQOPEN", cc, rc);
  }

  return obj;
}

void MQFunctions::put(MQHCONN conn, MQHOBJ obj, MQMD* md, MQPMO* options, MQLONG size, MQBYTE* buffer, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_putFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _putFn(conn, obj, md, options, size, buffer, cc, rc);

  trace("", "MQPUT", cc, rc);
}

void MQFunctions::put(MQHCONN conn, MQHOBJ obj, MQMD* md, MQPMO* options, MQLONG size, MQBYTE* buffer)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  put(conn, obj, md, options, size, buffer, &cc, &rc);

  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQPUT", cc, rc);
  }
}

void MQFunctions::get(MQHCONN conn, MQHOBJ obj, MQMD* md, MQGMO* options, MQLONG size, MQBYTE* buffer, PMQLONG dataLength, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_getFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _getFn(conn, obj, md, options, size, buffer, dataLength, cc, rc);

  trace("", "MQGET", cc, rc);
}

void MQFunctions::get(MQHCONN conn, MQHOBJ obj, MQMD* md, MQGMO* options, MQLONG size, MQBYTE* buffer, PMQLONG dataLength)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  get(conn, obj, md, options, size, buffer, dataLength, &cc, &rc);

  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQGET", cc, rc);
  }
}

void MQFunctions::close(MQHCONN conn, MQHOBJ* obj, MQLONG options, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_closeFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _closeFn(conn, obj, options, cc, rc);

  trace("", "MQCLOSE", cc, rc);
}

void MQFunctions::close(MQHCONN conn, MQHOBJ* obj, MQLONG options)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  close(conn, obj, options, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQCLOSE", cc, rc);
  }
}

void MQFunctions::disc(PMQHCONN conn, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_discFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _discFn(conn, cc, rc);

  trace("", "MQDISC", cc, rc);
}

void MQFunctions::disc(PMQHCONN conn)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  disc(conn, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQDISC", cc, rc);
  }
}

void MQFunctions::inq(MQHCONN conn, MQHOBJ obj, MQLONG selectorCount, PMQLONG selectors, MQLONG intAttrCount, PMQLONG intAttrs, MQLONG charAttrLength, PMQCHAR charAttrs, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_inqFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _inqFn(conn, obj, selectorCount, selectors, intAttrCount, intAttrs, charAttrLength, charAttrs, cc, rc);
}

void MQFunctions::inq(MQHCONN conn, MQHOBJ obj, MQLONG selectorCount, PMQLONG selectors, MQLONG intAttrCount, PMQLONG intAttrs, MQLONG charAttrLength, PMQCHAR charAttrs)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  inq(conn, obj, selectorCount, selectors, intAttrCount, intAttrs, charAttrLength, charAttrs, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQINQ", cc, rc);
  }
}

void MQFunctions::inq(MQHCONN conn, MQHOBJ obj, const std::vector<int>& intSelectors, const std::map<int, int>& charSelectors, std::map<int, int>& intResult, std::map<int, std::string>& charResult)
{
  std::vector<MQLONG> selectors;
  for(std::vector<int>::const_iterator it = intSelectors.begin(); it != intSelectors.end(); it++)
  {
    selectors.push_back(*it);
  }

  std::vector<MQLONG> intAttrs(intSelectors.size());

  MQLONG charAttrLength = 0;
  for(std::map<int, int>::const_iterator it = charSelectors.begin(); it != charSelectors.end(); it++)
  {
    selectors.push_back(it->first);
    charAttrLength += it->second;
  }
  std::vector<MQCHAR> charAttrs(charAttrLength);

  inq(conn, obj, selectors.size(), selectors.size() == 0 ? NULL : &selectors[0],
                 intAttrs.size(), intAttrs.size() == 0 ? NULL : &intAttrs[0],
                 charAttrs.size(), charAttrs.size() == 0 ? NULL : &charAttrs[0]);

  for(int i = 0; i < intAttrs.size(); i++)
  {
    intResult[intSelectors[i]] = intAttrs[i];
  }

  std::string result(charAttrs.begin(), charAttrs.end());
  for(std::map<int, int>::const_iterator it = charSelectors.begin(); it != charSelectors.end(); it++)
  {
    std::string value = result.substr(0, it->second);
    result.erase(0, it->second);
    value.erase(value.find_last_not_of(" \n\r\t")+1); // trim

    charResult[it->first] = value;
  }
}

void MQFunctions::trace(const std::string& subject, const std::string& function, PMQLONG cc, PMQLONG rc)
{
  Poco::Logger& logger = Poco::Logger::get("mq");
  if ( logger.trace() )
  {
    std::string msg;
    if ( ! subject.empty() )
    {
      msg.append(subject);
      msg.append(" - ");
    }
    msg.append(function);
    msg.append(" : CC=");
    Poco::NumberFormatter::append(msg, *cc);
    msg.append(" : RC=");
    Poco::NumberFormatter::append(msg, *rc);

    logger.trace(msg);
  }
}

} // Namespace MQWeb
<commit_msg>Use Poco's trim functions<commit_after>/*
 * Copyright 2010 MQWeb - Franky Braem
 *
 * Licensed under the EUPL, Version 1.1 or  as soon they
 * will be approved by the European Commission - subsequent
 * versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the
 * Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://joinup.ec.europa.eu/software/page/eupl
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the Licence is
 * distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the Licence for the specific language governing
 * permissions and limitations under the Licence.
 */
#include <MQ/MQFunctions.h>
#include <MQ/MQException.h>

#include <Poco/String.h>
#include <Poco/ScopedLock.h>
#include <Poco/Logger.h>
#include <Poco/NumberFormatter.h>

#ifdef __linux__
#include <string.h>
#endif

namespace MQ
{

Poco::Mutex MQFunctions::_MQIMutex;

MQFunctions::MQFunctions() :
    _connFn(NULL)
  , _connxFn(NULL)
  , _openFn(NULL)
  , _closeFn(NULL)
  , _putFn(NULL)
  , _getFn(NULL)
  , _discFn(NULL)
  , _inqFn(NULL)
{
}

MQFunctions::~MQFunctions()
{
  if ( _dll.isLoaded() )
  {
    _dll.unload();
  }
}

void MQFunctions::loadLibrary(const std::string& mqLibrary)
{
  if ( ! _dll.isLoaded() )
  {
     _dll.load(mqLibrary);
  }

  _connFn = (ConnFn) _dll.getSymbol("MQCONN");
  _connxFn = (ConnxFn) _dll.getSymbol("MQCONNX");
  _openFn = (OpenFn) _dll.getSymbol("MQOPEN");
  _closeFn = (CloseFn) _dll.getSymbol("MQCLOSE");
  _putFn = (PutFn) _dll.getSymbol("MQPUT");
  _getFn = (GetFn) _dll.getSymbol("MQGET");
  _discFn = (DiscFn) _dll.getSymbol("MQDISC");
  _inqFn = (InqFn) _dll.getSymbol("MQINQ");
}

void MQFunctions::conn(char* qmgrName, MQHCONN* hconn, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_connFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _connFn(qmgrName, hconn, cc, rc);

  trace(qmgrName, "MQCONN", cc, rc);
}

MQHCONN MQFunctions::conn(const std::string& qmgrName)
{
  MQCHAR48 name;
  strncpy(name, qmgrName.c_str(), sizeof(MQCHAR48));

  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;
  MQHCONN qmgr = 0;

  conn(name, &qmgr, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException(qmgrName, "MQCONN", cc, rc);
  }

  return qmgr;
}

void MQFunctions::connx(char* qmgrName, MQCNO* connectOpts, MQHCONN* hconn, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_connxFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _connxFn(qmgrName, connectOpts, hconn, cc, rc);

  trace(qmgrName, "MQCONNX", cc, rc);
}

MQHCONN MQFunctions::connx(const std::string& qmgrName, MQCNO* connectOpts)
{
  MQCHAR48 name;
  memset(name, '0', sizeof(MQCHAR48));
  strncpy(name, qmgrName.c_str(), sizeof(MQCHAR48));

  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;
  MQHCONN qmgr = 0;

  connx(name, connectOpts, &qmgr, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException(qmgrName, "MQCONNX", cc, rc);
  }

  return qmgr;
}

void MQFunctions::open(MQHCONN conn, MQOD* od, MQLONG options, MQHOBJ* obj, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_openFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _openFn(conn, od, options, obj, cc, rc);

  Poco::Logger& logger = Poco::Logger::get("mq");
  if ( logger.trace() )
  {
	std::string name(od->ObjectName, MQ_OBJECT_NAME_LENGTH);
	size_t zero = name.find_first_of('\0');
	if ( zero != std::string::npos ) // MQ Strings can have only 0's
	{
		name = name.substr(0, zero);
	}

	Poco::trimRightInPlace(name);
	trace(name, "MQOPEN", cc, rc);
  }
}

MQHOBJ MQFunctions::open(MQHCONN conn, MQOD* od, MQLONG options)
{
  MQHOBJ obj = 0;

  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;
  open(conn, od, options, &obj, &cc, &rc);

  if ( cc != MQCC_OK )
  {
	std::string name(od->ObjectName, MQ_OBJECT_NAME_LENGTH);
	size_t zero = name.find_first_not_of('\0');
	if ( zero == std::string::npos ) // MQ Strings can have only 0's
	{
		name = name.substr(0, zero);
	}

	Poco::trimRightInPlace(name);

    throw MQException(name, "MQOPEN", cc, rc);
  }

  return obj;
}

void MQFunctions::put(MQHCONN conn, MQHOBJ obj, MQMD* md, MQPMO* options, MQLONG size, MQBYTE* buffer, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_putFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _putFn(conn, obj, md, options, size, buffer, cc, rc);

  trace("", "MQPUT", cc, rc);
}

void MQFunctions::put(MQHCONN conn, MQHOBJ obj, MQMD* md, MQPMO* options, MQLONG size, MQBYTE* buffer)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  put(conn, obj, md, options, size, buffer, &cc, &rc);

  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQPUT", cc, rc);
  }
}

void MQFunctions::get(MQHCONN conn, MQHOBJ obj, MQMD* md, MQGMO* options, MQLONG size, MQBYTE* buffer, PMQLONG dataLength, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_getFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _getFn(conn, obj, md, options, size, buffer, dataLength, cc, rc);

  trace("", "MQGET", cc, rc);
}

void MQFunctions::get(MQHCONN conn, MQHOBJ obj, MQMD* md, MQGMO* options, MQLONG size, MQBYTE* buffer, PMQLONG dataLength)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  get(conn, obj, md, options, size, buffer, dataLength, &cc, &rc);

  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQGET", cc, rc);
  }
}

void MQFunctions::close(MQHCONN conn, MQHOBJ* obj, MQLONG options, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_closeFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _closeFn(conn, obj, options, cc, rc);

  trace("", "MQCLOSE", cc, rc);
}

void MQFunctions::close(MQHCONN conn, MQHOBJ* obj, MQLONG options)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  close(conn, obj, options, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQCLOSE", cc, rc);
  }
}

void MQFunctions::disc(PMQHCONN conn, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_discFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _discFn(conn, cc, rc);

  trace("", "MQDISC", cc, rc);
}

void MQFunctions::disc(PMQHCONN conn)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  disc(conn, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQDISC", cc, rc);
  }
}

void MQFunctions::inq(MQHCONN conn, MQHOBJ obj, MQLONG selectorCount, PMQLONG selectors, MQLONG intAttrCount, PMQLONG intAttrs, MQLONG charAttrLength, PMQCHAR charAttrs, PMQLONG cc, PMQLONG rc)
{
  poco_assert_dbg(_inqFn != NULL);

  Poco::ScopedLock<Poco::Mutex> lock(_MQIMutex);
  _inqFn(conn, obj, selectorCount, selectors, intAttrCount, intAttrs, charAttrLength, charAttrs, cc, rc);
}

void MQFunctions::inq(MQHCONN conn, MQHOBJ obj, MQLONG selectorCount, PMQLONG selectors, MQLONG intAttrCount, PMQLONG intAttrs, MQLONG charAttrLength, PMQCHAR charAttrs)
{
  MQLONG cc = MQCC_OK;
  MQLONG rc = MQRC_NONE;

  inq(conn, obj, selectorCount, selectors, intAttrCount, intAttrs, charAttrLength, charAttrs, &cc, &rc);
  if ( cc != MQCC_OK )
  {
    throw MQException("", "MQINQ", cc, rc);
  }
}

void MQFunctions::inq(MQHCONN conn, MQHOBJ obj, const std::vector<int>& intSelectors, const std::map<int, int>& charSelectors, std::map<int, int>& intResult, std::map<int, std::string>& charResult)
{
  std::vector<MQLONG> selectors;
  for(std::vector<int>::const_iterator it = intSelectors.begin(); it != intSelectors.end(); it++)
  {
    selectors.push_back(*it);
  }

  std::vector<MQLONG> intAttrs(intSelectors.size());

  MQLONG charAttrLength = 0;
  for(std::map<int, int>::const_iterator it = charSelectors.begin(); it != charSelectors.end(); it++)
  {
    selectors.push_back(it->first);
    charAttrLength += it->second;
  }
  std::vector<MQCHAR> charAttrs(charAttrLength);

  inq(conn, obj, selectors.size(), selectors.size() == 0 ? NULL : &selectors[0],
                 intAttrs.size(), intAttrs.size() == 0 ? NULL : &intAttrs[0],
                 charAttrs.size(), charAttrs.size() == 0 ? NULL : &charAttrs[0]);

  for(int i = 0; i < intAttrs.size(); i++)
  {
    intResult[intSelectors[i]] = intAttrs[i];
  }

  std::string result(charAttrs.begin(), charAttrs.end());
  for(std::map<int, int>::const_iterator it = charSelectors.begin(); it != charSelectors.end(); it++)
  {
    std::string value = result.substr(0, it->second);
    result.erase(0, it->second);
    charResult[it->first] = Poco::trimRightInPlace(value);
  }
}

void MQFunctions::trace(const std::string& subject, const std::string& function, PMQLONG cc, PMQLONG rc)
{
  Poco::Logger& logger = Poco::Logger::get("mq");
  if ( logger.trace() )
  {
    std::string msg;
    if ( ! subject.empty() )
    {
      msg.append(subject);
      msg.append(" - ");
    }
    msg.append(function);
    msg.append(" : CC=");
    Poco::NumberFormatter::append(msg, *cc);
    msg.append(" : RC=");
    Poco::NumberFormatter::append(msg, *rc);

    logger.trace(msg);
  }
}

} // Namespace MQWeb
<|endoftext|>


<commit_before>#include "interpreter.h"

#include "details/autoconfigurer.h"
#include "details/robotImplementations/unrealRobotModelImplementation.h"
#include "details/robotCommunication/bluetoothRobotCommunicationThread.h"
#include "details/robotCommunication/usbRobotCommunicationThread.h"
#include "details/tracer.h"
#include "details/debugHelper.h"

#include <QtGui/QAction>

using namespace qReal;
using namespace interpreters::robots;
using namespace interpreters::robots::details;

const Id startingElementType = Id("RobotsMetamodel", "RobotsDiagram", "InitialNode");
const Id startingElementType1 = Id("RobotsMetamodel", "RobotsDiagram", "InitialBlock");

Interpreter::Interpreter()
	: mGraphicalModelApi(NULL)
	, mLogicalModelApi(NULL)
	, mInterpretersInterface(NULL)
	, mState(idle)
	, mRobotModel(new RobotModel())
	, mBlocksTable(NULL)
	, mRobotCommunication(new RobotCommunication(SettingsManager::value("valueOfCommunication", "bluetooth").toString()))
	, mImplementationType(robotModelType::null)
	, mWatchListWindow(NULL)
	, mActionConnectToRobot(NULL)
{
	mParser = NULL;
	mBlocksTable = NULL;
	mTimer = new QTimer();

	mD2RobotModel = new d2Model::D2RobotModel();
	mD2ModelWidget = mD2RobotModel->createModelWidget();

	connect(mRobotModel, SIGNAL(disconnected()), this, SLOT(disconnectSlot()));
	connect(mRobotModel, SIGNAL(sensorsConfigured()), this, SLOT(sensorsConfiguredSlot()));
	connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
}

void Interpreter::init(GraphicalModelAssistInterface const &graphicalModelApi
	, LogicalModelAssistInterface const &logicalModelApi
	, qReal::gui::MainWindowInterpretersInterface &interpretersInterface)
{
	mGraphicalModelApi = &graphicalModelApi;
	mLogicalModelApi = &logicalModelApi;
	mInterpretersInterface = &interpretersInterface;

	mParser = new RobotsBlockParser(mInterpretersInterface->errorReporter());
	mBlocksTable = new BlocksTable(graphicalModelApi, logicalModelApi, mRobotModel, mInterpretersInterface->errorReporter(), mParser);

	robotModelType::robotModelTypeEnum const modelType = static_cast<robotModelType::robotModelTypeEnum>(SettingsManager::value("robotModel", "1").toInt());
	Tracer::debug(tracer::initialization, "Interpreter::init", "Going to set robot implementation, model type is " + DebugHelper::toString(modelType));
	setRobotImplementation(modelType);
}

Interpreter::~Interpreter()
{
	foreach (Thread * const thread, mThreads)
		delete thread;
	delete mBlocksTable;
}

void Interpreter::interpret()
{
	Tracer::debug(tracer::initialization, "Interpreter::interpret", "Preparing for interpretation");

	mInterpretersInterface->errorReporter()->clear();

	Id const &currentDiagramId = mInterpretersInterface->activeDiagram();

	if (!mConnected) {
		mInterpretersInterface->errorReporter()->addInformation(tr("No connection to robot"));
		return;
	}
	if (mState != idle) {
		mInterpretersInterface->errorReporter()->addInformation(tr("Interpreter is already running"));
		return;
	}

	mState = waitingForSensorsConfiguredToLaunch;

	mBlocksTable->setIdleForBlocks();

	Id const startingElement = findStartingElement(currentDiagramId);
	if (startingElement == Id()) {
		mInterpretersInterface->errorReporter()->addError(tr("No entry point found, please add Initial Node to a diagram"));
		return;
	}

	Autoconfigurer configurer(*mGraphicalModelApi, mBlocksTable, mInterpretersInterface->errorReporter(), mRobotModel);
	if (!configurer.configure(currentDiagramId))
		return;
}

void Interpreter::stop()
{
	mRobotModel->stopRobot();
	mState = idle;
	foreach (Thread *thread, mThreads) {
		delete thread;
		mThreads.removeAll(thread);
	}
	mBlocksTable->setFailure();
	/*mBlocksTable->clear();
	mThreads.clear();
	mTimer->stop();*/
}

void Interpreter::stopRobot()
{
	stop();
}

void Interpreter::showWatchList() {
	if (mWatchListWindow != NULL) {
		mWatchListWindow->close();
	}
	mWatchListWindow = new watchListWindow(mParser);
	mWatchListWindow->show();
}

void Interpreter::closeD2ModelWidget()
{
	if (mD2ModelWidget)
		mD2ModelWidget->close();
}

void Interpreter::showD2ModelWidget(bool isVisible)
{
	mD2ModelWidget->init(isVisible);
}

void Interpreter::setD2ModelWidgetActions(QAction *runAction, QAction *stopAction)
{
	mD2ModelWidget->setD2ModelWidgetActions(runAction, stopAction);
}

void Interpreter::setRobotImplementation(robotModelType::robotModelTypeEnum implementationType)
{
	mConnected = false;
	robotImplementations::AbstractRobotModelImplementation *robotImpl =
			robotImplementations::AbstractRobotModelImplementation::robotModel(implementationType, mRobotCommunication, mD2RobotModel);
	setRobotImplementation(robotImpl);
	mImplementationType = implementationType;
	if (mImplementationType != robotModelType::real)
		mRobotModel->init();
}

void Interpreter::connectedSlot(bool success)
{
	if (success) {
		if (mRobotModel->needsConnection()) {
			mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));
		}
	} else {
		Tracer::debug(tracer::initialization, "Interpreter::connectedSlot", "Robot connection status: " + QString::number(success));
		mInterpretersInterface->errorReporter()->addError(tr("Can't connect to a robot."));
	}
	mConnected = success;
	mActionConnectToRobot->setChecked(success);
}

void Interpreter::sensorsConfiguredSlot()
{
	Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Sensors are configured");

	mConnected = true;
	if (mRobotModel->needsConnection())
		mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));

	if (mState == waitingForSensorsConfiguredToLaunch) {
		mState = interpreting;

		Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Starting interpretation");
		mRobotModel->startInterpretation();

		Id const &currentDiagramId = mInterpretersInterface->activeDiagram();
		Id const startingElement = findStartingElement(currentDiagramId);
		Thread * const initialThread = new Thread(*mInterpretersInterface, *mBlocksTable, startingElement);
		addThread(initialThread);
	}
}

Id const Interpreter::findStartingElement(Id const &diagram) const
{
	IdList const children = mGraphicalModelApi->graphicalRepoApi().children(diagram);

	foreach (Id const child, children) {
		if (child.type() == startingElementType || child.type() == startingElementType1)
			return child;
	}

	return Id();
}

void Interpreter::threadStopped()
{
	Thread *thread = static_cast<Thread *>(sender());

	mThreads.removeAll(thread);
	delete thread;

	if (mThreads.isEmpty())
		stop();
}

void Interpreter::newThread(details::blocks::Block * const startBlock)
{
	Thread * const thread = new Thread(*mInterpretersInterface, *mBlocksTable, startBlock->id());
	addThread(thread);
}

void Interpreter::configureSensors(sensorType::SensorTypeEnum const &port1
		, sensorType::SensorTypeEnum const &port2
		, sensorType::SensorTypeEnum const &port3
		, sensorType::SensorTypeEnum const &port4)
{
	mRobotModel->configureSensors(port1, port2, port3, port4);
}

void Interpreter::addThread(details::Thread * const thread)
{
	mThreads.append(thread);
	connect(thread, SIGNAL(stopped()), this, SLOT(threadStopped()));
	connect(thread, SIGNAL(newThread(details::blocks::Block*const)), this, SLOT(newThread(details::blocks::Block*const)));

	thread->interpret();
}

interpreters::robots::details::RobotModel *Interpreter::robotModel()
{
	return mRobotModel;
}

void Interpreter::setRobotModel(details::RobotModel * const robotModel)
{
	mRobotModel = robotModel;
}

void Interpreter::setRobotImplementation(details::robotImplementations::AbstractRobotModelImplementation *robotImpl)
{
	mRobotModel->setRobotImplementation(robotImpl);
	if (robotImpl)
		connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(runTimer()));
}

void Interpreter::runTimer()
{
	mTimer->start(1000);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(readSensorValues()));
	if (mRobotModel->sensor(inputPort::port1)) {
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot1(int)));
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot2(int)));
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot3(int)));
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot4(int)));
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
}

void Interpreter::readSensorValues()
{
	if (mState == idle)
		return;

	if (mRobotModel->sensor(inputPort::port1))
		mRobotModel->sensor(inputPort::port1)->read();
	if (mRobotModel->sensor(inputPort::port2))
		mRobotModel->sensor(inputPort::port2)->read();
	if (mRobotModel->sensor(inputPort::port3))
		mRobotModel->sensor(inputPort::port3)->read();
	if (mRobotModel->sensor(inputPort::port4))
		mRobotModel->sensor(inputPort::port4)->read();
}

void Interpreter::slotFailure()
{
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::slotFailure", "");
}

void Interpreter::responseSlot1(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor1"), sensorValue);
}

void Interpreter::responseSlot2(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor2"), sensorValue);
}

void Interpreter::responseSlot3(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor3"), sensorValue);
}

void Interpreter::responseSlot4(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor4"), sensorValue);
}

void Interpreter::updateSensorValues(QString const &sensorVariableName, int sensorValue)
{
	(*(mParser->getVariables()))[sensorVariableName] = utils::Number(sensorValue, utils::Number::intType);
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::updateSensorValues", sensorVariableName + QString::number(sensorValue));
}

void Interpreter::connectToRobot()
{
	if (mConnected) {
		mRobotModel->stopRobot();
	} else {
		mRobotModel->init();
		mActionConnectToRobot->setChecked(mConnected);
	}
}

void Interpreter::disconnectSlot()
{
	mActionConnectToRobot->setChecked(false);
	mConnected = false;
}

void Interpreter::setRobotModelType(robotModelType::robotModelTypeEnum robotModelType)
{
	setRobotImplementation(robotModelType);
}

void Interpreter::setCommunicator(QString const &valueOfCommunication, QString const &portName)
{
	RobotCommunicationThreadInterface *communicator = NULL;
	if (valueOfCommunication == "bluetooth")
		communicator = new BluetoothRobotCommunicationThread();
	else
		communicator = new UsbRobotCommunicationThread();

	mRobotCommunication->setRobotCommunicationThreadObject(communicator);
	mRobotCommunication->setPortName(portName);
}

void Interpreter::setConnectRobotAction(QAction *actionConnect)
{
	mActionConnectToRobot = actionConnect;
}
<commit_msg>Button(Connection) comes off when type of connection is changed(real model) Fix for #362<commit_after>#include "interpreter.h"

#include "details/autoconfigurer.h"
#include "details/robotImplementations/unrealRobotModelImplementation.h"
#include "details/robotCommunication/bluetoothRobotCommunicationThread.h"
#include "details/robotCommunication/usbRobotCommunicationThread.h"
#include "details/tracer.h"
#include "details/debugHelper.h"

#include <QtGui/QAction>

using namespace qReal;
using namespace interpreters::robots;
using namespace interpreters::robots::details;

const Id startingElementType = Id("RobotsMetamodel", "RobotsDiagram", "InitialNode");
const Id startingElementType1 = Id("RobotsMetamodel", "RobotsDiagram", "InitialBlock");

Interpreter::Interpreter()
	: mGraphicalModelApi(NULL)
	, mLogicalModelApi(NULL)
	, mInterpretersInterface(NULL)
	, mState(idle)
	, mRobotModel(new RobotModel())
	, mBlocksTable(NULL)
	, mRobotCommunication(new RobotCommunication(SettingsManager::value("valueOfCommunication", "bluetooth").toString()))
	, mImplementationType(robotModelType::null)
	, mWatchListWindow(NULL)
	, mActionConnectToRobot(NULL)
{
	mParser = NULL;
	mBlocksTable = NULL;
	mTimer = new QTimer();

	mD2RobotModel = new d2Model::D2RobotModel();
	mD2ModelWidget = mD2RobotModel->createModelWidget();

	connect(mRobotModel, SIGNAL(disconnected()), this, SLOT(disconnectSlot()));
	connect(mRobotModel, SIGNAL(sensorsConfigured()), this, SLOT(sensorsConfiguredSlot()));
	connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
}

void Interpreter::init(GraphicalModelAssistInterface const &graphicalModelApi
	, LogicalModelAssistInterface const &logicalModelApi
	, qReal::gui::MainWindowInterpretersInterface &interpretersInterface)
{
	mGraphicalModelApi = &graphicalModelApi;
	mLogicalModelApi = &logicalModelApi;
	mInterpretersInterface = &interpretersInterface;

	mParser = new RobotsBlockParser(mInterpretersInterface->errorReporter());
	mBlocksTable = new BlocksTable(graphicalModelApi, logicalModelApi, mRobotModel, mInterpretersInterface->errorReporter(), mParser);

	robotModelType::robotModelTypeEnum const modelType = static_cast<robotModelType::robotModelTypeEnum>(SettingsManager::value("robotModel", "1").toInt());
	Tracer::debug(tracer::initialization, "Interpreter::init", "Going to set robot implementation, model type is " + DebugHelper::toString(modelType));
	setRobotImplementation(modelType);
}

Interpreter::~Interpreter()
{
	foreach (Thread * const thread, mThreads)
		delete thread;
	delete mBlocksTable;
}

void Interpreter::interpret()
{
	Tracer::debug(tracer::initialization, "Interpreter::interpret", "Preparing for interpretation");

	mInterpretersInterface->errorReporter()->clear();

	Id const &currentDiagramId = mInterpretersInterface->activeDiagram();

	if (!mConnected) {
		mInterpretersInterface->errorReporter()->addInformation(tr("No connection to robot"));
		return;
	}
	if (mState != idle) {
		mInterpretersInterface->errorReporter()->addInformation(tr("Interpreter is already running"));
		return;
	}

	mState = waitingForSensorsConfiguredToLaunch;

	mBlocksTable->setIdleForBlocks();

	Id const startingElement = findStartingElement(currentDiagramId);
	if (startingElement == Id()) {
		mInterpretersInterface->errorReporter()->addError(tr("No entry point found, please add Initial Node to a diagram"));
		return;
	}

	Autoconfigurer configurer(*mGraphicalModelApi, mBlocksTable, mInterpretersInterface->errorReporter(), mRobotModel);
	if (!configurer.configure(currentDiagramId))
		return;
}

void Interpreter::stop()
{
	mRobotModel->stopRobot();
	mState = idle;
	foreach (Thread *thread, mThreads) {
		delete thread;
		mThreads.removeAll(thread);
	}
	mBlocksTable->setFailure();
	/*mBlocksTable->clear();
	mThreads.clear();
	mTimer->stop();*/
}

void Interpreter::stopRobot()
{
	stop();
}

void Interpreter::showWatchList() {
	if (mWatchListWindow != NULL) {
		mWatchListWindow->close();
	}
	mWatchListWindow = new watchListWindow(mParser);
	mWatchListWindow->show();
}

void Interpreter::closeD2ModelWidget()
{
	if (mD2ModelWidget)
		mD2ModelWidget->close();
}

void Interpreter::showD2ModelWidget(bool isVisible)
{
	mD2ModelWidget->init(isVisible);
}

void Interpreter::setD2ModelWidgetActions(QAction *runAction, QAction *stopAction)
{
	mD2ModelWidget->setD2ModelWidgetActions(runAction, stopAction);
}

void Interpreter::setRobotImplementation(robotModelType::robotModelTypeEnum implementationType)
{
	mConnected = false;
	robotImplementations::AbstractRobotModelImplementation *robotImpl =
			robotImplementations::AbstractRobotModelImplementation::robotModel(implementationType, mRobotCommunication, mD2RobotModel);
	setRobotImplementation(robotImpl);
	mImplementationType = implementationType;
	if (mImplementationType != robotModelType::real)
		mRobotModel->init();
}

void Interpreter::connectedSlot(bool success)
{
	if (success) {
		if (mRobotModel->needsConnection()) {
			mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));
		}
	} else {
		Tracer::debug(tracer::initialization, "Interpreter::connectedSlot", "Robot connection status: " + QString::number(success));
		mInterpretersInterface->errorReporter()->addError(tr("Can't connect to a robot."));
	}
	mConnected = success;
	mActionConnectToRobot->setChecked(success);
}

void Interpreter::sensorsConfiguredSlot()
{
	Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Sensors are configured");

	if (mRobotModel->needsConnection() && mConnected)
		mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));

	mConnected = true;
	mActionConnectToRobot->setChecked(mConnected);

	if (mState == waitingForSensorsConfiguredToLaunch) {
		mState = interpreting;

		Tracer::debug(tracer::initialization, "Interpreter::sensorsConfiguredSlot", "Starting interpretation");
		mRobotModel->startInterpretation();

		Id const &currentDiagramId = mInterpretersInterface->activeDiagram();
		Id const startingElement = findStartingElement(currentDiagramId);
		Thread * const initialThread = new Thread(*mInterpretersInterface, *mBlocksTable, startingElement);
		addThread(initialThread);
	}
}

Id const Interpreter::findStartingElement(Id const &diagram) const
{
	IdList const children = mGraphicalModelApi->graphicalRepoApi().children(diagram);

	foreach (Id const child, children) {
		if (child.type() == startingElementType || child.type() == startingElementType1)
			return child;
	}

	return Id();
}

void Interpreter::threadStopped()
{
	Thread *thread = static_cast<Thread *>(sender());

	mThreads.removeAll(thread);
	delete thread;

	if (mThreads.isEmpty())
		stop();
}

void Interpreter::newThread(details::blocks::Block * const startBlock)
{
	Thread * const thread = new Thread(*mInterpretersInterface, *mBlocksTable, startBlock->id());
	addThread(thread);
}

void Interpreter::configureSensors(sensorType::SensorTypeEnum const &port1
		, sensorType::SensorTypeEnum const &port2
		, sensorType::SensorTypeEnum const &port3
		, sensorType::SensorTypeEnum const &port4)
{
	mRobotModel->configureSensors(port1, port2, port3, port4);
}

void Interpreter::addThread(details::Thread * const thread)
{
	mThreads.append(thread);
	connect(thread, SIGNAL(stopped()), this, SLOT(threadStopped()));
	connect(thread, SIGNAL(newThread(details::blocks::Block*const)), this, SLOT(newThread(details::blocks::Block*const)));

	thread->interpret();
}

interpreters::robots::details::RobotModel *Interpreter::robotModel()
{
	return mRobotModel;
}

void Interpreter::setRobotModel(details::RobotModel * const robotModel)
{
	mRobotModel = robotModel;
}

void Interpreter::setRobotImplementation(details::robotImplementations::AbstractRobotModelImplementation *robotImpl)
{
	mRobotModel->setRobotImplementation(robotImpl);
	if (robotImpl)
		connect(mRobotModel, SIGNAL(connected(bool)), this, SLOT(runTimer()));
}

void Interpreter::runTimer()
{
	mTimer->start(1000);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(readSensorValues()));
	if (mRobotModel->sensor(inputPort::port1)) {
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot1(int)));
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot2(int)));
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot3(int)));
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot4(int)));
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
}

void Interpreter::readSensorValues()
{
	if (mState == idle)
		return;

	if (mRobotModel->sensor(inputPort::port1))
		mRobotModel->sensor(inputPort::port1)->read();
	if (mRobotModel->sensor(inputPort::port2))
		mRobotModel->sensor(inputPort::port2)->read();
	if (mRobotModel->sensor(inputPort::port3))
		mRobotModel->sensor(inputPort::port3)->read();
	if (mRobotModel->sensor(inputPort::port4))
		mRobotModel->sensor(inputPort::port4)->read();
}

void Interpreter::slotFailure()
{
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::slotFailure", "");
}

void Interpreter::responseSlot1(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor1"), sensorValue);
}

void Interpreter::responseSlot2(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor2"), sensorValue);
}

void Interpreter::responseSlot3(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor3"), sensorValue);
}

void Interpreter::responseSlot4(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor4"), sensorValue);
}

void Interpreter::updateSensorValues(QString const &sensorVariableName, int sensorValue)
{
	(*(mParser->getVariables()))[sensorVariableName] = utils::Number(sensorValue, utils::Number::intType);
	Tracer::debug(tracer::autoupdatedSensorValues, "Interpreter::updateSensorValues", sensorVariableName + QString::number(sensorValue));
}

void Interpreter::connectToRobot()
{
	if (mConnected) {
		mRobotModel->stopRobot();
	} else {
		mRobotModel->init();
		mActionConnectToRobot->setChecked(mConnected);
	}
}

void Interpreter::disconnectSlot()
{
	mActionConnectToRobot->setChecked(false);
	mConnected = false;
}

void Interpreter::setRobotModelType(robotModelType::robotModelTypeEnum robotModelType)
{
	setRobotImplementation(robotModelType);
}

void Interpreter::setCommunicator(QString const &valueOfCommunication, QString const &portName)
{
	RobotCommunicationThreadInterface *communicator = NULL;
	if (valueOfCommunication == "bluetooth")
		communicator = new BluetoothRobotCommunicationThread();
	else
		communicator = new UsbRobotCommunicationThread();

	mRobotCommunication->setRobotCommunicationThreadObject(communicator);
	mRobotCommunication->setPortName(portName);

	disconnectSlot();
}

void Interpreter::setConnectRobotAction(QAction *actionConnect)
{
	mActionConnectToRobot = actionConnect;
}
<|endoftext|>


<commit_before>/**
 * \file SingleGraphFrame.cpp
 * \brief Frame for single graphs
 */

#include "SingleGraphFrame.h"

BEGIN_EVENT_TABLE(SingleGraphFrame,BaseFrame)
END_EVENT_TABLE()

/**
   Constructor for the Main frame.
*/

SingleGraphFrame::SingleGraphFrame(Graph* graph)
: BaseFrame() {
    flightId = "Please select a device from the menu.";

    this->graph = graph;

    CreateGUIControls();

    SetTransparent(245);
}

/**
   Destructor for the Main frame.
*/

SingleGraphFrame::~SingleGraphFrame() {
}

/**
    Updates the GUI with new database information
*/

void SingleGraphFrame::Update() {
    CreateMenu(false, false, true, false);

    graph->Update(flightId);
}

/**
   Creates all of the GUI controls on the frame.
*/

void SingleGraphFrame::CreateGUIControls() {
    // Set window properties and title bar
    SetTitle(wxT("Graph"));
    SetIcon(wxNullIcon);

    mainPanel = new wxPanel(this, wxID_ANY);
    mainSizer = new wxBoxSizer(wxVERTICAL);
    mainPanel->SetSizer(mainSizer);

    graph = new Graph(mainPanel,
                      graph->name,
                      graph->db_table,
                      graph->flightId,
                      graph->db_col);
    mainSizer->Add(graph, 1, wxEXPAND | wxALL);

    Update();

}

wxFrame* NewSingleGraphFrame(Graph* graph) {
    return (wxFrame*)(new SingleGraphFrame(graph));
}

<commit_msg>- cleanup<commit_after>/**
 * \file SingleGraphFrame.cpp
 * \brief Frame for single graphs
 */

#include "SingleGraphFrame.h"

BEGIN_EVENT_TABLE(SingleGraphFrame,BaseFrame)
END_EVENT_TABLE()

/**
   Constructor for the Main frame.
*/

SingleGraphFrame::SingleGraphFrame(Graph* graph)
: BaseFrame() {
    flightId = "Please select a device from the menu.";

    this->graph = graph;

    CreateGUIControls();

    SetTransparent(245);
}

/**
   Destructor for the Main frame.
*/

SingleGraphFrame::~SingleGraphFrame() {
}

/**
    Updates the GUI with new database information
*/

void SingleGraphFrame::Update() {
    CreateMenu(false, false, true, false);

    graph->Update(flightId);
}

/**
   Creates all of the GUI controls on the frame.
*/

void SingleGraphFrame::CreateGUIControls() {
    // Set window properties and title bar
    SetTitle(wxT("Graph"));
    SetIcon(wxNullIcon);

    mainPanel = new wxPanel(this, wxID_ANY);
    mainSizer = new wxBoxSizer(wxVERTICAL);
    mainPanel->SetSizer(mainSizer);

    graph = new Graph(mainPanel,
                      graph->name,
                      graph->db_table,
                      graph->flightId,
                      graph->db_col);
    mainSizer->Add(graph, 1, wxEXPAND | wxALL);

    Update();
}

wxFrame* NewSingleGraphFrame(Graph* graph) {
    return (wxFrame*)(new SingleGraphFrame(graph));
}

<|endoftext|>


<commit_before>#include "ImageOutlineFinder.h"
#include "FMath.h"

#include <poly2tri.h>
#include <iostream>

#include "../liquidfun_contrib/ConvexDecomposition/b2Polygon.h"

ImageOutlineFinder::ImageOutlineFinder()
= default;

ImageOutlineFinder::~ImageOutlineFinder()
= default;

void ImageOutlineFinder::findOutLines(const sf::Image& image, const int alpha_threshold)
{
	alpha_threshold_ = alpha_threshold;
	image_ = image;
	const sf::Vector2i starting_point = findStartingPoint();
	if (starting_point.x > -1)
	{
		traverseBoundary(starting_point);
	}
}

sf::Vector2i ImageOutlineFinder::findStartingPoint() const
{

	for (unsigned int cx = 1; cx < image_.getSize().x; cx++) {
		for (unsigned int cy = 1; cy < image_.getSize().y; cy++) {
			if (isBoundary({ static_cast<int>(cx), static_cast<int>(cy) })) {
				return { static_cast<int>(cx), static_cast<int>(cy) };
			}
		}
	}
	return {-1, -1};
}

void ImageOutlineFinder::traverseBoundary(const sf::Vector2i starting_point)
{
	const sf::Vector2i start = sf::Vector2i(starting_point.x, starting_point.y);
	sf::Vector2i next = start;
	sf::Vector2i old = sf::Vector2i(-1, -1);

	sf::Vector2i next_nsp = { -1, 0 };

	vertices_.push_back(start);

	// Set arbitary limit to length of circumference
	for (unsigned int i = 0; i < static_cast<unsigned int>((image_.getSize().x * image_.getSize().y) / 2); i++) {
		// Save off the last position
		old = next;

		// Find the next clockwise boundary pixel
		next = findNextBoundaryPoint(next, next_nsp);

		// Set the search start point as the previous pixel
		// to avoid loops and continue traversing the shape
		// in the same direction i.e.

		// edge:  x  first point     second point  34x
		//       x            23x                  2x
		//      x             1x                   1

		// In this diagram the numbers represent the order
		// in which the neighboring points are tested. We
		// Always start with the previous point found.
		next_nsp = {old.x - next.x, old.y - next.y};

		// When we get back to the start break the loop
		if (next.x == start.x && next.y == start.y)
			break;

		if (next.x < 0 || next.y < 0)
		{
			sf::Vector2i nnext = next;

			if (nnext.x < 0)
				nnext.x = 0;

			if (nnext.y < 0)
				nnext.y = 0;

			vertices_.push_back(nnext);
		}
		else
		{
			vertices_.push_back(next);
		}
	}

	for (auto& vert : vertices_)
	{
		vert.x -= image_.getSize().x / 2.f;
		vert.y -= image_.getSize().y / 2.f;
	}

}

sf::Vector2i ImageOutlineFinder::findNextBoundaryPoint(const sf::Vector2i point, const sf::Vector2i sp) const
{
	sf::Vector2i nsp = sp;
	for (int i = 0; i < 9; i++) {
		nsp = clockWise(nsp);
		const sf::Vector2i next = { point.x + nsp.x, point.y + nsp.y };
		if (isBoundary(next)) {
			return next;
		}
	}
	return {-1, -1};
}

sf::Vector2i ImageOutlineFinder::clockWise(const sf::Vector2i sp)
{
	if (sp.x == -1) {
		if (sp.y == -1)
			return { -1, 0 };
		if (sp.y == 0)
			return { -1, 1 };
		if (sp.y == 1)
			return { 0, 1 };
	}

	if (sp.x == 0) {
		if (sp.y == -1)
			return {-1, -1};
		if (sp.y == 1)
			return {1, 1};
	}

	if (sp.x == 1) {
		if (sp.y == -1)
			return {0, -1};
		if (sp.y == 0)
			return {1, -1};
		if (sp.y == 1)
			return {1, 0};
	}
	return {-10 , -10};

}

std::vector<sf::Vector2i> ImageOutlineFinder::getVertices() const
{
	return vertices_;
}

std::vector<sf::Vector2f> ImageOutlineFinder::getSimplifiedVertices(const float limit, unsigned int average_before, unsigned int average_after)
{
	std::vector<sf::Vector2f> smoothed_line;
	std::vector<sf::Vector2f> simplified_line;

	if (vertices_.size() == 0)
		return std::vector<sf::Vector2f>();

	smoothed_line.emplace_back(vertices_[0].x, vertices_[0].y);
	std::vector<sf::Vector2f>  average_vertices;

	// Loop over the next [average] vertices and
	// add the result to the array of smoothed points
	if (average_before > 0 && average_before < vertices_.size())
	{
		for (unsigned int i = 0; i < vertices_.size() - average_before; i++) {

			average_vertices.clear();
			for (int j = 0; j < average_before; j++) {
				average_vertices.emplace_back(vertices_[i + j].x, vertices_[i + j].y);
			}
			smoothed_line.push_back(ImageOutlineFinder::average(average_vertices));
		}
	} else
	{
		for (const auto& vert : vertices_)
		{
			smoothed_line.emplace_back(sf::Vector2f(vert.x, vert.y ));
		}
	}

	float curvature_total = 0.f;
	float last_curvature = 0.f;

	for (unsigned int i = 0; i < smoothed_line.size() - 3; i++) {
		// Calculate the curvature
		const float curvature = ImageOutlineFinder::curvature(smoothed_line[i], smoothed_line[i + 1], smoothed_line[i + 2]);

		// Use a curvature accumulator to prevent cases
		// where a line curves gradually - this would be
		// be picked up if we just used the curvature because
		// each individual curvature may be less than our limit
		curvature_total += curvature;

		// If the total curvature is greater than our set
		// limit then add the point to our simplified line
		if (curvature_total > limit) {
			curvature_total = 0;
			if (simplified_line.empty()
				|| (simplified_line.back().x != smoothed_line[i].x && simplified_line.back().y != smoothed_line[i].y))
				simplified_line.push_back(smoothed_line[i]);
		}
	}

	smoothed_line.clear();
	smoothed_line.emplace_back(vertices_[0].x, vertices_[0].y);
	// Loop over the next [average] vertices and
	// add the result to the array of smoothed points
	if (average_after > 0 && average_after < simplified_line.size())
	{
		for (unsigned int i = 0; i < simplified_line.size() - average_after; i++) {

			average_vertices.clear();
			for (int j = 0; j < average_after; j++) {
				average_vertices.emplace_back(simplified_line[i + j].x, simplified_line[i + j].y);
			}
			smoothed_line.push_back(ImageOutlineFinder::average(average_vertices));
		}
		return smoothed_line;
	}
	return simplified_line;
}

std::vector<std::vector<sf::Vector2f>> ImageOutlineFinder::getSimplifiedTriangles(const float limit, const unsigned int average,const unsigned int average_after, const float min_area)
{
	std::vector<std::vector<sf::Vector2f>> result;

	std::vector<sf::Vector2f> simplified_verts = getSimplifiedVertices(limit, average, average_after);

	if (simplified_verts.size() < 3)
		return result;

	std::vector<p2t::Point*> polyline;

	polyline.reserve(simplified_verts.size());
	for (auto& point : simplified_verts)
	{
		polyline.push_back(new p2t::Point(point.x, point.y));
	}

	p2t::CDT* cdt = new p2t::CDT(polyline);
	cdt->Triangulate();
	auto tris = cdt->GetTriangles();

	for (auto& tri : tris)
	{
		std::vector<sf::Vector2f> sf_tri;
		sf_tri.reserve(3);
		p2t::Point* p = tri->GetPoint(0);
		sf_tri.emplace_back( p->x, p->y );
		p = tri->PointCCW(*p);
		sf_tri.emplace_back( p->x, p->y );
		p = tri->PointCCW(*p);
		sf_tri.emplace_back( p->x, p->y );

		float area = (sf_tri[0].x*(sf_tri[1].y - sf_tri[2].x)
			+ sf_tri[1].x*(sf_tri[2].y - sf_tri[0].y)
			+ sf_tri[2].x*(sf_tri[0].y - sf_tri[1].y)) / 2.f;
		if (area < 0)
			area *= -1;

		if (area >= min_area)
			result.push_back(sf_tri);
	}

	for (auto & i : polyline) {
		delete i;
	}
	polyline.clear();
	delete cdt;
	return result;
}

std::vector<std::vector<sf::Vector2f>> ImageOutlineFinder::getSimplifiedPolys(float limit, unsigned average,
	unsigned average_after, unsigned int max_polys)
{

	auto simplverts = getSimplifiedVertices(limit, average, average_after);
	std::vector<b2Vec2> cloud;

	if (limit < 0)
	{
		cloud.reserve(simplverts.size());

		for (const auto & vert : simplverts)
		{
			cloud.emplace_back(vert.x, vert.y);
		}
	}
	else
	{
		cloud.reserve(vertices_.size());

		for (const auto & vert : vertices_)
		{
			cloud.emplace_back(vert.x, vert.y);
		}
	}

	if (cloud.size() < 3)
		return std::vector<std::vector<sf::Vector2f>>();

	b2Polygon polygon = ConvexHull(cloud.data(), cloud.size());

	std::vector<b2Polygon> polys;
	polys.resize(max_polys);
	const auto size = DecomposeConvex(&polygon, polys.data(), max_polys);

	std::vector<std::vector<sf::Vector2f>> result;

	if (size == -1)
		return result;

	result.reserve(size);
	for (auto i = 0; i < size; i++)
	{
		if (polys[i].IsUsable(true) && polys[i].nVertices > 3)
		{
			std::vector<sf::Vector2f> poly;
			poly.reserve(polys[i].nVertices);
			auto verts = polys[i].GetVertexVecs();
			for (auto j = 0; j < polys[i].nVertices; j++)
			{
				poly.emplace_back(verts->x, verts->y);
				verts++;
			}
			result.push_back(poly);
		}
	}

	return result;
}

bool ImageOutlineFinder::isBoundary(const sf::Vector2i point) const
{

	if (!pointHasAlpha(point))
		return false;

	for (int i = -1; i<2; i++) {
		for (int j = -1; j<2; j++) {
			if (!pointHasAlpha({ point.x + i, point.y + j }))
				return true;
		}
	}

	// If this point has alpha and all of the ajoining points
	// have alpha then it's not a boundary
	return false;
}

bool ImageOutlineFinder::pointHasAlpha(const sf::Vector2i point) const
{
	if (point.x < 0 || point.x > static_cast<int>(image_.getSize().x - 1)
		|| point.y < 0 || point.y > static_cast<int>(image_.getSize().y - 1))
		return true;

	return image_.getPixel(point.x, point.y).a < alpha_threshold_;
}

sf::Vector2f ImageOutlineFinder::average(std::vector<sf::Vector2f> vertices)
{
	sf::Vector2f average = vertices[0];
	for (auto& v : vertices)
	{
		if (v.x == vertices[0].x && v.y == vertices[0].y)
			continue;
		average = { average.x + v.x, average.y + v.y };
	}
	average = { average.x / vertices.size(), average.y / vertices.size() };
	return average;
}

sf::Vector2f ImageOutlineFinder::midPoint(const sf::Vector2f v1, const sf::Vector2f v2)
{
	return { (v1.x + v2.x) / 2.f, (v1.y + v2.y) / 2.f };
}

float ImageOutlineFinder::curvature(const sf::Vector2f v1, const sf::Vector2f v2, const sf::Vector2f v3)
{
	const sf::Vector2f mid_point = midPoint(v1, v3);
	return sq(mid_point.x - v2.x) + sq(mid_point.y - v2.y);
}

float ImageOutlineFinder::sq(const float f)
{
	return f * f;
}

<commit_msg>some fix image tracing of in some fringe cases<commit_after>#include "ImageOutlineFinder.h"
#include "FMath.h"

#include <poly2tri.h>
#include <iostream>

#include "../liquidfun_contrib/ConvexDecomposition/b2Polygon.h"

ImageOutlineFinder::ImageOutlineFinder()
= default;

ImageOutlineFinder::~ImageOutlineFinder()
= default;

void ImageOutlineFinder::findOutLines(const sf::Image& image, const int alpha_threshold)
{
	alpha_threshold_ = alpha_threshold;
	image_ = image;
	const sf::Vector2i starting_point = findStartingPoint();
	if (starting_point.x > -1)
	{
		traverseBoundary({ starting_point.x + 1, starting_point.y + 1 });
	}
}

sf::Vector2i ImageOutlineFinder::findStartingPoint() const
{
	for (unsigned int cx = 1; cx < image_.getSize().x; cx++) {
		for (unsigned int cy = 1; cy < image_.getSize().y; cy++) {
			if (isBoundary({ static_cast<int>(cx), static_cast<int>(cy) })) {
				return { static_cast<int>(cx), static_cast<int>(cy) };
			}
		}
	}
	return {-1, -1};
}

void ImageOutlineFinder::traverseBoundary(const sf::Vector2i starting_point)
{
	const sf::Vector2i start = sf::Vector2i(starting_point.x, starting_point.y);
	sf::Vector2i next = start;
	sf::Vector2i old = sf::Vector2i(-1, -1);

	sf::Vector2i next_nsp = { -1, 0 };

	vertices_.push_back(start);

	// Set arbitary limit to length of circumference
	for (unsigned int i = 0; i < static_cast<unsigned int>((image_.getSize().x * image_.getSize().y) / 2); i++) {
		// Save off the last position
		old = next;

		// Find the next clockwise boundary pixel
		next = findNextBoundaryPoint(next, next_nsp);

		// Set the search start point as the previous pixel
		// to avoid loops and continue traversing the shape
		// in the same direction i.e.

		// edge:  x  first point     second point  34x
		//       x            23x                  2x
		//      x             1x                   1

		// In this diagram the numbers represent the order
		// in which the neighboring points are tested. We
		// Always start with the previous point found.
		next_nsp = {old.x - next.x, old.y - next.y};

		// When we get back to the start break the loop
		if (next.x == start.x && next.y == start.y)
			break;

		if (next.x < 0 || next.y < 0)
		{
			sf::Vector2i nnext = next;

			if (nnext.x < 0)
				nnext.x = 0;

			if (nnext.y < 0)
				nnext.y = 0;

			vertices_.push_back(nnext);
		}
		else
		{
			vertices_.push_back(next);
		}
	}

	for (auto& vert : vertices_)
	{
		vert.x -= image_.getSize().x / 2.f;
		vert.y -= image_.getSize().y / 2.f;
	}

}

sf::Vector2i ImageOutlineFinder::findNextBoundaryPoint(const sf::Vector2i point, const sf::Vector2i sp) const
{
	sf::Vector2i nsp = sp;
	for (int i = 0; i < 9; i++) {
		nsp = clockWise(nsp);
		const sf::Vector2i next = { point.x + nsp.x, point.y + nsp.y };
		if (isBoundary(next)) {
			return next;
		}
	}
	return {-1, -1};
}

sf::Vector2i ImageOutlineFinder::clockWise(const sf::Vector2i sp)
{
	if (sp.x == -1) {
		if (sp.y == -1)
			return { -1, 0 };
		if (sp.y == 0)
			return { -1, 1 };
		if (sp.y == 1)
			return { 0, 1 };
	}

	if (sp.x == 0) {
		if (sp.y == -1)
			return {-1, -1};
		if (sp.y == 1)
			return {1, 1};
	}

	if (sp.x == 1) {
		if (sp.y == -1)
			return {0, -1};
		if (sp.y == 0)
			return {1, -1};
		if (sp.y == 1)
			return {1, 0};
	}
	return {-10 , -10};

}

std::vector<sf::Vector2i> ImageOutlineFinder::getVertices() const
{
	return vertices_;
}

std::vector<sf::Vector2f> ImageOutlineFinder::getSimplifiedVertices(const float limit, unsigned int average_before, unsigned int average_after)
{
	std::vector<sf::Vector2f> smoothed_line;
	std::vector<sf::Vector2f> simplified_line;

	if (vertices_.size() == 0)
		return std::vector<sf::Vector2f>();

	smoothed_line.emplace_back(vertices_[0].x, vertices_[0].y);
	std::vector<sf::Vector2f>  average_vertices;

	// Loop over the next [average] vertices and
	// add the result to the array of smoothed points
	if (average_before > 0 && average_before < vertices_.size())
	{
		for (unsigned int i = 0; i < vertices_.size() - average_before; i++) {

			average_vertices.clear();
			for (int j = 0; j < average_before; j++) {
				average_vertices.emplace_back(vertices_[i + j].x, vertices_[i + j].y);
			}
			smoothed_line.push_back(ImageOutlineFinder::average(average_vertices));
		}
	} else
	{
		for (const auto& vert : vertices_)
		{
			smoothed_line.emplace_back(sf::Vector2f(vert.x, vert.y ));
		}
	}

	float curvature_total = 0.f;
	float last_curvature = 0.f;

	for (unsigned int i = 0; i < smoothed_line.size() - 3; i++) {
		// Calculate the curvature
		const float curvature = ImageOutlineFinder::curvature(smoothed_line[i], smoothed_line[i + 1], smoothed_line[i + 2]);

		// Use a curvature accumulator to prevent cases
		// where a line curves gradually - this would be
		// be picked up if we just used the curvature because
		// each individual curvature may be less than our limit
		curvature_total += curvature;

		// If the total curvature is greater than our set
		// limit then add the point to our simplified line
		if (curvature_total > limit) {
			curvature_total = 0;
			if (simplified_line.empty()
				|| (simplified_line.back().x != smoothed_line[i].x && simplified_line.back().y != smoothed_line[i].y))
				simplified_line.push_back(smoothed_line[i]);
		}
	}

	smoothed_line.clear();
	smoothed_line.emplace_back(vertices_[0].x, vertices_[0].y);
	// Loop over the next [average] vertices and
	// add the result to the array of smoothed points
	if (average_after > 0 && average_after < simplified_line.size())
	{
		for (unsigned int i = 0; i < simplified_line.size() - average_after; i++) {

			average_vertices.clear();
			for (int j = 0; j < average_after; j++) {
				average_vertices.emplace_back(simplified_line[i + j].x, simplified_line[i + j].y);
			}
			smoothed_line.push_back(ImageOutlineFinder::average(average_vertices));
		}
		return smoothed_line;
	}
	return simplified_line;
}

std::vector<std::vector<sf::Vector2f>> ImageOutlineFinder::getSimplifiedTriangles(const float limit, const unsigned int average,const unsigned int average_after, const float min_area)
{
	std::vector<std::vector<sf::Vector2f>> result;

	std::vector<sf::Vector2f> simplified_verts = getSimplifiedVertices(limit, average, average_after);

	if (simplified_verts.size() < 3)
		return result;

	std::vector<p2t::Point*> polyline;

	polyline.reserve(simplified_verts.size());
	for (auto& point : simplified_verts)
	{
		polyline.push_back(new p2t::Point(point.x, point.y));
	}

	p2t::CDT* cdt = new p2t::CDT(polyline);
	cdt->Triangulate();
	auto tris = cdt->GetTriangles();

	for (auto& tri : tris)
	{
		std::vector<sf::Vector2f> sf_tri;
		sf_tri.reserve(3);
		p2t::Point* p = tri->GetPoint(0);
		sf_tri.emplace_back( p->x, p->y );
		p = tri->PointCCW(*p);
		sf_tri.emplace_back( p->x, p->y );
		p = tri->PointCCW(*p);
		sf_tri.emplace_back( p->x, p->y );

		float area = (sf_tri[0].x*(sf_tri[1].y - sf_tri[2].x)
			+ sf_tri[1].x*(sf_tri[2].y - sf_tri[0].y)
			+ sf_tri[2].x*(sf_tri[0].y - sf_tri[1].y)) / 2.f;
		if (area < 0)
			area *= -1;

		if (area >= min_area)
			result.push_back(sf_tri);
	}

	for (auto & i : polyline) {
		delete i;
	}
	polyline.clear();
	delete cdt;
	return result;
}

std::vector<std::vector<sf::Vector2f>> ImageOutlineFinder::getSimplifiedPolys(float limit, unsigned average,
	unsigned average_after, unsigned int max_polys)
{

	auto simplverts = getSimplifiedVertices(limit, average, average_after);
	std::vector<b2Vec2> cloud;

	if (limit < 0)
	{
		cloud.reserve(simplverts.size());

		for (const auto & vert : simplverts)
		{
			cloud.emplace_back(vert.x, vert.y);
		}
	}
	else
	{
		cloud.reserve(vertices_.size());

		for (const auto & vert : vertices_)
		{
			cloud.emplace_back(vert.x, vert.y);
		}
	}

	if (cloud.size() < 3)
		return std::vector<std::vector<sf::Vector2f>>();

	b2Polygon polygon = ConvexHull(cloud.data(), cloud.size());

	std::vector<b2Polygon> polys;
	polys.resize(max_polys);
	const auto size = DecomposeConvex(&polygon, polys.data(), max_polys);

	std::vector<std::vector<sf::Vector2f>> result;

	if (size == -1)
		return result;

	result.reserve(size);
	for (auto i = 0; i < size; i++)
	{
		if (polys[i].IsUsable(true) && polys[i].nVertices > 3)
		{
			std::vector<sf::Vector2f> poly;
			poly.reserve(polys[i].nVertices);
			auto verts = polys[i].GetVertexVecs();
			for (auto j = 0; j < polys[i].nVertices; j++)
			{
				poly.emplace_back(verts->x, verts->y);
				verts++;
			}
			result.push_back(poly);
		}
	}

	return result;
}

bool ImageOutlineFinder::isBoundary(const sf::Vector2i point) const
{

	if (!pointHasAlpha(point))
		return false;

	for (int i = -1; i<2; i++) {
		for (int j = -1; j<2; j++) {
			if (!pointHasAlpha({ point.x + i, point.y + j }))
				return true;
		}
	}

	// If this point has alpha and all of the ajoining points
	// have alpha then it's not a boundary
	return false;
}

bool ImageOutlineFinder::pointHasAlpha(const sf::Vector2i point) const
{
	if (point.x < 0 || point.x > static_cast<int>(image_.getSize().x - 1)
		|| point.y < 0 || point.y > static_cast<int>(image_.getSize().y - 1))
		return true;

	return image_.getPixel(point.x, point.y).a < alpha_threshold_;
}

sf::Vector2f ImageOutlineFinder::average(std::vector<sf::Vector2f> vertices)
{
	sf::Vector2f average = vertices[0];
	for (auto& v : vertices)
	{
		if (v.x == vertices[0].x && v.y == vertices[0].y)
			continue;
		average = { average.x + v.x, average.y + v.y };
	}
	average = { average.x / vertices.size(), average.y / vertices.size() };
	return average;
}

sf::Vector2f ImageOutlineFinder::midPoint(const sf::Vector2f v1, const sf::Vector2f v2)
{
	return { (v1.x + v2.x) / 2.f, (v1.y + v2.y) / 2.f };
}

float ImageOutlineFinder::curvature(const sf::Vector2f v1, const sf::Vector2f v2, const sf::Vector2f v3)
{
	const sf::Vector2f mid_point = midPoint(v1, v3);
	return sq(mid_point.x - v2.x) + sq(mid_point.y - v2.y);
}

float ImageOutlineFinder::sq(const float f)
{
	return f * f;
}

<|endoftext|>


<commit_before>#include <string>
#include <stdexcept>
#include <memory>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "rect.h"
#include "image.h"
#include "window.h"

//Initialize the unique_ptr's deleters here
std::unique_ptr<SDL_Window, void (*)(SDL_Window*)> Window::mWindow
	= std::unique_ptr<SDL_Window, void (*)(SDL_Window*)>(nullptr, SDL_DestroyWindow);
std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)> Window::mRenderer
	= std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)>(nullptr, SDL_DestroyRenderer);
//other static members
Recti Window::mBox;
int Window::SCREEN_WIDTH;
int Window::SCREEN_HEIGHT;

Window::~Window(){}
void Window::Init(std::string title){
	//initialize all SDL subsystems
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
		throw std::runtime_error("SDL Init Failed");
    if (TTF_Init() == -1)
		throw std::runtime_error("TTF Init Failed");

	//Start up window
	SCREEN_WIDTH = 1280;
	SCREEN_HEIGHT = 720;
	//TODO: Solve the resized window issues
	mWindow.reset(SDL_CreateWindow(title.c_str(), 100, 100, SCREEN_WIDTH,
		SCREEN_HEIGHT, SDL_WINDOW_SHOWN));// | SDL_WINDOW_RESIZABLE));
	//if window failed to create
	if (mWindow == nullptr)
		throw std::runtime_error("Failed to open window");

	//Start up the renderer
	mRenderer.reset(SDL_CreateRenderer(mWindow.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC));
	//Make sure it went ok
	if (mRenderer == nullptr)
		throw std::runtime_error("Failed to start renderer");
	//initialize the window box
	mBox.Set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
}
void Window::Quit(){
	TTF_Quit();
	SDL_Quit();
}
void Window::Draw(int x, int y, SDL_Texture *tex, SDL_Rect *clip, int w, int h,
				  float angle, Vector2f pivot, SDL_RendererFlip flip)
{
	SDL_Rect dstRect;
	dstRect.x = x;
	dstRect.y = y;
	//Setup desired width and height properties
	if (w == -1 && h == -1)
		SDL_QueryTexture(tex, NULL, NULL, &dstRect.w, &dstRect.h);
	else {
		dstRect.w = w;
		dstRect.h = h;
	}
	//Calculate the pivot point as an offset from image center
	pivot.x = dstRect.w / 2 + pivot.x;
	pivot.y = dstRect.h / 2 + pivot.y;

	//Draw the texture
	SDL_RenderCopyEx(mRenderer.get(), tex, clip, &dstRect, angle, &(SDL_Point)pivot, flip);
}
void Window::Draw(Image *image, const SDL_Rect &dstRect, SDL_Rect *clip, float angle,
				  Vector2f pivot, SDL_RendererFlip flip)
{
	Draw(dstRect.x, dstRect.y, image->Texture(), clip, dstRect.w, dstRect.h);
}
void Window::Draw(Text *text, SDL_Rect dstRect, float angle,
				  Vector2f pivot, SDL_RendererFlip flip)
{
	text->GetSize(dstRect.w, dstRect.h);
	Draw(dstRect.x, dstRect.y, text->Texture(), NULL, dstRect.w, dstRect.h);
}
SDL_Texture* Window::LoadTexture(std::string file){
	SDL_Texture *tex = nullptr;
	tex = IMG_LoadTexture(mRenderer.get(), file.c_str());
	if (tex == nullptr)
		throw std::runtime_error("Failed to load image: " + file);
	return tex;
}
SDL_Texture* Window::SurfaceToTexture(SDL_Surface *surf){
	SDL_Texture *tex = nullptr;
	tex = SDL_CreateTextureFromSurface(mRenderer.get(), surf);
	if (tex == nullptr)
		throw std::runtime_error("Failed to convert surface");
	SDL_FreeSurface(surf);
	return tex;
}
void Window::Clear(){
	SDL_RenderClear(mRenderer.get());
}
void Window::Present(){
	SDL_RenderPresent(mRenderer.get());
}
void Window::HandleEvents(SDL_Event &e){
}
Recti Window::Box(){
	//Update the box to match the current window w/h
	SDL_GetWindowSize(mWindow.get(), &mBox.w, &mBox.h);
	return mBox;
}<commit_msg>Window is now created in center of screen<commit_after>#include <string>
#include <stdexcept>
#include <memory>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "rect.h"
#include "image.h"
#include "window.h"

//Initialize the unique_ptr's deleters here
std::unique_ptr<SDL_Window, void (*)(SDL_Window*)> Window::mWindow
	= std::unique_ptr<SDL_Window, void (*)(SDL_Window*)>(nullptr, SDL_DestroyWindow);
std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)> Window::mRenderer
	= std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer*)>(nullptr, SDL_DestroyRenderer);
//other static members
Recti Window::mBox;
int Window::SCREEN_WIDTH;
int Window::SCREEN_HEIGHT;

Window::~Window(){}
void Window::Init(std::string title){
	//initialize all SDL subsystems
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
		throw std::runtime_error("SDL Init Failed");
    if (TTF_Init() == -1)
		throw std::runtime_error("TTF Init Failed");

	//Start up window
	SCREEN_WIDTH = 1280;
	SCREEN_HEIGHT = 720;
	//TODO: Solve the resized window issues
	mWindow.reset(SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
		SCREEN_HEIGHT, SDL_WINDOW_SHOWN));// | SDL_WINDOW_RESIZABLE));
	//if window failed to create
	if (mWindow == nullptr)
		throw std::runtime_error("Failed to open window");

	//Start up the renderer
	mRenderer.reset(SDL_CreateRenderer(mWindow.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC));
	//Make sure it went ok
	if (mRenderer == nullptr)
		throw std::runtime_error("Failed to start renderer");
	//initialize the window box
	mBox.Set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
}
void Window::Quit(){
	TTF_Quit();
	SDL_Quit();
}
void Window::Draw(int x, int y, SDL_Texture *tex, SDL_Rect *clip, int w, int h,
				  float angle, Vector2f pivot, SDL_RendererFlip flip)
{
	SDL_Rect dstRect;
	dstRect.x = x;
	dstRect.y = y;
	//Setup desired width and height properties
	if (w == -1 && h == -1)
		SDL_QueryTexture(tex, NULL, NULL, &dstRect.w, &dstRect.h);
	else {
		dstRect.w = w;
		dstRect.h = h;
	}
	//Calculate the pivot point as an offset from image center
	pivot.x = dstRect.w / 2 + pivot.x;
	pivot.y = dstRect.h / 2 + pivot.y;

	//Draw the texture
	SDL_RenderCopyEx(mRenderer.get(), tex, clip, &dstRect, angle, &(SDL_Point)pivot, flip);
}
void Window::Draw(Image *image, const SDL_Rect &dstRect, SDL_Rect *clip, float angle,
				  Vector2f pivot, SDL_RendererFlip flip)
{
	Draw(dstRect.x, dstRect.y, image->Texture(), clip, dstRect.w, dstRect.h);
}
void Window::Draw(Text *text, SDL_Rect dstRect, float angle,
				  Vector2f pivot, SDL_RendererFlip flip)
{
	text->GetSize(dstRect.w, dstRect.h);
	Draw(dstRect.x, dstRect.y, text->Texture(), NULL, dstRect.w, dstRect.h);
}
SDL_Texture* Window::LoadTexture(std::string file){
	SDL_Texture *tex = nullptr;
	tex = IMG_LoadTexture(mRenderer.get(), file.c_str());
	if (tex == nullptr)
		throw std::runtime_error("Failed to load image: " + file);
	return tex;
}
SDL_Texture* Window::SurfaceToTexture(SDL_Surface *surf){
	SDL_Texture *tex = nullptr;
	tex = SDL_CreateTextureFromSurface(mRenderer.get(), surf);
	if (tex == nullptr)
		throw std::runtime_error("Failed to convert surface");
	SDL_FreeSurface(surf);
	return tex;
}
void Window::Clear(){
	SDL_RenderClear(mRenderer.get());
}
void Window::Present(){
	SDL_RenderPresent(mRenderer.get());
}
void Window::HandleEvents(SDL_Event &e){
}
Recti Window::Box(){
	//Update the box to match the current window w/h
	SDL_GetWindowSize(mWindow.get(), &mBox.w, &mBox.h);
	return mBox;
}<|endoftext|>


<commit_before>/*  cbr
 *  UniformServerMap.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "Network.hpp"
#include "UniformServerMap.hpp"

namespace CBR {

UniformServerMap::UniformServerMap(LocationService* loc_service, const BoundingBox3f& region, const Vector3ui32& perside)
 : ServerMap(loc_service),
   mRegion(region),
   mServersPerDim(perside)
{
}

UniformServerMap::~UniformServerMap() {
}

ServerID UniformServerMap::lookup(const Vector3f& pos) {
    assert( mRegion.contains(pos) );

    Vector3f region_extents = mRegion.extents();
    Vector3f to_point = pos - mRegion.min();

    Vector3ui32 server_dim_indices( (uint32)((to_point.x/region_extents.x)*mServersPerDim.x),
                                    (uint32)((to_point.y/region_extents.y)*mServersPerDim.y),
                                    (uint32)((to_point.z/region_extents.z)*mServersPerDim.z) );

    server_dim_indices.x = (server_dim_indices.x >= mServersPerDim.x) ? mServersPerDim.x-1 : server_dim_indices.x;
    server_dim_indices.y = (server_dim_indices.y >= mServersPerDim.y) ? mServersPerDim.y-1 : server_dim_indices.y;
    server_dim_indices.z = (server_dim_indices.z >= mServersPerDim.z) ? mServersPerDim.z-1 : server_dim_indices.z;

    uint32 server_index = server_dim_indices.z*mServersPerDim.x*mServersPerDim.y + server_dim_indices.y*mServersPerDim.x + server_dim_indices.x + 1;
    return ServerID(server_index);
}

ServerID UniformServerMap::lookup(const UUID& obj_id) {
    Vector3f pos = mLocationService->currentPosition(obj_id);
    return lookup(pos);
}

} // namespace CBR
<commit_msg>Clamp server selection instead of asserting that objects fall in the simulation region.<commit_after>/*  cbr
 *  UniformServerMap.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "Network.hpp"
#include "UniformServerMap.hpp"

namespace CBR {

template<typename T>
T clamp(T val, T minval, T maxval) {
    if (val < minval) return minval;
    if (val > maxval) return maxval;
    return val;
}

UniformServerMap::UniformServerMap(LocationService* loc_service, const BoundingBox3f& region, const Vector3ui32& perside)
 : ServerMap(loc_service),
   mRegion(region),
   mServersPerDim(perside)
{
}

UniformServerMap::~UniformServerMap() {
}

ServerID UniformServerMap::lookup(const Vector3f& pos) {
    Vector3f region_extents = mRegion.extents();
    Vector3f to_point = pos - mRegion.min();

    Vector3i32 server_dim_indices( (int32)((to_point.x/region_extents.x)*mServersPerDim.x),
                                   (int32)((to_point.y/region_extents.y)*mServersPerDim.y),
                                   (int32)((to_point.z/region_extents.z)*mServersPerDim.z) );

    server_dim_indices.x = clamp(server_dim_indices.x, 0, (int32)mServersPerDim.x-1);
    server_dim_indices.y = clamp(server_dim_indices.y, 0, (int32)mServersPerDim.y-1);
    server_dim_indices.z = clamp(server_dim_indices.z, 0, (int32)mServersPerDim.z-1);

    uint32 server_index = (uint32) server_dim_indices.z*mServersPerDim.x*mServersPerDim.y + server_dim_indices.y*mServersPerDim.x + server_dim_indices.x + 1;
    return ServerID(server_index);
}

ServerID UniformServerMap::lookup(const UUID& obj_id) {
    Vector3f pos = mLocationService->currentPosition(obj_id);
    return lookup(pos);
}

} // namespace CBR
<|endoftext|>