<commit_before>/**
 * Non-metric Space Library
 *
 * Main developers: Bilegsaikhan Naidan, Leonid Boytsov, Yury Malkov, Ben Frederickson, David Novak
 *
 * For the complete list of contributors and further details see:
 * https://github.com/searchivarius/NonMetricSpaceLib
 *
 * Copyright (c) 2013-2018
 *
 * This code is released under the
 * Apache License Version 2.0 http://www.apache.org/licenses/.
 *
 */
#include <iostream>
#include <string>

#include "space.h"
#include "params.h"
#include "init.h"
#include "report_intr_dim.h"
#include "spacefactory.h"
#include "cmd_options.h"
#include "my_isnan_isinf.h"

using namespace similarity;
using namespace std;

const unsigned defaultSampleQty = 1000000;

template <typename dist_t>
void ComputeMuDeffect(const Space<dist_t>& space,
                    const ObjectVector& dataset,
                    double & dleft, double & dright,
                    size_t SampleQty = 1000000) {
  dleft = dright = -1;
  for (size_t n = 0; n < SampleQty; ++n) {
    size_t r1 = RandomInt() % dataset.size();
    size_t r2 = RandomInt() % dataset.size();
    size_t r3 = RandomInt() % dataset.size();
    CHECK(r1 < dataset.size());
    CHECK(r2 < dataset.size());
    CHECK(r3 < dataset.size());
    const Object* q = dataset[r1];
    const Object* a = dataset[r2];
    const Object* b = dataset[r3];
    {
      dist_t d1 = space.IndexTimeDistance(q, a);
      dist_t d2 = space.IndexTimeDistance(q, b);
      dist_t d3 = space.IndexTimeDistance(a, b);
      if (my_isnan(d1) || my_isnan(d2) || my_isnan(d3)) {
        throw runtime_error("!!! Bug: a distance returned NAN!");
      }
      if (d3 != 0) {
        dright = max(dright, (double)fabs(double(d1)-double(d2))/double(d3));
      }
    }
    {
      dist_t d1 = space.IndexTimeDistance(a, q);
      dist_t d2 = space.IndexTimeDistance(b, q);
      dist_t d3 = space.IndexTimeDistance(b, a);
      if (my_isnan(d1) || my_isnan(d2) || my_isnan(d3)) {
        throw runtime_error("!!! Bug: a distance returned NAN!");
      }
      if (d3 != 0) {
        dleft = max(dleft, (double)fabs(double(d1)-double(d2))/double(d3));
      }
    }
  }
}

template <typename dist_t>
void TestSpace(
                string spaceDesc,
                string dataFile,
                bool compMuDeffect,
                unsigned maxNumData,
                unsigned sampleQty,
                string sampleFile
               ) {
  string          spaceType;
  vector<string>  vSpaceArgs;

  ParseSpaceArg(spaceDesc, spaceType, vSpaceArgs);
  AnyParams   spaceParams({AnyParams(vSpaceArgs)});

  unique_ptr<Space<dist_t>> space(SpaceFactoryRegistry<dist_t>::
                                Instance().CreateSpace(spaceType, spaceParams));

  ObjectVector    data;
  vector<string>  tmp;
  unique_ptr<DataFileInputState> inpState(space->ReadDataset(data, tmp, dataFile, maxNumData));
  space->UpdateParamsFromFile(*inpState);
  vector<double>  dist;

  // Prints the report
  ReportIntrinsicDimensionality("********", *space, data, dist, sampleQty);
  if (!sampleFile.empty()) {
    ofstream of(sampleFile);
    CHECK_MSG(of, "Cannot open for writing file: " + sampleFile);
    of.exceptions ( std::ifstream::failbit | std::ifstream::badbit );

    for (size_t i = 0; i < dist.size(); ++i) {
      if (i) of << "\t";
      of << dist[i];
    }
    of << std::endl;
  }
  if (compMuDeffect) {
    double    dleft, dright;
    ComputeMuDeffect<dist_t>(
                  *space,
                  data,
                  dleft, dright,
                  sampleQty
                 );
    LOG(LIB_INFO) << "### left mu-defect. : " << dleft << " right mu-defect. :" << dright;
  }
}

int main(int argc, char* argv[]) {
  string    spaceDesc, distType;
  string    dataFile;
  string    sampleFile;
  unsigned  maxNumData;
  unsigned  sampleQty;
  bool      compMuDeffect;

  CmdOptions cmd_options;

  cmd_options.Add(new CmdParam("spaceType,s", "space type, e.g., l1, l2, lp:p=0.5",
                               &spaceDesc, true));
  cmd_options.Add(new CmdParam("distType", "distance value type: int, float, double",
                               &distType, false, DIST_TYPE_FLOAT));
  cmd_options.Add(new CmdParam("dataFile,i", "input data file",
                               &dataFile, true));
  cmd_options.Add(new CmdParam("maxNumData", "if non-zero, only the first maxNumData elements are used",
                               &maxNumData, false, 0));
  cmd_options.Add(new CmdParam("sampleQty", "a number of samples (a sample is a pair of data points)",
                               &sampleQty, false, defaultSampleQty));
  cmd_options.Add(new CmdParam("muDeffect,m", "estimate the left and the right mu deffectiveness",
                               &compMuDeffect, false, false));
  cmd_options.Add(new CmdParam("sampleFile", "optional output sample file",
                               &sampleFile, false, ""));

  try {
    cmd_options.Parse(argc, argv);

    if (!DoesFileExist(dataFile)) {
      PREPARE_RUNTIME_ERR(err) << "data file " << dataFile << " doesn't exist";
      THROW_RUNTIME_ERR(err);
    }

    initLibrary(0, LIB_LOGSTDERR);

    if (DIST_TYPE_INT == distType) {
      TestSpace<int>(
                  spaceDesc,
                  dataFile,
                  compMuDeffect,
                  maxNumData,
                  sampleQty,
                  sampleFile
                );
    } else if (DIST_TYPE_FLOAT == distType) {
      TestSpace<float>(
                  spaceDesc,
                  dataFile,
                  compMuDeffect,
                  maxNumData,
                  sampleQty,
                  sampleFile
                 );
    } else if (DIST_TYPE_DOUBLE == distType) {
      TestSpace<double>(
                  spaceDesc,
                  dataFile,
                  compMuDeffect,
                  maxNumData,
                  sampleQty,
                  sampleFile
                 );
    }

  } catch (const CmdParserException& e) {
    cmd_options.ToString();
    std::cout.flush();
    LOG(LIB_FATAL) << e.what();
  } catch (const exception& e) {
    cmd_options.ToString();
    std::cout.flush();
    LOG(LIB_FATAL) << e.what();
  }

  return 0;
}
<commit_msg>tiny fix in report_intr_dim output format.<commit_after>/**
 * Non-metric Space Library
 *
 * Main developers: Bilegsaikhan Naidan, Leonid Boytsov, Yury Malkov, Ben Frederickson, David Novak
 *
 * For the complete list of contributors and further details see:
 * https://github.com/searchivarius/NonMetricSpaceLib
 *
 * Copyright (c) 2013-2018
 *
 * This code is released under the
 * Apache License Version 2.0 http://www.apache.org/licenses/.
 *
 */
#include <iostream>
#include <string>

#include "space.h"
#include "params.h"
#include "init.h"
#include "report_intr_dim.h"
#include "spacefactory.h"
#include "cmd_options.h"
#include "my_isnan_isinf.h"

using namespace similarity;
using namespace std;

const unsigned defaultSampleQty = 1000000;

template <typename dist_t>
void ComputeMuDeffect(const Space<dist_t>& space,
                    const ObjectVector& dataset,
                    double & dleft, double & dright,
                    size_t SampleQty = 1000000) {
  dleft = dright = -1;
  for (size_t n = 0; n < SampleQty; ++n) {
    size_t r1 = RandomInt() % dataset.size();
    size_t r2 = RandomInt() % dataset.size();
    size_t r3 = RandomInt() % dataset.size();
    CHECK(r1 < dataset.size());
    CHECK(r2 < dataset.size());
    CHECK(r3 < dataset.size());
    const Object* q = dataset[r1];
    const Object* a = dataset[r2];
    const Object* b = dataset[r3];
    {
      dist_t d1 = space.IndexTimeDistance(q, a);
      dist_t d2 = space.IndexTimeDistance(q, b);
      dist_t d3 = space.IndexTimeDistance(a, b);
      if (my_isnan(d1) || my_isnan(d2) || my_isnan(d3)) {
        throw runtime_error("!!! Bug: a distance returned NAN!");
      }
      if (d3 != 0) {
        dright = max(dright, (double)fabs(double(d1)-double(d2))/double(d3));
      }
    }
    {
      dist_t d1 = space.IndexTimeDistance(a, q);
      dist_t d2 = space.IndexTimeDistance(b, q);
      dist_t d3 = space.IndexTimeDistance(b, a);
      if (my_isnan(d1) || my_isnan(d2) || my_isnan(d3)) {
        throw runtime_error("!!! Bug: a distance returned NAN!");
      }
      if (d3 != 0) {
        dleft = max(dleft, (double)fabs(double(d1)-double(d2))/double(d3));
      }
    }
  }
}

template <typename dist_t>
void TestSpace(
                string spaceDesc,
                string dataFile,
                bool compMuDeffect,
                unsigned maxNumData,
                unsigned sampleQty,
                string sampleFile
               ) {
  string          spaceType;
  vector<string>  vSpaceArgs;

  ParseSpaceArg(spaceDesc, spaceType, vSpaceArgs);
  AnyParams   spaceParams({AnyParams(vSpaceArgs)});

  unique_ptr<Space<dist_t>> space(SpaceFactoryRegistry<dist_t>::
                                Instance().CreateSpace(spaceType, spaceParams));

  ObjectVector    data;
  vector<string>  tmp;
  unique_ptr<DataFileInputState> inpState(space->ReadDataset(data, tmp, dataFile, maxNumData));
  space->UpdateParamsFromFile(*inpState);
  vector<double>  dist;

  // Prints the report
  ReportIntrinsicDimensionality("********", *space, data, dist, sampleQty);
  if (!sampleFile.empty()) {
    ofstream of(sampleFile);
    CHECK_MSG(of, "Cannot open for writing file: " + sampleFile);
    of.exceptions ( std::ifstream::failbit | std::ifstream::badbit );

    for (size_t i = 0; i < dist.size(); ++i) {
      if (i) of << ",";
      of << dist[i];
    }
    of << std::endl;
  }
  if (compMuDeffect) {
    double    dleft, dright;
    ComputeMuDeffect<dist_t>(
                  *space,
                  data,
                  dleft, dright,
                  sampleQty
                 );
    LOG(LIB_INFO) << "### left mu-defect. : " << dleft << " right mu-defect. :" << dright;
  }
}

int main(int argc, char* argv[]) {
  string    spaceDesc, distType;
  string    dataFile;
  string    sampleFile;
  unsigned  maxNumData;
  unsigned  sampleQty;
  bool      compMuDeffect;

  CmdOptions cmd_options;

  cmd_options.Add(new CmdParam("spaceType,s", "space type, e.g., l1, l2, lp:p=0.5",
                               &spaceDesc, true));
  cmd_options.Add(new CmdParam("distType", "distance value type: int, float, double",
                               &distType, false, DIST_TYPE_FLOAT));
  cmd_options.Add(new CmdParam("dataFile,i", "input data file",
                               &dataFile, true));
  cmd_options.Add(new CmdParam("maxNumData", "if non-zero, only the first maxNumData elements are used",
                               &maxNumData, false, 0));
  cmd_options.Add(new CmdParam("sampleQty", "a number of samples (a sample is a pair of data points)",
                               &sampleQty, false, defaultSampleQty));
  cmd_options.Add(new CmdParam("muDeffect,m", "estimate the left and the right mu deffectiveness",
                               &compMuDeffect, false, false));
  cmd_options.Add(new CmdParam("sampleFile", "optional output sample file",
                               &sampleFile, false, ""));

  try {
    cmd_options.Parse(argc, argv);

    if (!DoesFileExist(dataFile)) {
      PREPARE_RUNTIME_ERR(err) << "data file " << dataFile << " doesn't exist";
      THROW_RUNTIME_ERR(err);
    }

    initLibrary(0, LIB_LOGSTDERR);

    if (DIST_TYPE_INT == distType) {
      TestSpace<int>(
                  spaceDesc,
                  dataFile,
                  compMuDeffect,
                  maxNumData,
                  sampleQty,
                  sampleFile
                );
    } else if (DIST_TYPE_FLOAT == distType) {
      TestSpace<float>(
                  spaceDesc,
                  dataFile,
                  compMuDeffect,
                  maxNumData,
                  sampleQty,
                  sampleFile
                 );
    } else if (DIST_TYPE_DOUBLE == distType) {
      TestSpace<double>(
                  spaceDesc,
                  dataFile,
                  compMuDeffect,
                  maxNumData,
                  sampleQty,
                  sampleFile
                 );
    }

  } catch (const CmdParserException& e) {
    cmd_options.ToString();
    std::cout.flush();
    LOG(LIB_FATAL) << e.what();
  } catch (const exception& e) {
    cmd_options.ToString();
    std::cout.flush();
    LOG(LIB_FATAL) << e.what();
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <qstringlist.h>
#include <QEvent>

#include "dbus_service.h"
#include "defines.h"
#include "QsLog.h"

DBusService::DBusService(const QString &serviceName, QObject *parent) :
	QObject(parent),
	mDbusServiceName(serviceName),
	mServiceType(getDeviceType(serviceName)),
	mConnected(true),
	mDeviceInstance(serviceName, "/DeviceInstance", DBUS_CONNECTION)
{
	mDeviceInstance.getValue();
	QLOG_INFO() << "[DBusService] DeviceInstance of " << serviceName << "=" << mDeviceInstance.getValue().toInt() << "with type" << mServiceType;
}

QString DBusService::getDeviceType(const QString &name)
{
	QStringList elements = name.split(".");
	if (elements.count() < 3)
		return "Unkown";

	return elements[2];
}

void DBusService::setDeviceType(const QString &name)
{
	mServiceType = getDeviceType(name);
}

void DBusService::registerObjects(const QStringList &pathList)
{
	foreach(const QString &path, pathList)
		registerObject(path);
}

void DBusService::registerObject(const QString &path)
{
	QLOG_INFO() << "[DBusService] registerObject " << mDbusServiceName << path;
	BusItemCons * busitem = new BusItemCons(mDbusServiceName, path, DBUS_CONNECTION);
	mBusItems.insert(path, busitem);
}

QVariant DBusService::getValue(const QString path)
{
	if (mBusItems.contains(path)) {
		return mBusItems.value(path)->getValue();
	} else
		return QVariant();
}

bool DBusService::setValue(const QString path, const QVariant value)
{
	if (mBusItems.contains(path)) {
		QLOG_TRACE() << "[DBusService] Set value" << path << value.toString();
		return mBusItems.value(path)->setValue(value) == 0 ? true : false;
	} else
		return false;
}
<commit_msg>dbus_service: removed trace log<commit_after>#include <qstringlist.h>
#include <QEvent>

#include "dbus_service.h"
#include "defines.h"
#include "QsLog.h"

DBusService::DBusService(const QString &serviceName, QObject *parent) :
	QObject(parent),
	mDbusServiceName(serviceName),
	mServiceType(getDeviceType(serviceName)),
	mConnected(true),
	mDeviceInstance(serviceName, "/DeviceInstance", DBUS_CONNECTION)
{
	mDeviceInstance.getValue();
	QLOG_INFO() << "[DBusService] DeviceInstance of " << serviceName << "=" << mDeviceInstance.getValue().toInt() << "with type" << mServiceType;
}

QString DBusService::getDeviceType(const QString &name)
{
	QStringList elements = name.split(".");
	if (elements.count() < 3)
		return "Unkown";

	return elements[2];
}

void DBusService::setDeviceType(const QString &name)
{
	mServiceType = getDeviceType(name);
}

void DBusService::registerObjects(const QStringList &pathList)
{
	foreach(const QString &path, pathList)
		registerObject(path);
}

void DBusService::registerObject(const QString &path)
{
	QLOG_INFO() << "[DBusService] registerObject " << mDbusServiceName << path;
	BusItemCons * busitem = new BusItemCons(mDbusServiceName, path, DBUS_CONNECTION);
	mBusItems.insert(path, busitem);
}

QVariant DBusService::getValue(const QString path)
{
	if (mBusItems.contains(path)) {
		return mBusItems.value(path)->getValue();
	} else
		return QVariant();
}

bool DBusService::setValue(const QString path, const QVariant value)
{
	if (mBusItems.contains(path))
		return mBusItems.value(path)->setValue(value) == 0 ? true : false;
	else
		return false;
}
<|endoftext|>


<commit_before>// @(#)root/eve:$Id$
// Author: Timur Pocheptsov

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
#include "TGLPlotCamera.h"
#include "TGLIncludes.h"
#include "TVirtualGL.h"

//______________________________________________________________________________
//
// Camera for TGLPlotPainter and sub-classes.

ClassImp(TGLPlotCamera);

//______________________________________________________________________________
TGLPlotCamera::TGLPlotCamera() :
   fZoom(1.), fShift(1.5), fCenter(),
   fVpChanged(kFALSE)
{
   //Construct camera for plot painters.
   fOrthoBox[0] = 1.;
   fOrthoBox[1] = 1.;
   fOrthoBox[2] = -100.;
   fOrthoBox[3] = 100.;
}

//______________________________________________________________________________
void TGLPlotCamera::SetViewport(const TGLRect &vp)
{
   //Setup viewport, if it was changed, plus reset arcball.

   if (vp.Width() != fViewport.Width() || vp.Height() != fViewport.Height() ||
       vp.X() != fViewport.X() || vp.Y() != fViewport.Y())
   {
      fVpChanged = kTRUE;
      fArcBall.SetBounds(vp.Width(), vp.Height());
      fViewport = vp;

   } else
      fVpChanged = kFALSE;
}

//______________________________________________________________________________
void TGLPlotCamera::SetViewVolume(const TGLVertex3 */*box*/)
{
   //'box' is the TGLPlotPainter's back box's coordinates.
/*   fCenter[0] = (box[0].X() + box[1].X()) / 2;
   fCenter[1] = (box[0].Y() + box[2].Y()) / 2;
   fCenter[2] = (box[0].Z() + box[4].Z()) / 2;
   const Double_t maxDim = box[1].X() - box[0].X();
   fOrthoBox[0] = maxDim;
   fOrthoBox[1] = maxDim;
   fOrthoBox[2] = -100 * maxDim;//100?
   fOrthoBox[3] = 100 * maxDim;
   fShift = maxDim * 1.5;*/
}

//______________________________________________________________________________
void TGLPlotCamera::StartRotation(Int_t px, Int_t py)
{
   //User clicks somewhere (px, py).
   fArcBall.Click(TPoint(px, py));
}

//______________________________________________________________________________
void TGLPlotCamera::RotateCamera(Int_t px, Int_t py)
{
   //Mouse movement.
   fArcBall.Drag(TPoint(px, py));
}

//______________________________________________________________________________
void TGLPlotCamera::StartPan(Int_t px, Int_t py)
{
   //User clicks somewhere (px, py).
   fMousePos.fX = px;
   fMousePos.fY = fViewport.Height() - py;
}

//______________________________________________________________________________
void TGLPlotCamera::Pan(Int_t px, Int_t py)
{
   //Pan camera.
   py = fViewport.Height() - py;
   //Extract gl matrices.
   Double_t mv[16] = {0.};
   glGetDoublev(GL_MODELVIEW_MATRIX, mv);
   Double_t pr[16] = {0.};
   glGetDoublev(GL_PROJECTION_MATRIX, pr);
   Int_t vp[] = {0, 0, fViewport.Width(), fViewport.Height()};
   //Adjust pan vector.
   TGLVertex3 start, end;
   gluUnProject(fMousePos.fX, fMousePos.fY, 1., mv, pr, vp, &start.X(), &start.Y(), &start.Z());
   gluUnProject(px, py, 1., mv, pr, vp, &end.X(), &end.Y(), &end.Z());
   fTruck += (start - end) /= 2.;
   fMousePos.fX = px;
   fMousePos.fY = py;
}

//______________________________________________________________________________
void TGLPlotCamera::SetCamera()const
{
   //Viewport and projection.
   glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height());

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(
           -fOrthoBox[0] * fZoom,
            fOrthoBox[0] * fZoom,
           -fOrthoBox[1] * fZoom,
            fOrthoBox[1] * fZoom,
            fOrthoBox[2],
            fOrthoBox[3]
          );

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

//______________________________________________________________________________
void TGLPlotCamera::Apply(Double_t phi, Double_t theta)const
{
   //Applies rotations and translations before drawing
   glTranslated(0., 0., -fShift);
   glMultMatrixd(fArcBall.GetRotMatrix());
   glRotated(theta - 90., 1., 0., 0.);
   glRotated(phi, 0., 0., 1.);
   glTranslated(-fTruck[0], -fTruck[1], -fTruck[2]);
//   glTranslated(-fCenter[0], -fCenter[1], -fCenter[2]);
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetX()const
{
   //viewport[0]
   return fViewport.X();
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetY()const
{
   //viewport[1]
   return fViewport.Y();
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetWidth()const
{
   //viewport[2]
   return Int_t(fViewport.Width());
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetHeight()const
{
   //viewport[3]
   return Int_t(fViewport.Height());
}

//______________________________________________________________________________
void TGLPlotCamera::ZoomIn()
{
   //Zoom in.
   fZoom /= 1.2;
}

//______________________________________________________________________________
void TGLPlotCamera::ZoomOut()
{
   //Zoom out.
   fZoom *= 1.2;
}
<commit_msg>Fix a compilation warning on Windows<commit_after>// @(#)root/eve:$Id$
// Author: Timur Pocheptsov

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
#include "TGLPlotCamera.h"
#include "TGLIncludes.h"
#include "TVirtualGL.h"

//______________________________________________________________________________
//
// Camera for TGLPlotPainter and sub-classes.

ClassImp(TGLPlotCamera);

//______________________________________________________________________________
TGLPlotCamera::TGLPlotCamera() :
   fZoom(1.), fShift(1.5), fCenter(),
   fVpChanged(kFALSE)
{
   //Construct camera for plot painters.
   fOrthoBox[0] = 1.;
   fOrthoBox[1] = 1.;
   fOrthoBox[2] = -100.;
   fOrthoBox[3] = 100.;
}

//______________________________________________________________________________
void TGLPlotCamera::SetViewport(const TGLRect &vp)
{
   //Setup viewport, if it was changed, plus reset arcball.

   if (vp.Width() != fViewport.Width() || vp.Height() != fViewport.Height() ||
       vp.X() != fViewport.X() || vp.Y() != fViewport.Y())
   {
      fVpChanged = kTRUE;
      fArcBall.SetBounds(vp.Width(), vp.Height());
      fViewport = vp;

   } else
      fVpChanged = kFALSE;
}

//______________________________________________________________________________
void TGLPlotCamera::SetViewVolume(const TGLVertex3* /* box */)
{
   //'box' is the TGLPlotPainter's back box's coordinates.
/*   fCenter[0] = (box[0].X() + box[1].X()) / 2;
   fCenter[1] = (box[0].Y() + box[2].Y()) / 2;
   fCenter[2] = (box[0].Z() + box[4].Z()) / 2;
   const Double_t maxDim = box[1].X() - box[0].X();
   fOrthoBox[0] = maxDim;
   fOrthoBox[1] = maxDim;
   fOrthoBox[2] = -100 * maxDim;//100?
   fOrthoBox[3] = 100 * maxDim;
   fShift = maxDim * 1.5;*/
}

//______________________________________________________________________________
void TGLPlotCamera::StartRotation(Int_t px, Int_t py)
{
   //User clicks somewhere (px, py).
   fArcBall.Click(TPoint(px, py));
}

//______________________________________________________________________________
void TGLPlotCamera::RotateCamera(Int_t px, Int_t py)
{
   //Mouse movement.
   fArcBall.Drag(TPoint(px, py));
}

//______________________________________________________________________________
void TGLPlotCamera::StartPan(Int_t px, Int_t py)
{
   //User clicks somewhere (px, py).
   fMousePos.fX = px;
   fMousePos.fY = fViewport.Height() - py;
}

//______________________________________________________________________________
void TGLPlotCamera::Pan(Int_t px, Int_t py)
{
   //Pan camera.
   py = fViewport.Height() - py;
   //Extract gl matrices.
   Double_t mv[16] = {0.};
   glGetDoublev(GL_MODELVIEW_MATRIX, mv);
   Double_t pr[16] = {0.};
   glGetDoublev(GL_PROJECTION_MATRIX, pr);
   Int_t vp[] = {0, 0, fViewport.Width(), fViewport.Height()};
   //Adjust pan vector.
   TGLVertex3 start, end;
   gluUnProject(fMousePos.fX, fMousePos.fY, 1., mv, pr, vp, &start.X(), &start.Y(), &start.Z());
   gluUnProject(px, py, 1., mv, pr, vp, &end.X(), &end.Y(), &end.Z());
   fTruck += (start - end) /= 2.;
   fMousePos.fX = px;
   fMousePos.fY = py;
}

//______________________________________________________________________________
void TGLPlotCamera::SetCamera()const
{
   //Viewport and projection.
   glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height());

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(
           -fOrthoBox[0] * fZoom,
            fOrthoBox[0] * fZoom,
           -fOrthoBox[1] * fZoom,
            fOrthoBox[1] * fZoom,
            fOrthoBox[2],
            fOrthoBox[3]
          );

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

//______________________________________________________________________________
void TGLPlotCamera::Apply(Double_t phi, Double_t theta)const
{
   //Applies rotations and translations before drawing
   glTranslated(0., 0., -fShift);
   glMultMatrixd(fArcBall.GetRotMatrix());
   glRotated(theta - 90., 1., 0., 0.);
   glRotated(phi, 0., 0., 1.);
   glTranslated(-fTruck[0], -fTruck[1], -fTruck[2]);
//   glTranslated(-fCenter[0], -fCenter[1], -fCenter[2]);
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetX()const
{
   //viewport[0]
   return fViewport.X();
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetY()const
{
   //viewport[1]
   return fViewport.Y();
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetWidth()const
{
   //viewport[2]
   return Int_t(fViewport.Width());
}

//______________________________________________________________________________
Int_t TGLPlotCamera::GetHeight()const
{
   //viewport[3]
   return Int_t(fViewport.Height());
}

//______________________________________________________________________________
void TGLPlotCamera::ZoomIn()
{
   //Zoom in.
   fZoom /= 1.2;
}

//______________________________________________________________________________
void TGLPlotCamera::ZoomOut()
{
   //Zoom out.
   fZoom *= 1.2;
}
<|endoftext|>


<commit_before>/*
 * libcpu: x86_disasm.cpp
 *
 * disassembler
 */

#include <stdlib.h>
#include <stdio.h>

#include "libcpu.h"
#include "x86_isa.h"
#include "x86_decode.h"

static const char* mnemo[] = {
#define DECLARE_INSTR(name,str) str,
#include "x86_instr.h"
#undef DECLARE_INSTR
};

static const char *to_mnemonic(struct x86_instr *instr)
{
	return mnemo[instr->type];
}

static const char *byte_reg_names[] = {
	"%al",
	"%cl",
	"%dl",
	"%bl",
	"%ah",
	"%ch",
	"%dh",
	"%bh",
};

static const char *word_reg_names[] = {
	"%ax",
	"%cx",
	"%dx",
	"%bx",
	"%sp",
	"%bp",
	"%si",
	"%di",
};

static const char *seg_reg_names[] = {
	"%es",
	"%cs",
	"%ss",
	"%ds",
};

static const char *mem_byte_reg_names[] = {
	"%bx,%si",
	"%bx,%di",
	"%bp,%si",
	"%bp,%di",
	"%si",
	"%di",
	NULL,
	"%bx",
};

static const char *seg_override_names[] = {
	"",
	"%es:",
	"%cs:",
	"%ss:",
	"%ds:",
};

static const char *lock_names[] = {
	"",
	"lock ",
};

static const char *prefix_names[] = {
	"",
	"repnz ",
	"rep ",
};

static const char *sign_to_str(int n)
{
	if (n >= 0)
		return "";

	return "-";
}

static const char *to_reg_name(struct x86_instr *instr, int reg_num)
{
	if (instr->flags & WIDTH_BYTE)
		return byte_reg_names[reg_num];

	return word_reg_names[reg_num];
}

static const char *to_seg_reg_name(struct x86_instr *instr, int reg_num)
{
	return seg_reg_names[reg_num];
}

static int
print_operand(addr_t pc, char *operands, size_t size, struct x86_instr *instr, struct x86_operand *operand)
{
	int ret = 0;

	switch (operand->type) {
	case OP_IMM:
		ret = snprintf(operands, size, "$0x%x", operand->imm);
		break;
	case OP_REL:
		ret = snprintf(operands, size, "%x", (unsigned int)((long)pc + instr->nr_bytes + operand->rel));
		break;
	case OP_REG:
		ret = snprintf(operands, size, "%s", to_reg_name(instr, operand->reg));
		break;
	case OP_SEG_REG:
		ret = snprintf(operands, size, "%s", to_seg_reg_name(instr, operand->reg));
		break;
	case OP_MEM:
		ret = snprintf(operands, size, "%s%x", sign_to_str(operand->disp), abs(operand->disp));
		break;
	case OP_MEM_DISP:
		ret = snprintf(operands, size, "%s%s0x%x(%s)", seg_override_names[instr->seg_override], sign_to_str(operand->disp), abs(operand->disp), mem_byte_reg_names[operand->reg]);
		break;
	}
	return ret;
}

int
arch_8086_disasm_instr(cpu_t *cpu, addr_t pc, char *line, unsigned int max_line)
{
	struct x86_instr instr;
	char operands[32];
	int len = 0;

	if (arch_8086_decode_instr(&instr, cpu->RAM, pc) != 0) {
		fprintf(stderr, "error: unable to decode opcode %x\n", instr.opcode);
		exit(1);
	}

	operands[0] = '\0';

	/* AT&T syntax operands */
	if (!(instr.flags & SRC_NONE))
		len += print_operand(pc, operands+len, sizeof(operands)-len, &instr, &instr.src);

	if (!(instr.flags & SRC_NONE) && !(instr.flags & DST_NONE))
		len += snprintf(operands+len, sizeof(operands)-len, ",");

	if (!(instr.flags & DST_NONE))
		len += print_operand(pc, operands+len, sizeof(operands)-len, &instr, &instr.dst);

        snprintf(line, max_line, "%s%s%s\t%s", lock_names[instr.lock_prefix], prefix_names[instr.rep_prefix], to_mnemonic(&instr), operands);

        return arch_8086_instr_length(&instr);
}
<commit_msg>x86: Fix disasm hexadecimal prints<commit_after>/*
 * libcpu: x86_disasm.cpp
 *
 * disassembler
 */

#include <stdlib.h>
#include <stdio.h>

#include "libcpu.h"
#include "x86_isa.h"
#include "x86_decode.h"

static const char* mnemo[] = {
#define DECLARE_INSTR(name,str) str,
#include "x86_instr.h"
#undef DECLARE_INSTR
};

static const char *to_mnemonic(struct x86_instr *instr)
{
	return mnemo[instr->type];
}

static const char *byte_reg_names[] = {
	"%al",
	"%cl",
	"%dl",
	"%bl",
	"%ah",
	"%ch",
	"%dh",
	"%bh",
};

static const char *word_reg_names[] = {
	"%ax",
	"%cx",
	"%dx",
	"%bx",
	"%sp",
	"%bp",
	"%si",
	"%di",
};

static const char *seg_reg_names[] = {
	"%es",
	"%cs",
	"%ss",
	"%ds",
};

static const char *mem_byte_reg_names[] = {
	"%bx,%si",
	"%bx,%di",
	"%bp,%si",
	"%bp,%di",
	"%si",
	"%di",
	NULL,
	"%bx",
};

static const char *seg_override_names[] = {
	"",
	"%es:",
	"%cs:",
	"%ss:",
	"%ds:",
};

static const char *lock_names[] = {
	"",
	"lock ",
};

static const char *prefix_names[] = {
	"",
	"repnz ",
	"rep ",
};

static const char *sign_to_str(int n)
{
	if (n >= 0)
		return "";

	return "-";
}

static const char *to_reg_name(struct x86_instr *instr, int reg_num)
{
	if (instr->flags & WIDTH_BYTE)
		return byte_reg_names[reg_num];

	return word_reg_names[reg_num];
}

static const char *to_seg_reg_name(struct x86_instr *instr, int reg_num)
{
	return seg_reg_names[reg_num];
}

static int
print_operand(addr_t pc, char *operands, size_t size, struct x86_instr *instr, struct x86_operand *operand)
{
	int ret = 0;

	switch (operand->type) {
	case OP_IMM:
		ret = snprintf(operands, size, "$0x%x", operand->imm);
		break;
	case OP_REL:
		ret = snprintf(operands, size, "0x%x", (unsigned int)((long)pc + instr->nr_bytes + operand->rel));
		break;
	case OP_REG:
		ret = snprintf(operands, size, "%s", to_reg_name(instr, operand->reg));
		break;
	case OP_SEG_REG:
		ret = snprintf(operands, size, "%s", to_seg_reg_name(instr, operand->reg));
		break;
	case OP_MEM:
		ret = snprintf(operands, size, "%s0x%x", sign_to_str(operand->disp), abs(operand->disp));
		break;
	case OP_MEM_DISP:
		ret = snprintf(operands, size, "%s%s0x%x(%s)", seg_override_names[instr->seg_override], sign_to_str(operand->disp), abs(operand->disp), mem_byte_reg_names[operand->reg]);
		break;
	}
	return ret;
}

int
arch_8086_disasm_instr(cpu_t *cpu, addr_t pc, char *line, unsigned int max_line)
{
	struct x86_instr instr;
	char operands[32];
	int len = 0;

	if (arch_8086_decode_instr(&instr, cpu->RAM, pc) != 0) {
		fprintf(stderr, "error: unable to decode opcode %x\n", instr.opcode);
		exit(1);
	}

	operands[0] = '\0';

	/* AT&T syntax operands */
	if (!(instr.flags & SRC_NONE))
		len += print_operand(pc, operands+len, sizeof(operands)-len, &instr, &instr.src);

	if (!(instr.flags & SRC_NONE) && !(instr.flags & DST_NONE))
		len += snprintf(operands+len, sizeof(operands)-len, ",");

	if (!(instr.flags & DST_NONE))
		len += print_operand(pc, operands+len, sizeof(operands)-len, &instr, &instr.dst);

        snprintf(line, max_line, "%s%s%s\t%s", lock_names[instr.lock_prefix], prefix_names[instr.rep_prefix], to_mnemonic(&instr), operands);

        return arch_8086_instr_length(&instr);
}
<|endoftext|>


<commit_before>/*
 * Silly subclass of CTreeCtrl just to implement Drag&Drop.
 *
 * Based on MFC sample code from CMNCTRL1
 */

#include "stdafx.h"
#include "MyTreeCtrl.h"
#include "DboxMain.h"
#include "corelib/ItemData.h"
#include "corelib/MyString.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static const TCHAR GROUP_SEP = TCHAR('.');

CMyTreeCtrl::CMyTreeCtrl() : m_bDragging(false), m_pimagelist(NULL)
{
}

CMyTreeCtrl::~CMyTreeCtrl()
{
  delete m_pimagelist;
}

BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)
	//{{AFX_MSG_MAP(CMyTreeCtrl)
	ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndLabelEdit)
	ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBeginDrag)
	ON_NOTIFY_REFLECT(TVN_BEGINRDRAG, OnBeginDrag)
	ON_WM_MOUSEMOVE()
	ON_WM_DESTROY()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMyTreeCtrl::OnDestroy()
{
  CImageList  *pimagelist;

  pimagelist = GetImageList(TVSIL_NORMAL);
  if (pimagelist != NULL) {
    pimagelist->DeleteImageList();
    delete pimagelist;
  }
}

void CMyTreeCtrl::SetNewStyle(long lStyleMask, BOOL bSetBits)
{
  long        lStyleOld;

  lStyleOld = GetWindowLong(m_hWnd, GWL_STYLE);
  lStyleOld &= ~lStyleMask;
  if (bSetBits)
    lStyleOld |= lStyleMask;

  SetWindowLong(m_hWnd, GWL_STYLE, lStyleOld);
  SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
}

void CMyTreeCtrl::UpdateLeafsGroup(HTREEITEM hItem, CString prefix)
{
  if (IsLeafNode(hItem)) {
    DWORD itemData = GetItemData(hItem);
    ASSERT(itemData != NULL);
    CItemData *ci = (CItemData *)itemData;
    ci->SetGroup(CMyString(prefix));
  } else { // update prefix with current group name and recurse
    if (!prefix.IsEmpty())
      prefix += GROUP_SEP;
    prefix += GetItemText(hItem);
    HTREEITEM child;
    for(child = GetChildItem(hItem); child != NULL; child = GetNextSiblingItem(child)) {
      UpdateLeafsGroup(child, prefix);
    }
  }
}

void CMyTreeCtrl::OnEndLabelEdit(LPNMHDR pnmhdr, LRESULT *pLResult)
{
  TV_DISPINFO     *ptvinfo;

  ptvinfo = (TV_DISPINFO *)pnmhdr;
  if (ptvinfo->item.pszText != NULL) {
    ptvinfo->item.mask = TVIF_TEXT;
    SetItem(&ptvinfo->item);
    HTREEITEM ti = ptvinfo->item.hItem;
    if (IsLeafNode(ptvinfo->item.hItem)) {
      // Update leaf's title
      DWORD itemData = GetItemData(ti);
      ASSERT(itemData != NULL);
      CItemData *ci = (CItemData *)itemData;
      ci->SetTitle(ptvinfo->item.pszText);
      DboxMain *parent = (DboxMain *)GetParent();
      // update corresponding List text
      DisplayInfo *di = (DisplayInfo *)ci->GetDisplayInfo();
      ASSERT(di != NULL);
      int lindex = di->list_index;
      parent->UpdateListItemTitle(lindex, ptvinfo->item.pszText);
      // Mark database as modified
      parent->SetChanged(true);
    } else {
      // Update all leaf chldren with new path element
      // prefix is path up to and NOT including renamed node
      CString prefix;
      HTREEITEM parent, current = ti;
      do {
	parent = GetParentItem(current);
	if (parent == NULL) {
	  break;
	}
	current = parent;
	if (!prefix.IsEmpty())
	  prefix = GROUP_SEP + prefix;
	prefix = GetItemText(current) + prefix;
      } while (1);
      UpdateLeafsGroup(ti, prefix);
    }
  }
  *pLResult = TRUE;
}

void CMyTreeCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
  HTREEITEM           hitem;
  UINT                flags;

  if (m_bDragging) {
    ASSERT(m_pimagelist != NULL);
    m_pimagelist->DragMove(point);
    if ((hitem = HitTest(point, &flags)) != NULL) {
      m_pimagelist->DragLeave(this);
      SelectDropTarget(hitem);
      m_hitemDrop = hitem;
      m_pimagelist->DragEnter(this, point);
    }
  }

  CTreeCtrl::OnMouseMove(nFlags, point);
}

bool CMyTreeCtrl::IsChildNodeOf(HTREEITEM hitemChild, HTREEITEM hitemSuspectedParent)
{
  do {
    if (hitemChild == hitemSuspectedParent)
      break;
  } while ((hitemChild = GetParentItem(hitemChild)) != NULL);

  return (hitemChild != NULL);
}

bool CMyTreeCtrl::IsLeafNode(HTREEITEM hItem)
{
  // ItemHasChildren() won't work in the general case
  BOOL status;
  int i, dummy;
  status = GetItemImage(hItem, i, dummy);
  ASSERT(status);
  return (i == LEAF);
}

void CMyTreeCtrl::DeleteWithParents(HTREEITEM hItem)
{
  // We don't want nodes that have no children to remain
  HTREEITEM p;
  do {
    p = GetParentItem(hItem);
    DeleteItem(hItem);
    if (ItemHasChildren(p))
      break;
    hItem = p;
  } while (p != TVI_ROOT);
}

CString CMyTreeCtrl::GetGroup(HTREEITEM hItem)
{
  CString retval;
  CString nodeText;
  while (hItem != NULL) {
    nodeText = GetItemText(hItem);
    if (!retval.IsEmpty())
      nodeText += GROUP_SEP;
    retval = nodeText + retval;
    hItem = GetParentItem(hItem);
  }
  return retval;
}

static CMyString GetPathElem(CMyString &path)
{
  // Get first path element and chop it off, i.e., if
  // path = "a.b.c.d"
  // will return "a" and path will be "b.c.d"
  // (assuming GROUP_SEP is '.')

  CMyString retval;
  int N = path.Find(GROUP_SEP);
  if (N == -1) {
    retval = path;
    path = _T("");
  } else {
    const int Len = path.GetLength();
    retval = CMyString(path.Left(N));
    path = CMyString(path.Right(Len - N - 1));
  }
  return retval;
}

static bool ExistsInTree(CTreeCtrl &Tree, HTREEITEM node,
			 const CMyString &s, HTREEITEM &si)
{
  // returns true iff s is a direct descendant of node
  HTREEITEM ti = Tree.GetChildItem(node);

  while (ti != NULL) {
    const CMyString itemText = Tree.GetItemText(ti);
    if (itemText == s) {
      si = ti;
      return true;
    }
    ti = Tree.GetNextItem(ti, TVGN_NEXT);
  }
  return false;
}

HTREEITEM CMyTreeCtrl::AddGroup(const CString &group)
{
  // Add a group at the end of path
  HTREEITEM ti = TVI_ROOT;
  HTREEITEM si;
  if (!group.IsEmpty()) {
    CMyString path = group;
    CMyString s;
    do {
      s = GetPathElem(path);
      if (!ExistsInTree(*this, ti, s, si)) {
	ti = InsertItem(s, ti, TVI_SORT);
	SetItemImage(ti, CMyTreeCtrl::NODE, CMyTreeCtrl::NODE);
      } else
	ti = si;
    } while (!path.IsEmpty());
  }
  return ti;
}

bool CMyTreeCtrl::TransferItem(HTREEITEM hitemDrag, HTREEITEM hitemDrop)
{
  TV_INSERTSTRUCT     tvstruct;
  TCHAR               sztBuffer[128];
  HTREEITEM           hNewItem, hFirstChild;
  DWORD itemData = GetItemData(hitemDrag);

  // avoid an infinite recursion
  tvstruct.item.hItem = hitemDrag;
  tvstruct.item.cchTextMax = sizeof(sztBuffer)/sizeof(TCHAR) - 1;
  tvstruct.item.pszText = sztBuffer;
  tvstruct.item.mask = (TVIF_CHILDREN | TVIF_HANDLE | TVIF_IMAGE
			| TVIF_SELECTEDIMAGE | TVIF_TEXT);
  GetItem(&tvstruct.item);  // get information of the dragged element
  tvstruct.hParent = hitemDrop;
  tvstruct.hInsertAfter = TVI_SORT;
  tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
  hNewItem = InsertItem(&tvstruct);
  if (itemData != 0) { // Non-NULL itemData implies Leaf
    CItemData *ci = (CItemData *)itemData;
    // Update Group
    CMyString path, elem;
    HTREEITEM p, q = hNewItem;
    do {
      p = GetParentItem(q);
      if (p != NULL) {
	elem = CMyString(GetItemText(p));
	if (!path.IsEmpty())
	  elem += GROUP_SEP;
	path = elem + path;
	q = p;
      } else
	break;
    } while (1);
    ci->SetGroup(path);
    // Mark database as modified!
    ((DboxMain *)GetParent())->SetChanged(true);
    // Update DisplayInfo record associated with ItemData
    DisplayInfo *di = (DisplayInfo *)ci->GetDisplayInfo();
    ASSERT(di != NULL);
    di->tree_item = hNewItem;
  }
  SetItemData(hNewItem, itemData);

  while ((hFirstChild = GetChildItem(hitemDrag)) != NULL) {
    TransferItem(hFirstChild, hNewItem);  // recursively transfer all the items
    DeleteItem(hFirstChild);
  }
  return true;
}

void CMyTreeCtrl::OnButtonUp()
{
  if (m_bDragging) {
    ASSERT(m_pimagelist != NULL);
    m_pimagelist->DragLeave(this);
    m_pimagelist->EndDrag();
    delete m_pimagelist;
    m_pimagelist = NULL;
    HTREEITEM parent = GetParentItem(m_hitemDrag);

    if (m_hitemDrag != m_hitemDrop &&
	!IsLeafNode(m_hitemDrop) &&
	!IsChildNodeOf(m_hitemDrop, m_hitemDrag) &&
	parent != m_hitemDrop) {
      TransferItem(m_hitemDrag, m_hitemDrop);
      DeleteItem(m_hitemDrag);
      while (parent != NULL && !ItemHasChildren(parent)) {
	HTREEITEM grandParent = GetParentItem(parent);
	DeleteItem(parent);
	parent = grandParent;
      }
    } else
      MessageBeep(0);

    ReleaseCapture();
    m_bDragging = FALSE;
    SelectDropTarget(NULL);
  }
}

void CMyTreeCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
  OnButtonUp();
  CTreeCtrl::OnLButtonUp(nFlags, point);
}

void CMyTreeCtrl::OnBeginDrag(LPNMHDR , LRESULT *)
{
  CPoint      ptAction;
  UINT        nFlags;

  GetCursorPos(&ptAction);
  ScreenToClient(&ptAction);
  ASSERT(!m_bDragging);
  m_bDragging = TRUE;
  m_hitemDrag = HitTest(ptAction, &nFlags);
  m_hitemDrop = NULL;

  ASSERT(m_pimagelist == NULL);
  m_pimagelist = CreateDragImage(m_hitemDrag);
  m_pimagelist->DragShowNolock(TRUE);
  m_pimagelist->SetDragCursorImage(0, CPoint(0, 0));
  m_pimagelist->BeginDrag(0, CPoint(0,0));
  m_pimagelist->DragMove(ptAction);
  m_pimagelist->DragEnter(this, ptAction);
  SetCapture();
}
<commit_msg>Removed annoying beep, resort after online edit.<commit_after>/*
 * Silly subclass of CTreeCtrl just to implement Drag&Drop.
 *
 * Based on MFC sample code from CMNCTRL1
 */

#include "stdafx.h"
#include "MyTreeCtrl.h"
#include "DboxMain.h"
#include "corelib/ItemData.h"
#include "corelib/MyString.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static const TCHAR GROUP_SEP = TCHAR('.');

CMyTreeCtrl::CMyTreeCtrl() : m_bDragging(false), m_pimagelist(NULL)
{
}

CMyTreeCtrl::~CMyTreeCtrl()
{
  delete m_pimagelist;
}

BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)
	//{{AFX_MSG_MAP(CMyTreeCtrl)
	ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndLabelEdit)
	ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBeginDrag)
	ON_WM_MOUSEMOVE()
	ON_WM_DESTROY()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMyTreeCtrl::OnDestroy()
{
  CImageList  *pimagelist;

  pimagelist = GetImageList(TVSIL_NORMAL);
  if (pimagelist != NULL) {
    pimagelist->DeleteImageList();
    delete pimagelist;
  }
}

void CMyTreeCtrl::SetNewStyle(long lStyleMask, BOOL bSetBits)
{
  long        lStyleOld;

  lStyleOld = GetWindowLong(m_hWnd, GWL_STYLE);
  lStyleOld &= ~lStyleMask;
  if (bSetBits)
    lStyleOld |= lStyleMask;

  SetWindowLong(m_hWnd, GWL_STYLE, lStyleOld);
  SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
}

void CMyTreeCtrl::UpdateLeafsGroup(HTREEITEM hItem, CString prefix)
{
  // Starting with hItem, update the Group field of all of hItem's
  // children. Called after a label has been edited.
  if (IsLeafNode(hItem)) {
    DWORD itemData = GetItemData(hItem);
    ASSERT(itemData != NULL);
    CItemData *ci = (CItemData *)itemData;
    ci->SetGroup(CMyString(prefix));
  } else { // update prefix with current group name and recurse
    if (!prefix.IsEmpty())
      prefix += GROUP_SEP;
    prefix += GetItemText(hItem);
    HTREEITEM child;
    for(child = GetChildItem(hItem); child != NULL; child = GetNextSiblingItem(child)) {
      UpdateLeafsGroup(child, prefix);
    }
  }
}

void CMyTreeCtrl::OnEndLabelEdit(LPNMHDR pnmhdr, LRESULT *pLResult)
{
  TV_DISPINFO *ptvinfo = (TV_DISPINFO *)pnmhdr;

  if (ptvinfo->item.pszText != NULL) {
    DboxMain *parent = (DboxMain *)GetParent();
    ptvinfo->item.mask = TVIF_TEXT;
    SetItem(&ptvinfo->item);
    HTREEITEM ti = ptvinfo->item.hItem;
    if (IsLeafNode(ptvinfo->item.hItem)) {
      // Update leaf's title
      DWORD itemData = GetItemData(ti);
      ASSERT(itemData != NULL);
      CItemData *ci = (CItemData *)itemData;
      ci->SetTitle(ptvinfo->item.pszText);
      // update corresponding List text
      DisplayInfo *di = (DisplayInfo *)ci->GetDisplayInfo();
      ASSERT(di != NULL);
      int lindex = di->list_index;
      parent->UpdateListItemTitle(lindex, ptvinfo->item.pszText);
    } else {
      // Update all leaf chldren with new path element
      // prefix is path up to and NOT including renamed node
      CString prefix;
      HTREEITEM parent, current = ti;
      do {
	parent = GetParentItem(current);
	if (parent == NULL) {
	  break;
	}
	current = parent;
	if (!prefix.IsEmpty())
	  prefix = GROUP_SEP + prefix;
	prefix = GetItemText(current) + prefix;
      } while (1);
      UpdateLeafsGroup(ti, prefix);
    }
    // Mark database as modified
    parent->SetChanged(true);
    SortChildren(GetParentItem(ti));
  }
  *pLResult = TRUE;
}

void CMyTreeCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
  HTREEITEM           hitem;
  UINT                flags;

  if (m_bDragging) {
    ASSERT(m_pimagelist != NULL);
    m_pimagelist->DragMove(point);
    if ((hitem = HitTest(point, &flags)) != NULL) {
      m_pimagelist->DragLeave(this);
      SelectDropTarget(hitem);
      m_hitemDrop = hitem;
      m_pimagelist->DragEnter(this, point);
    }
  }
  CTreeCtrl::OnMouseMove(nFlags, point);
}

bool CMyTreeCtrl::IsChildNodeOf(HTREEITEM hitemChild, HTREEITEM hitemSuspectedParent)
{
  do {
    if (hitemChild == hitemSuspectedParent)
      break;
  } while ((hitemChild = GetParentItem(hitemChild)) != NULL);

  return (hitemChild != NULL);
}

bool CMyTreeCtrl::IsLeafNode(HTREEITEM hItem)
{
  // ItemHasChildren() won't work in the general case
  BOOL status;
  int i, dummy;
  status = GetItemImage(hItem, i, dummy);
  ASSERT(status);
  return (i == LEAF);
}

void CMyTreeCtrl::DeleteWithParents(HTREEITEM hItem)
{
  // We don't want nodes that have no children to remain
  HTREEITEM p;
  do {
    p = GetParentItem(hItem);
    DeleteItem(hItem);
    if (ItemHasChildren(p))
      break;
    hItem = p;
  } while (p != TVI_ROOT);
}

CString CMyTreeCtrl::GetGroup(HTREEITEM hItem)
{
  CString retval;
  CString nodeText;
  while (hItem != NULL) {
    nodeText = GetItemText(hItem);
    if (!retval.IsEmpty())
      nodeText += GROUP_SEP;
    retval = nodeText + retval;
    hItem = GetParentItem(hItem);
  }
  return retval;
}

static CMyString GetPathElem(CMyString &path)
{
  // Get first path element and chop it off, i.e., if
  // path = "a.b.c.d"
  // will return "a" and path will be "b.c.d"
  // (assuming GROUP_SEP is '.')

  CMyString retval;
  int N = path.Find(GROUP_SEP);
  if (N == -1) {
    retval = path;
    path = _T("");
  } else {
    const int Len = path.GetLength();
    retval = CMyString(path.Left(N));
    path = CMyString(path.Right(Len - N - 1));
  }
  return retval;
}

static bool ExistsInTree(CTreeCtrl &Tree, HTREEITEM node,
			 const CMyString &s, HTREEITEM &si)
{
  // returns true iff s is a direct descendant of node
  HTREEITEM ti = Tree.GetChildItem(node);

  while (ti != NULL) {
    const CMyString itemText = Tree.GetItemText(ti);
    if (itemText == s) {
      si = ti;
      return true;
    }
    ti = Tree.GetNextItem(ti, TVGN_NEXT);
  }
  return false;
}

HTREEITEM CMyTreeCtrl::AddGroup(const CString &group)
{
  // Add a group at the end of path
  HTREEITEM ti = TVI_ROOT;
  HTREEITEM si;
  if (!group.IsEmpty()) {
    CMyString path = group;
    CMyString s;
    do {
      s = GetPathElem(path);
      if (!ExistsInTree(*this, ti, s, si)) {
	ti = InsertItem(s, ti, TVI_SORT);
	SetItemImage(ti, CMyTreeCtrl::NODE, CMyTreeCtrl::NODE);
      } else
	ti = si;
    } while (!path.IsEmpty());
  }
  return ti;
}

bool CMyTreeCtrl::TransferItem(HTREEITEM hitemDrag, HTREEITEM hitemDrop)
{
  TV_INSERTSTRUCT     tvstruct;
  TCHAR               sztBuffer[128];
  HTREEITEM           hNewItem, hFirstChild;
  DWORD itemData = GetItemData(hitemDrag);

  // avoid an infinite recursion
  tvstruct.item.hItem = hitemDrag;
  tvstruct.item.cchTextMax = sizeof(sztBuffer)/sizeof(TCHAR) - 1;
  tvstruct.item.pszText = sztBuffer;
  tvstruct.item.mask = (TVIF_CHILDREN | TVIF_HANDLE | TVIF_IMAGE
			| TVIF_SELECTEDIMAGE | TVIF_TEXT);
  GetItem(&tvstruct.item);  // get information of the dragged element
  tvstruct.hParent = hitemDrop;
  tvstruct.hInsertAfter = TVI_SORT;
  tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
  hNewItem = InsertItem(&tvstruct);
  if (itemData != 0) { // Non-NULL itemData implies Leaf
    CItemData *ci = (CItemData *)itemData;
    // Update Group
    CMyString path, elem;
    HTREEITEM p, q = hNewItem;
    do {
      p = GetParentItem(q);
      if (p != NULL) {
	elem = CMyString(GetItemText(p));
	if (!path.IsEmpty())
	  elem += GROUP_SEP;
	path = elem + path;
	q = p;
      } else
	break;
    } while (1);
    ci->SetGroup(path);
    // Mark database as modified!
    ((DboxMain *)GetParent())->SetChanged(true);
    // Update DisplayInfo record associated with ItemData
    DisplayInfo *di = (DisplayInfo *)ci->GetDisplayInfo();
    ASSERT(di != NULL);
    di->tree_item = hNewItem;
  }
  SetItemData(hNewItem, itemData);

  while ((hFirstChild = GetChildItem(hitemDrag)) != NULL) {
    TransferItem(hFirstChild, hNewItem);  // recursively transfer all the items
    DeleteItem(hFirstChild);
  }
  return true;
}

void CMyTreeCtrl::OnButtonUp()
{
  if (m_bDragging) {
    ASSERT(m_pimagelist != NULL);
    m_pimagelist->DragLeave(this);
    m_pimagelist->EndDrag();
    delete m_pimagelist;
    m_pimagelist = NULL;
    HTREEITEM parent = GetParentItem(m_hitemDrag);

    if (m_hitemDrag != m_hitemDrop &&
	!IsLeafNode(m_hitemDrop) &&
	!IsChildNodeOf(m_hitemDrop, m_hitemDrag) &&
	parent != m_hitemDrop) {
      TransferItem(m_hitemDrag, m_hitemDrop);
      DeleteItem(m_hitemDrag);
      while (parent != NULL && !ItemHasChildren(parent)) {
	HTREEITEM grandParent = GetParentItem(parent);
	DeleteItem(parent);
	parent = grandParent;
      }
    }
    ReleaseCapture();
    m_bDragging = FALSE;
    SelectDropTarget(NULL);
  }
}

void CMyTreeCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
  OnButtonUp();
  CTreeCtrl::OnLButtonUp(nFlags, point);
}

void CMyTreeCtrl::OnBeginDrag(LPNMHDR , LRESULT *)
{
  CPoint      ptAction;
  UINT        nFlags;

  GetCursorPos(&ptAction);
  ScreenToClient(&ptAction);
  ASSERT(!m_bDragging);
  m_bDragging = TRUE;
  m_hitemDrag = HitTest(ptAction, &nFlags);
  m_hitemDrop = NULL;

  ASSERT(m_pimagelist == NULL);
  m_pimagelist = CreateDragImage(m_hitemDrag);
  m_pimagelist->DragShowNolock(TRUE);
  m_pimagelist->SetDragCursorImage(0, CPoint(0, 0));
  m_pimagelist->BeginDrag(0, CPoint(0,0));
  m_pimagelist->DragMove(ptAction);
  m_pimagelist->DragEnter(this, ptAction);
  SetCapture();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <map>
#include <string>
#include <iterator>
#include <vector>
using namespace std;

unsigned int M;
string morse_string;
string morse_table[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};

int matches(unsigned int start, vector<int> &x, map<string, int> &dictionary) {
	if (start == morse_string.size())
		return 1;
	if (x[start] != -1)
		return x[start];

	int ret = 0;
	map<string, int>::iterator it;
	string substring;
	for (unsigned int i = 0 ; i < M && start+i < morse_string.size() ; i++) {
		substring += morse_string[start+i];
		if ((it = dictionary.find(substring)) != dictionary.end())
			ret += it->second*matches(start+i+1, x, dictionary);
	}

	x[start] = ret;
	return ret;
}

string encode_morse(const string s) {
	string ret = "";
	for (char c:s)
		ret += morse_table[c-'A'];
	if (ret.size() > M)
		M = ret.size();
	return ret;
}

int main() {
	int T, N;
	string tmp;
	map<string, int>::iterator it;
	cin >> T;

	while (T--) {
		M = 0;
		vector<int> x(1000, -1);
		map<string, int> dictionary;
		morse_string = "";
		cin >> morse_string;
		cin >> N;
		for (int j = 0 ; j < N ; j++) {
			cin >> tmp;
			tmp = encode_morse(tmp);
			if ((it = dictionary.find(tmp)) == dictionary.end())
				dictionary[tmp] = 1;
			else
				dictionary[tmp]++;
		}

		cout << matches(0, x, dictionary) << endl;

		if (T) {
			cout << endl;
			for (int j = 0 ; j < 1000 ; j++)
				x[j] = -1;
		}
	}
	return 0;
}
<commit_msg>Morse Multiple Matches<commit_after><|endoftext|>


<commit_before>// from execute.cpp
void DrawASCII(LWR& lwr) {
  string ascii_filename;
  fprintf(stdout, "What ASCII photo would you like me to draw?\n> ");
  cin >> ascii_filename;
  lwr.DrawASCIIPhoto(ASCII_PATH + ascii_filename + TXT);
}

// from LWR
  // Just for fun draw a file containing ASCII characters
  int DrawASCIIPhoto(std::string path_to_ascii_file = "",
    double speed_percent = 100.0);

// from utils
namespace AsciiArt {
  int Generate2DVectorFromASCIIFile(std::string ascii_file,
    std::vector<std::vector<char>>& ascii_img,
    std::unordered_map<char, std::string> character_set,
    std::vector<char>& char_appearance);
};

///////////////////////////////////////////////////////////////////////////////
////                                ASCII                                  ////
///////////////////////////////////////////////////////////////////////////////

// This comes from the thesis and thus needs to be heavily modified.

// .png or .jpg photo should first be converted into an ASCII photo.
/*
int LWR::DrawASCIIPhoto(string path_to_ascii_file,
  double speed_percent) {
  vector<vector<char>> ascii_img;
  vector<cart_motion*> character_motion_paths;
  unordered_map<char, int> character_freq;
  unsigned int err_val = 0;

  if (path_to_ascii_file != "") {
    // read ASCII photo from file into 2D vector.
    Generate2DVectorFromASCIIFile(path_to_ascii_file, ascii_img,
      character_freq);

    int img_width = ascii_img.at(0).size();
    int img_height = ascii_img.size();
    LWRLogParser log_parser = LWRLogParser();

    // load motion profiles for all characters in ascii drawing
    // from motion normalized log files
    for (const auto &myPair : character_freq) {
      string log_file = KUKA_LOG_DIR;
      log_file += myPair.first;
      log_file += "_standardized";
      log_file += KUKA_LOG_EXTENSION;
      log_parser.SetLogFile(log_file);

      character_motion_paths.push_back(new cart_motion());

      // parse log file and generate motion to repeat
      err_val = log_parser.ParseMotion(NULL, character_motion_paths.back());
      if (err_val != EOK) {
        printf("ERROR, could not parse input file");
        // add deleting
        // delete &cart_path;
        return ERROR_INVALID_INPUT_FILE;
      }
    }

  }
  else {
    // keyboard input script
  }
  return 1;
}
*/
int LWR::DrawASCIIPhoto(string path_to_ascii_file,
  double speed_percent) {
  // assume standardized character recording files have been created

  // start with map character -> filename
  string standardized_file_path = "C:\\Users\\HMMS\\Documents\\GitHub\\Thesis\\KUKA LWR\\logs\\standardized_char_set\\";
  string standardized_file_extension = ".dat";
  static unordered_map<char, string> char_filename_map = {
    { '$', "$" }, { ' ', "space" }, { '+', "+" }, { '7', "7" }, { '8', "8" },
    { ':', "colon" }, { '=', "equal" }, { '?', "question" }, { 'D', "D" },
    { 'I', "I" }, { 'M', "M" }, { 'N', "N" }, { 'O', "O" }, { 'Z', "Z" },
    { '~', "tilde" }, { '\n', "newline" }, {'\b', "newline_left"}
  };
  // reserve for char order and appearance in ASCII file
  vector<char> char_appearance;
  //float start[3] = { -0.7, 0.4, -0.0145 };
  float start[3] = { -0.70f, 0.0f, 0.200f };  // draw on table
  int column = 0;
  int row = 0;

  // create 2D character array for ascii art photo
  // get mapping in order of what characters are in the file
  vector<vector<char>> ascii_img;
  AsciiArt::Generate2DVectorFromASCIIFile(path_to_ascii_file, ascii_img, char_filename_map, char_appearance);

  // artificially add \n and \b to appearance
  char_appearance.push_back('\n');
  //char_appearance.push_back('\b');

  // map character to open file stream (hardcore)
  /*
  unordered_map<char, ifstream> char_files;
  for (int i = 0; i < char_appearance.size(); ++i) {
  char_files[i] = ifstream(char_filename_map[char_appearance[i]]);
  }
  */

  // load header information
  // assume char width, height, pose all the same for all standards
  int char_width;
  int char_height;
  float pose_rotation_matrix[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  Logging::Logger log;
  log.SetInputFile(standardized_file_path + char_appearance[0] + standardized_file_extension);
  log.ReadHeader();
  //LWRLogParser log_parser = LWRLogParser(standardized_file_path + char_appearance[0] + standardized_file_extension);
  //log_parser.ParseHeader();

  // get char width, char height, rotation matrix
  log.GetCharacterWidth(char_width);
  log.GetCharacterHeight(char_height);
  log.GetPoseRotationMatrix(pose_rotation_matrix);

  // load entire path for each used character
  // maps 'char' -> vector<float[3]> e.g. '$' -> [[1,2,3], [1,2,4], [1,2,2] ...
  unordered_map<char, vector<vector<float>>> char_path_map;
  for (unsigned int i = 0; i < char_appearance.size(); ++i) {
    char current_char = char_appearance[i];
    ifstream char_file = ifstream(standardized_file_path + char_filename_map[current_char] + standardized_file_extension);
    // add new entry to map for char
    char_path_map[current_char] = vector<vector<float>>();
    // read path
    log.ReadStandardizedCharacterPath(&char_file, char_path_map[current_char]);
  }

  // set rotation matrix in commanded pose
  // same rotation matrix is used for all points
  // limited scope
  {
    int i = 0;
    int j = 0;
    for (i; i < NUMBER_OF_FRAME_ELEMENTS; ++i) {
      pose_cmd[i] = pose_rotation_matrix[j++];
      if ((i + 1) % 4 == 0) {
        i++;
      }
    }
  }

  // get starting position
  char tmp = ascii_img[0][0];
  vector<float> starting_xyz = char_path_map[tmp][0];
  pose_cmd[3] = starting_xyz[0];
  pose_cmd[7] = starting_xyz[1];
  pose_cmd[11] = starting_xyz[2];
  // add starting position offset

  // move to starting position
  int err_val = EOK;
  printf("MOVING to starting position.\n");

  //err_val = MoveToJointPosition({-0.669f, 43.977f, 0.690f, -101.919f, -0.207f, -55.887f, -0.368f});
  //err_val = MoveToCartesianPose(pose_cmd);
  //if (err_val != EOK) {
  //  fri_->printf("ERROR, cannot move robot to position\n");
  //}
  //else {
  //  printf("MOVED to starting position\n");
  //}
  // start cartesian impedance control mode
  err_val = StartCartesianImpedanceControlMode(CARTESIAN_STIFFNESS_HIGH, CARTESIAN_DAMPING_LOW, CARTESIAN_TORQUE_NONE);
  if (err_val != EOK) {
    printf("ERROR, could not start robot in CartImpedanceControlMode");
    return err_val;
  }

  ofstream output("C:\\Users\\HMMS\\Documents\\GitHub\\Thesis\\KUKA LWR\\misc\\ascii_art_path.txt");

  // loop over char in 2D ascii art array

  // for this printer pattern add:
  //    new line at end to even line numbers
  //    inv(space), new line to the start odd line numbers
  /*
  for (int i = 0; i < ascii_img.size(); ++i) {
    if (i % 2 == 0) {
      ascii_img[i].push_back('\n');
    }
    else {
      ascii_img[i].insert(ascii_img[i].begin(), '\b');
    }
  }
  */
  row = 0;
  for (auto ascii_row : ascii_img) {
    column = 0;
    if ((row % 2) == 1) { // odd == right to left

      for (column = ascii_row.size() - 1; column >= 0; column--) {
        char ascii_character = ascii_row[column];
        printf("%c", ascii_character);
        //output << ascii_character << "\n";
        auto path = char_path_map[ascii_character];
        for (int elem = path.size() -1 ; elem >= 0; elem--) {
          //printf("%d/%d\n", path.size()-1-elem, path.size());
          // wait one KRC iteration cycle
          fri_->WaitForKRCTick();

          // check for connection issues

          if (!fri_->IsMachineOK()) {
          fprintf(stderr, "ERROR, the machine is not ready anymore.\n");
          err_val = Errors::ERROR_MACHINE_NOT_OKAY;
          break;
          }

          // set commanded pose displacements to standardized path value
          // rotations will never change and are set origionally
          pose_cmd[3] = path[elem][0];
          pose_cmd[7] = path[elem][1];
          pose_cmd[11] = path[elem][2];

          // add starting point
          pose_cmd[3] += start[0];
          pose_cmd[7] += start[1];
          pose_cmd[11] += start[2];

          // add position x y global offset
          pose_cmd[3] += (float)(column*char_width) / 1000.0f;  // mm to m
          pose_cmd[7] -= (float)(row*char_height) / 1000.0f;

          fri_->SetCommandedCartPose(pose_cmd);
          //printf("%.5f, %.5f, %.5f\n", pose_cmd[3], pose_cmd[7], pose_cmd[11]);
          output << pose_cmd[3] << "\t" << pose_cmd[7] << "\t" << pose_cmd[11] << "\n";
        }
      }
      printf("\n");
    }
    else {  // forward
      for (column = 0; column < static_cast<int>(ascii_row.size()); ++column) {
        char ascii_character = ascii_row[column];
        printf("%c", ascii_character);
        //output << ascii_character << "\n";
        auto path = char_path_map[ascii_character];

        for (unsigned int elem = 0; elem < path.size(); ++elem) {
          //printf("%d/%d\n", elem, path.size()-1);
          // wait one KRC iteration cycle
          fri_->WaitForKRCTick();

          // check for connection issues

          if (!fri_->IsMachineOK()) {
          fprintf(stderr, "ERROR, the machine is not ready anymore.\n");
          err_val = Errors::ERROR_MACHINE_NOT_OKAY;
          break;
          }

          // set commanded pose displacements to standardized path value
          // rotations will never change and are set origionally
          pose_cmd[3] = path[elem][0];
          pose_cmd[7] = path[elem][1];
          pose_cmd[11] = path[elem][2];

          // add starting point
          pose_cmd[3] += start[0];
          pose_cmd[7] += start[1];
          pose_cmd[11] += start[2];

          // add position x y global offset
          pose_cmd[3] += (float)(column*char_width) / 1000.0f;  // mm to m
          pose_cmd[7] -= (float)(row*char_height) / 1000.0f;

          fri_->SetCommandedCartPose(pose_cmd);
          //printf("%.5f, %.5f, %.5f\n", pose_cmd[3], pose_cmd[7], pose_cmd[11]);
          output << pose_cmd[3] << "\t" << pose_cmd[7] << "\t" << pose_cmd[11] << "\n";
        }
      }
      printf("\n");
    }
    // add new line
    auto path = char_path_map['\n'];
    column < 0 ? column++ : column-- ;
    for (unsigned int elem = 0; elem < path.size(); ++elem) {
      //printf("%d/%d\n", elem, path.size() - 1);
      // wait one KRC iteration cycle
      fri_->WaitForKRCTick();

      // check for connection issues

      if (!fri_->IsMachineOK()) {
        fprintf(stderr, "ERROR, the machine is not ready anymore.\n");
        err_val = Errors::ERROR_MACHINE_NOT_OKAY;
        break;
      }

      // set commanded pose displacements to standardized path value
      // rotations will never change and are set origionally
      pose_cmd[3] = path[elem][0];
      pose_cmd[7] = path[elem][1];
      pose_cmd[11] = path[elem][2];

      // add starting point
      pose_cmd[3] += start[0];
      pose_cmd[7] += start[1];
      pose_cmd[11] += start[2];

      // add position x y global offset
      pose_cmd[3] += (float)(column*char_width) / 1000.0f;  // mm to m
      pose_cmd[7] -= (float)(row*char_height) / 1000.0f;

      fri_->SetCommandedCartPose(pose_cmd);
      //printf("%.5f, %.5f, %.5f\n", pose_cmd[3], pose_cmd[7], pose_cmd[11]);
      output << pose_cmd[3] << "\t" << pose_cmd[7] << "\t" << pose_cmd[11] << "\n";
    }

    row++;
  }

  // stop
  fri_->StopRobot();
  return EOK;
}<commit_msg>Generate ascii art file<commit_after>// from execute.cpp
void DrawASCII(LWR& lwr) {
  string ascii_filename;
  fprintf(stdout, "What ASCII photo would you like me to draw?\n> ");
  cin >> ascii_filename;
  lwr.DrawASCIIPhoto(ASCII_PATH + ascii_filename + TXT);
}

// from LWR
  // Just for fun draw a file containing ASCII characters
  int DrawASCIIPhoto(std::string path_to_ascii_file = "",
    double speed_percent = 100.0);

// from utils
namespace AsciiArt {
  int Generate2DVectorFromASCIIFile(std::string ascii_file,
    std::vector<std::vector<char>>& ascii_img,
    std::unordered_map<char, std::string> character_set,
    std::vector<char>& char_appearance);
};

namespace AsciiArt {
  int Generate2DVectorFromASCIIFile(string ascii_file,
    vector<vector<char>>& ascii_img,
    unordered_map<char, string> character_set,
    vector<char>& char_appearance) {

    ifstream ss_ascii_file(ascii_file);
    if (!ss_ascii_file.is_open()) {
      printf("Unable to open ASCII file");
      return ERROR_FILE_NOT_FOUND;
    }

    string line;
    int row = 0;
    while (getline(ss_ascii_file, line)) {
      ascii_img.push_back(vector<char>());  // row vector columns set to line size
      for (unsigned int i = 0; i<line.length(); i++) {
        ascii_img[row].push_back(line.at(i));  // set character
        if (character_set.erase(line[i]) == 1) {  // just removed from map
          char_appearance.push_back(line.at(i));
        }
      }
      row++;
    }
    return SUCCESS;
  }
}

///////////////////////////////////////////////////////////////////////////////
////                                ASCII                                  ////
///////////////////////////////////////////////////////////////////////////////

// This comes from the thesis and thus needs to be heavily modified.

// .png or .jpg photo should first be converted into an ASCII photo.
/*
int LWR::DrawASCIIPhoto(string path_to_ascii_file,
  double speed_percent) {
  vector<vector<char>> ascii_img;
  vector<cart_motion*> character_motion_paths;
  unordered_map<char, int> character_freq;
  unsigned int err_val = 0;

  if (path_to_ascii_file != "") {
    // read ASCII photo from file into 2D vector.
    Generate2DVectorFromASCIIFile(path_to_ascii_file, ascii_img,
      character_freq);

    int img_width = ascii_img.at(0).size();
    int img_height = ascii_img.size();
    LWRLogParser log_parser = LWRLogParser();

    // load motion profiles for all characters in ascii drawing
    // from motion normalized log files
    for (const auto &myPair : character_freq) {
      string log_file = KUKA_LOG_DIR;
      log_file += myPair.first;
      log_file += "_standardized";
      log_file += KUKA_LOG_EXTENSION;
      log_parser.SetLogFile(log_file);

      character_motion_paths.push_back(new cart_motion());

      // parse log file and generate motion to repeat
      err_val = log_parser.ParseMotion(NULL, character_motion_paths.back());
      if (err_val != EOK) {
        printf("ERROR, could not parse input file");
        // add deleting
        // delete &cart_path;
        return ERROR_INVALID_INPUT_FILE;
      }
    }

  }
  else {
    // keyboard input script
  }
  return 1;
}
*/
int LWR::DrawASCIIPhoto(string path_to_ascii_file,
  double speed_percent) {
  // assume standardized character recording files have been created

  // start with map character -> filename
  string standardized_file_path = "C:\\Users\\HMMS\\Documents\\GitHub\\Thesis\\KUKA LWR\\logs\\standardized_char_set\\";
  string standardized_file_extension = ".dat";
  static unordered_map<char, string> char_filename_map = {
    { '$', "$" }, { ' ', "space" }, { '+', "+" }, { '7', "7" }, { '8', "8" },
    { ':', "colon" }, { '=', "equal" }, { '?', "question" }, { 'D', "D" },
    { 'I', "I" }, { 'M', "M" }, { 'N', "N" }, { 'O', "O" }, { 'Z', "Z" },
    { '~', "tilde" }, { '\n', "newline" }, {'\b', "newline_left"}
  };
  // reserve for char order and appearance in ASCII file
  vector<char> char_appearance;
  //float start[3] = { -0.7, 0.4, -0.0145 };
  float start[3] = { -0.70f, 0.0f, 0.200f };  // draw on table
  int column = 0;
  int row = 0;

  // create 2D character array for ascii art photo
  // get mapping in order of what characters are in the file
  vector<vector<char>> ascii_img;
  AsciiArt::Generate2DVectorFromASCIIFile(path_to_ascii_file, ascii_img, char_filename_map, char_appearance);

  // artificially add \n and \b to appearance
  char_appearance.push_back('\n');
  //char_appearance.push_back('\b');

  // map character to open file stream (hardcore)
  /*
  unordered_map<char, ifstream> char_files;
  for (int i = 0; i < char_appearance.size(); ++i) {
  char_files[i] = ifstream(char_filename_map[char_appearance[i]]);
  }
  */

  // load header information
  // assume char width, height, pose all the same for all standards
  int char_width;
  int char_height;
  float pose_rotation_matrix[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  Logging::Logger log;
  log.SetInputFile(standardized_file_path + char_appearance[0] + standardized_file_extension);
  log.ReadHeader();
  //LWRLogParser log_parser = LWRLogParser(standardized_file_path + char_appearance[0] + standardized_file_extension);
  //log_parser.ParseHeader();

  // get char width, char height, rotation matrix
  log.GetCharacterWidth(char_width);
  log.GetCharacterHeight(char_height);
  log.GetPoseRotationMatrix(pose_rotation_matrix);

  // load entire path for each used character
  // maps 'char' -> vector<float[3]> e.g. '$' -> [[1,2,3], [1,2,4], [1,2,2] ...
  unordered_map<char, vector<vector<float>>> char_path_map;
  for (unsigned int i = 0; i < char_appearance.size(); ++i) {
    char current_char = char_appearance[i];
    ifstream char_file = ifstream(standardized_file_path + char_filename_map[current_char] + standardized_file_extension);
    // add new entry to map for char
    char_path_map[current_char] = vector<vector<float>>();
    // read path
    log.ReadStandardizedCharacterPath(&char_file, char_path_map[current_char]);
  }

  // set rotation matrix in commanded pose
  // same rotation matrix is used for all points
  // limited scope
  {
    int i = 0;
    int j = 0;
    for (i; i < NUMBER_OF_FRAME_ELEMENTS; ++i) {
      pose_cmd[i] = pose_rotation_matrix[j++];
      if ((i + 1) % 4 == 0) {
        i++;
      }
    }
  }

  // get starting position
  char tmp = ascii_img[0][0];
  vector<float> starting_xyz = char_path_map[tmp][0];
  pose_cmd[3] = starting_xyz[0];
  pose_cmd[7] = starting_xyz[1];
  pose_cmd[11] = starting_xyz[2];
  // add starting position offset

  // move to starting position
  int err_val = EOK;
  printf("MOVING to starting position.\n");

  //err_val = MoveToJointPosition({-0.669f, 43.977f, 0.690f, -101.919f, -0.207f, -55.887f, -0.368f});
  //err_val = MoveToCartesianPose(pose_cmd);
  //if (err_val != EOK) {
  //  fri_->printf("ERROR, cannot move robot to position\n");
  //}
  //else {
  //  printf("MOVED to starting position\n");
  //}
  // start cartesian impedance control mode
  err_val = StartCartesianImpedanceControlMode(CARTESIAN_STIFFNESS_HIGH, CARTESIAN_DAMPING_LOW, CARTESIAN_TORQUE_NONE);
  if (err_val != EOK) {
    printf("ERROR, could not start robot in CartImpedanceControlMode");
    return err_val;
  }

  ofstream output("C:\\Users\\HMMS\\Documents\\GitHub\\Thesis\\KUKA LWR\\misc\\ascii_art_path.txt");

  // loop over char in 2D ascii art array

  // for this printer pattern add:
  //    new line at end to even line numbers
  //    inv(space), new line to the start odd line numbers
  /*
  for (int i = 0; i < ascii_img.size(); ++i) {
    if (i % 2 == 0) {
      ascii_img[i].push_back('\n');
    }
    else {
      ascii_img[i].insert(ascii_img[i].begin(), '\b');
    }
  }
  */
  row = 0;
  for (auto ascii_row : ascii_img) {
    column = 0;
    if ((row % 2) == 1) { // odd == right to left

      for (column = ascii_row.size() - 1; column >= 0; column--) {
        char ascii_character = ascii_row[column];
        printf("%c", ascii_character);
        //output << ascii_character << "\n";
        auto path = char_path_map[ascii_character];
        for (int elem = path.size() -1 ; elem >= 0; elem--) {
          //printf("%d/%d\n", path.size()-1-elem, path.size());
          // wait one KRC iteration cycle
          fri_->WaitForKRCTick();

          // check for connection issues

          if (!fri_->IsMachineOK()) {
          fprintf(stderr, "ERROR, the machine is not ready anymore.\n");
          err_val = Errors::ERROR_MACHINE_NOT_OKAY;
          break;
          }

          // set commanded pose displacements to standardized path value
          // rotations will never change and are set origionally
          pose_cmd[3] = path[elem][0];
          pose_cmd[7] = path[elem][1];
          pose_cmd[11] = path[elem][2];

          // add starting point
          pose_cmd[3] += start[0];
          pose_cmd[7] += start[1];
          pose_cmd[11] += start[2];

          // add position x y global offset
          pose_cmd[3] += (float)(column*char_width) / 1000.0f;  // mm to m
          pose_cmd[7] -= (float)(row*char_height) / 1000.0f;

          fri_->SetCommandedCartPose(pose_cmd);
          //printf("%.5f, %.5f, %.5f\n", pose_cmd[3], pose_cmd[7], pose_cmd[11]);
          output << pose_cmd[3] << "\t" << pose_cmd[7] << "\t" << pose_cmd[11] << "\n";
        }
      }
      printf("\n");
    }
    else {  // forward
      for (column = 0; column < static_cast<int>(ascii_row.size()); ++column) {
        char ascii_character = ascii_row[column];
        printf("%c", ascii_character);
        //output << ascii_character << "\n";
        auto path = char_path_map[ascii_character];

        for (unsigned int elem = 0; elem < path.size(); ++elem) {
          //printf("%d/%d\n", elem, path.size()-1);
          // wait one KRC iteration cycle
          fri_->WaitForKRCTick();

          // check for connection issues

          if (!fri_->IsMachineOK()) {
          fprintf(stderr, "ERROR, the machine is not ready anymore.\n");
          err_val = Errors::ERROR_MACHINE_NOT_OKAY;
          break;
          }

          // set commanded pose displacements to standardized path value
          // rotations will never change and are set origionally
          pose_cmd[3] = path[elem][0];
          pose_cmd[7] = path[elem][1];
          pose_cmd[11] = path[elem][2];

          // add starting point
          pose_cmd[3] += start[0];
          pose_cmd[7] += start[1];
          pose_cmd[11] += start[2];

          // add position x y global offset
          pose_cmd[3] += (float)(column*char_width) / 1000.0f;  // mm to m
          pose_cmd[7] -= (float)(row*char_height) / 1000.0f;

          fri_->SetCommandedCartPose(pose_cmd);
          //printf("%.5f, %.5f, %.5f\n", pose_cmd[3], pose_cmd[7], pose_cmd[11]);
          output << pose_cmd[3] << "\t" << pose_cmd[7] << "\t" << pose_cmd[11] << "\n";
        }
      }
      printf("\n");
    }
    // add new line
    auto path = char_path_map['\n'];
    column < 0 ? column++ : column-- ;
    for (unsigned int elem = 0; elem < path.size(); ++elem) {
      //printf("%d/%d\n", elem, path.size() - 1);
      // wait one KRC iteration cycle
      fri_->WaitForKRCTick();

      // check for connection issues

      if (!fri_->IsMachineOK()) {
        fprintf(stderr, "ERROR, the machine is not ready anymore.\n");
        err_val = Errors::ERROR_MACHINE_NOT_OKAY;
        break;
      }

      // set commanded pose displacements to standardized path value
      // rotations will never change and are set origionally
      pose_cmd[3] = path[elem][0];
      pose_cmd[7] = path[elem][1];
      pose_cmd[11] = path[elem][2];

      // add starting point
      pose_cmd[3] += start[0];
      pose_cmd[7] += start[1];
      pose_cmd[11] += start[2];

      // add position x y global offset
      pose_cmd[3] += (float)(column*char_width) / 1000.0f;  // mm to m
      pose_cmd[7] -= (float)(row*char_height) / 1000.0f;

      fri_->SetCommandedCartPose(pose_cmd);
      //printf("%.5f, %.5f, %.5f\n", pose_cmd[3], pose_cmd[7], pose_cmd[11]);
      output << pose_cmd[3] << "\t" << pose_cmd[7] << "\t" << pose_cmd[11] << "\n";
    }

    row++;
  }

  // stop
  fri_->StopRobot();
  return EOK;
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "LFListenerPoolTest.h"

//--- module under test --------------------------------------------------------
#include "LFListenerPool.h"

//--- test modules used --------------------------------------------------------
#include "TestSuite.h"

//--- standard modules used ----------------------------------------------------
#include "Socket.h"
#include "WPMStatHandler.h"
#include "RequestProcessor.h"

//--- TestRequestReactor ----
//:test driver for lf pool testing
class TestProcessor: public RequestProcessor
{
public:
	TestProcessor(LFListenerPoolTest *);
	~TestProcessor();
	void ProcessRequest(Context &ctx);

protected:
	LFListenerPoolTest *fTest;
};

TestProcessor::TestProcessor(LFListenerPoolTest *test)
	: RequestProcessor("TestProcessor")
	, fTest(test)
{
	StartTrace(TestProcessor.Ctor);
}

TestProcessor::~TestProcessor()
{
	StartTrace(TestProcessor.Dtor);
}

void TestProcessor::ProcessRequest(Context &ctx)
{
	StartTrace(TestProcessor.ProcessRequest);
	fTest->EventProcessed(ctx.GetSocket());
}

//---- LFListenerPoolTest ----------------------------------------------------------------
LFListenerPoolTest::LFListenerPoolTest(TString tstrName)
	: TestCaseType(tstrName)
{
	StartTrace(LFListenerPoolTest.LFListenerPoolTest);
}

LFListenerPoolTest::~LFListenerPoolTest()
{
	StartTrace(LFListenerPoolTest.Dtor);
}

void LFListenerPoolTest::setUp ()
{
	StartTrace(LFListenerPoolTest.setUp);
	t_assert(GetConfig().IsDefined("Modules"));
}

void LFListenerPoolTest::NoReactorTest()
{
	StartTrace(LFListenerPoolTest.NoReactorTest);
	LFListenerPool lfp(0);

	Trace("ip:" << GetConfig()["Testhost"]["ip"].AsString() << " : port:" << GetConfig()["Testhost"]["port"].AsLong());
	Acceptor ac1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["Testhost"]["port"].AsLong(), 5, 0);
	Anything lfpConfig;
	lfpConfig[String("Accept") << GetConfig()["Testhost"]["port"].AsString()] = (IFAObject *)&ac1;
	if ( t_assertm( !lfp.Init(2, lfpConfig, true), "no reactor is configured; init should fail")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 10) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::NoFactoryTest()
{
	StartTrace(LFListenerPoolTest.NoFactoryTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("TCP4343");
	if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to fail; no valid factory")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 10) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::InvalidAcceptorTest()
{
	StartTrace(LFListenerPoolTest.InvalidAcceptorTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("Fake");
	if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to fail; acceptor is not valid")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 10) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::InvalidReactorTest()
{
	StartTrace(LFListenerPoolTest.InvalidReactorTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(0, 0));

	Anything lfpConfig;
	lfpConfig.Append("TCP5010");
	if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to fail; reactor is not valid")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 10) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::OneAcceptorTest()
{
	StartTrace(LFListenerPoolTest.OneAcceptorTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("TCP5010");
	if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to succeed; are factories present?")) {
		if (t_assert(lfp.Start(true, 1000, 10) == 0 )) {
			ProcessOneEvent();
			lfp.RequestTermination();
			t_assertm(lfp.Join() == 0, "expected Join to succeed");
		}
	}
}

void LFListenerPoolTest::TwoAcceptorsTest()
{
	StartTrace(LFListenerPoolTest.TwoAcceptorsTest);
	const long cNumOfThreads = 3;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("TCP5010");
	lfpConfig.Append("TCP5011");
	if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to succeed; are factories present?")) {
		if (t_assert(lfp.Start(true, 1000, 10) == 0 )) {
			ProcessTwoEvents();
			lfp.RequestTermination();
			t_assertm(lfp.Join() == 0, "expected Join to succeed");
		}
	}
}

void LFListenerPoolTest::ManyAcceptorsTest()
{
	StartTrace(LeaderFollowerPoolTest.ManyAcceptorsTest);
	{
		const long cNumOfThreads = 0;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "should not allow LFPool to run without threads")) {
			t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
			t_assertm(lfp.Start(true, 1000, 10) == -1, "expected Start to fail");

		}
	}
	{
		const long cNumOfThreads = 1;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(false, 1000, 10) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
	{
		const long cNumOfThreads = 2;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(false, 1000, 10) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
	{
		const long cNumOfThreads = 3;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(false, 1000, 10) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
	{
		const long cNumOfThreads = 4;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(true, 1000, 10) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
}

bool LFListenerPoolTest::EventProcessed(Socket *socket)
{
	StartTrace(LFListenerPoolTest.EventProcessed);
	if (t_assert(socket != NULL)) {
		String request;
		(*socket->GetStream()) >> request;
		assertEqual("hallo", request);
		(*socket->GetStream()) << "HostReply" << endl;
		return true;
	}
	return false;
}

void LFListenerPoolTest::ProcessOneEvent()
{
	StartTrace(LeaderFollowerPoolTest.ProcessOneEvent);
	Connector c1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5010"]["Port"].AsLong());
	String reply1;

	if ( t_assert(c1.GetStream() != NULL) ) {
		(*c1.GetStream()) << "hallo" << endl;
		t_assert(!!(*c1.GetStream()));
		(*c1.GetStream()) >> reply1;
		t_assert(!!(*c1.GetStream()));

		assertEqual("HostReply", reply1);
	}
}

void LFListenerPoolTest::ProcessManyEvents()
{
	StartTrace(LeaderFollowerPoolTest.ProcessManyEvents);
	Connector c1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5010"]["Port"].AsLong());
	Connector c2(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5011"]["Port"].AsLong());
	Connector c3(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5012"]["Port"].AsLong());
	String reply1;
	String reply2;
	String reply3;

	if (t_assert(c1.GetStream() != NULL) && t_assert(c2.GetStream() != NULL) && t_assert(c3.GetStream() != NULL)) {
		(*c1.GetStream()) << "hallo" << endl;
		(*c2.GetStream()) << "hallo" << endl;
		(*c3.GetStream()) << "hallo" << endl;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));
		t_assert(!!(*c3.GetStream()));
		(*c1.GetStream()) >> reply1;
		(*c2.GetStream()) >> reply2;
		(*c3.GetStream()) >> reply3;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));
		t_assert(!!(*c3.GetStream()));

		assertEqual("HostReply", reply1);
		assertEqual("HostReply", reply2);
		assertEqual("HostReply", reply3);
	}
}

void LFListenerPoolTest::ProcessTwoEvents()
{
	StartTrace(LeaderFollowerPoolTest.ProcessTwoEvents);
	Connector c1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5010"]["Port"].AsLong());
	Connector c2(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5011"]["Port"].AsLong());
	String reply1;
	String reply2;

	if (t_assert(c1.GetStream() != NULL) && t_assert(c2.GetStream() != NULL)) {
		(*c1.GetStream()) << "hallo" << endl;
		(*c2.GetStream()) << "hallo" << endl;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));
		(*c1.GetStream()) >> reply1;
		(*c2.GetStream()) >> reply2;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));

		assertEqual("HostReply", reply1);
		assertEqual("HostReply", reply2);
	}
}

// builds up a suite of testcases, add a line for each testmethod
Test *LFListenerPoolTest::suite ()
{
	StartTrace(LFListenerPoolTest.suite);
	TestSuite *testSuite = new TestSuite;

	ADD_CASE(testSuite, LFListenerPoolTest, NoReactorTest);
	ADD_CASE(testSuite, LFListenerPoolTest, NoFactoryTest);
	ADD_CASE(testSuite, LFListenerPoolTest, OneAcceptorTest);
	ADD_CASE(testSuite, LFListenerPoolTest, TwoAcceptorsTest);
	ADD_CASE(testSuite, LFListenerPoolTest, ManyAcceptorsTest);
	ADD_CASE(testSuite, LFListenerPoolTest, InvalidAcceptorTest);
	ADD_CASE(testSuite, LFListenerPoolTest, InvalidReactorTest);

	return testSuite;
}
<commit_msg>adjusted PoolAllocator params according to real memory usage<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "LFListenerPoolTest.h"

//--- module under test --------------------------------------------------------
#include "LFListenerPool.h"

//--- test modules used --------------------------------------------------------
#include "TestSuite.h"

//--- standard modules used ----------------------------------------------------
#include "Socket.h"
#include "WPMStatHandler.h"
#include "RequestProcessor.h"

//--- TestRequestReactor ----
//:test driver for lf pool testing
class TestProcessor: public RequestProcessor
{
public:
	TestProcessor(LFListenerPoolTest *);
	~TestProcessor();
	void ProcessRequest(Context &ctx);

protected:
	LFListenerPoolTest *fTest;
};

TestProcessor::TestProcessor(LFListenerPoolTest *test)
	: RequestProcessor("TestProcessor")
	, fTest(test)
{
	StartTrace(TestProcessor.Ctor);
}

TestProcessor::~TestProcessor()
{
	StartTrace(TestProcessor.Dtor);
}

void TestProcessor::ProcessRequest(Context &ctx)
{
	StartTrace(TestProcessor.ProcessRequest);
	fTest->EventProcessed(ctx.GetSocket());
}

//---- LFListenerPoolTest ----------------------------------------------------------------
LFListenerPoolTest::LFListenerPoolTest(TString tstrName)
	: TestCaseType(tstrName)
{
	StartTrace(LFListenerPoolTest.LFListenerPoolTest);
}

LFListenerPoolTest::~LFListenerPoolTest()
{
	StartTrace(LFListenerPoolTest.Dtor);
}

void LFListenerPoolTest::setUp ()
{
	StartTrace(LFListenerPoolTest.setUp);
	t_assert(GetConfig().IsDefined("Modules"));
}

void LFListenerPoolTest::NoReactorTest()
{
	StartTrace(LFListenerPoolTest.NoReactorTest);
	LFListenerPool lfp(0);

	Trace("ip:" << GetConfig()["Testhost"]["ip"].AsString() << " : port:" << GetConfig()["Testhost"]["port"].AsLong());
	Acceptor ac1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["Testhost"]["port"].AsLong(), 5, 0);
	Anything lfpConfig;
	lfpConfig[String("Accept") << GetConfig()["Testhost"]["port"].AsString()] = (IFAObject *)&ac1;
	if ( t_assertm( !lfp.Init(2, lfpConfig, true), "no reactor is configured; init should fail")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 11) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::NoFactoryTest()
{
	StartTrace(LFListenerPoolTest.NoFactoryTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("TCP4343");
	if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to fail; no valid factory")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 11) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::InvalidAcceptorTest()
{
	StartTrace(LFListenerPoolTest.InvalidAcceptorTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("Fake");
	if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to fail; acceptor is not valid")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 11) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::InvalidReactorTest()
{
	StartTrace(LFListenerPoolTest.InvalidReactorTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(0, 0));

	Anything lfpConfig;
	lfpConfig.Append("TCP5010");
	if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to fail; reactor is not valid")) {
		t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
		t_assertm(lfp.Start(true, 1000, 11) == -1, "expected Start to fail");
	}
}

void LFListenerPoolTest::OneAcceptorTest()
{
	StartTrace(LFListenerPoolTest.OneAcceptorTest);
	const long cNumOfThreads = 2;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("TCP5010");
	if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to succeed; are factories present?")) {
		if (t_assert(lfp.Start(true, 1000, 11) == 0 )) {
			ProcessOneEvent();
			lfp.RequestTermination();
			t_assertm(lfp.Join() == 0, "expected Join to succeed");
		}
	}
}

void LFListenerPoolTest::TwoAcceptorsTest()
{
	StartTrace(LFListenerPoolTest.TwoAcceptorsTest);
	const long cNumOfThreads = 3;
	LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

	Anything lfpConfig;
	lfpConfig.Append("TCP5010");
	lfpConfig.Append("TCP5011");
	if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "expected initialization to succeed; are factories present?")) {
		if (t_assert(lfp.Start(true, 1000, 11) == 0 )) {
			ProcessTwoEvents();
			lfp.RequestTermination();
			t_assertm(lfp.Join() == 0, "expected Join to succeed");
		}
	}
}

void LFListenerPoolTest::ManyAcceptorsTest()
{
	StartTrace(LeaderFollowerPoolTest.ManyAcceptorsTest);
	{
		const long cNumOfThreads = 0;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(!lfp.Init(cNumOfThreads, lfpConfig, true), "should not allow LFPool to run without threads")) {
			t_assertm(lfp.GetPoolSize() == 0, "expected no threads in pool");
			t_assertm(lfp.Start(true, 1000, 11) == -1, "expected Start to fail");

		}
	}
	{
		const long cNumOfThreads = 1;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(false, 1000, 10) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
	{
		const long cNumOfThreads = 2;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(false, 1000, 10) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
	{
		const long cNumOfThreads = 3;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(false, 1000, 10) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
	{
		const long cNumOfThreads = 4;
		LFListenerPool lfp(new RequestReactor(new TestProcessor(this), new WPMStatHandler(cNumOfThreads)));

		Anything lfpConfig;
		lfpConfig.Append("TCP5010");
		lfpConfig.Append("TCP5011");
		lfpConfig.Append("TCP5012");

		if (t_assertm(lfp.Init(cNumOfThreads, lfpConfig, true), "some port maybe already bound")) {
			if (t_assert(lfp.Start(true, 1000, 11) == 0 )) {
				ProcessManyEvents();
				lfp.RequestTermination();
				t_assertm(lfp.Join() == 0, "expected Join to succeed");
			}
		}
	}
}

bool LFListenerPoolTest::EventProcessed(Socket *socket)
{
	StartTrace(LFListenerPoolTest.EventProcessed);
	if (t_assert(socket != NULL)) {
		String request;
		(*socket->GetStream()) >> request;
		assertEqual("hallo", request);
		(*socket->GetStream()) << "HostReply" << endl;
		return true;
	}
	return false;
}

void LFListenerPoolTest::ProcessOneEvent()
{
	StartTrace(LeaderFollowerPoolTest.ProcessOneEvent);
	Connector c1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5010"]["Port"].AsLong());
	String reply1;

	if ( t_assert(c1.GetStream() != NULL) ) {
		(*c1.GetStream()) << "hallo" << endl;
		t_assert(!!(*c1.GetStream()));
		(*c1.GetStream()) >> reply1;
		t_assert(!!(*c1.GetStream()));

		assertEqual("HostReply", reply1);
	}
}

void LFListenerPoolTest::ProcessManyEvents()
{
	StartTrace(LeaderFollowerPoolTest.ProcessManyEvents);
	Connector c1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5010"]["Port"].AsLong());
	Connector c2(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5011"]["Port"].AsLong());
	Connector c3(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5012"]["Port"].AsLong());
	String reply1;
	String reply2;
	String reply3;

	if (t_assert(c1.GetStream() != NULL) && t_assert(c2.GetStream() != NULL) && t_assert(c3.GetStream() != NULL)) {
		(*c1.GetStream()) << "hallo" << endl;
		(*c2.GetStream()) << "hallo" << endl;
		(*c3.GetStream()) << "hallo" << endl;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));
		t_assert(!!(*c3.GetStream()));
		(*c1.GetStream()) >> reply1;
		(*c2.GetStream()) >> reply2;
		(*c3.GetStream()) >> reply3;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));
		t_assert(!!(*c3.GetStream()));

		assertEqual("HostReply", reply1);
		assertEqual("HostReply", reply2);
		assertEqual("HostReply", reply3);
	}
}

void LFListenerPoolTest::ProcessTwoEvents()
{
	StartTrace(LeaderFollowerPoolTest.ProcessTwoEvents);
	Connector c1(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5010"]["Port"].AsLong());
	Connector c2(GetConfig()["Testhost"]["ip"].AsString(), GetConfig()["TCP5011"]["Port"].AsLong());
	String reply1;
	String reply2;

	if (t_assert(c1.GetStream() != NULL) && t_assert(c2.GetStream() != NULL)) {
		(*c1.GetStream()) << "hallo" << endl;
		(*c2.GetStream()) << "hallo" << endl;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));
		(*c1.GetStream()) >> reply1;
		(*c2.GetStream()) >> reply2;
		t_assert(!!(*c1.GetStream()));
		t_assert(!!(*c2.GetStream()));

		assertEqual("HostReply", reply1);
		assertEqual("HostReply", reply2);
	}
}

// builds up a suite of testcases, add a line for each testmethod
Test *LFListenerPoolTest::suite ()
{
	StartTrace(LFListenerPoolTest.suite);
	TestSuite *testSuite = new TestSuite;

	ADD_CASE(testSuite, LFListenerPoolTest, NoReactorTest);
	ADD_CASE(testSuite, LFListenerPoolTest, NoFactoryTest);
	ADD_CASE(testSuite, LFListenerPoolTest, OneAcceptorTest);
	ADD_CASE(testSuite, LFListenerPoolTest, TwoAcceptorsTest);
	ADD_CASE(testSuite, LFListenerPoolTest, ManyAcceptorsTest);
	ADD_CASE(testSuite, LFListenerPoolTest, InvalidAcceptorTest);
	ADD_CASE(testSuite, LFListenerPoolTest, InvalidReactorTest);

	return testSuite;
}
<|endoftext|>