<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkContext2D.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkContext2D.h"

#include "vtkPoints2D.h"
#include "vtkTransform2D.h"
#include "vtkContextDevice2D.h"
#include "vtkPen.h"
#include "vtkBrush.h"
#include "vtkTextProperty.h"
#include "vtkFloatArray.h"

#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"

vtkCxxRevisionMacro(vtkContext2D, "1.7");
vtkCxxSetObjectMacro(vtkContext2D, Pen, vtkPen);
vtkCxxSetObjectMacro(vtkContext2D, Brush, vtkBrush);
vtkCxxSetObjectMacro(vtkContext2D, TextProp, vtkTextProperty);
vtkCxxSetObjectMacro(vtkContext2D, Transform, vtkTransform2D);

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkContext2D);

//-----------------------------------------------------------------------------
bool vtkContext2D::Begin(vtkContextDevice2D *device)
{
  this->Device = device;
  this->Modified();
  return true;
}

//-----------------------------------------------------------------------------
bool vtkContext2D::End()
{
  this->Device->End();
  this->Device = NULL;
  this->Modified();
  return true;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawLine(float x1, float y1, float x2, float y2)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float x[] = { x1, y1, x2, y2 };

  this->ApplyPen();
  this->Device->DrawPoly(&x[0], 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawLine(float p[4])
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }

  this->ApplyPen();
  this->Device->DrawPoly(&p[0], 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawLine(vtkPoints2D *points)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  if (points->GetNumberOfPoints() < 2)
    {
    vtkErrorMacro(<< "Attempted to paint a line with <2 points.");
    return;
    }
  float *f = vtkFloatArray::SafeDownCast(points->GetData())->GetPointer(0);

  this->ApplyPen();
  this->Device->DrawPoly(f, 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoly(float *x, float *y, int n)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float *p = new float[2*n];
  for (int i = 0; i < n; ++i)
    {
    p[2*i]   = x[i];
    p[2*i+1] = y[i];
    }

  this->ApplyPen();
  this->Device->DrawPoly(p, n);
  delete[] p;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoly(vtkPoints2D *points)
{
  // Construct an array with the correct coordinate packing for OpenGL.
  int n = points->GetNumberOfPoints();
  // If the points are of type float then call OpenGL directly
  float *f = vtkFloatArray::SafeDownCast(points->GetData())->GetPointer(0);
  this->DrawPoly(f, n);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoly(float *points, int n)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  if (n < 2)
    {
    vtkErrorMacro(<< "Attempted to paint a line with <2 points.");
    return;
    }

  this->ApplyPen();

  if (this->Transform)
    {
    float *p = new float[2*n];
    this->Transform->TransformPoints(points, &p[0], n);
    this->Device->DrawPoly(p, n);
    delete[] p;
    }
  else
    {
    this->Device->DrawPoly(points, n);
    }
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoint(float x, float y)
{
  float p[] = { x, y };
  this->DrawPoints(&p[0], 1);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoints(float *x, float *y, int n)
{
  // Copy the points into an array and draw it.
  float *p = new float[2*n];
  for (int i = 0; i < n; ++i)
    {
    p[2*i]   = x[i];
    p[2*i+1] = y[i];
    }
  this->DrawPoints(&p[0], n);
  delete[] p;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoints(vtkPoints2D *points)
{
  // Construct an array with the correct coordinate packing for OpenGL.
  int n = points->GetNumberOfPoints();
  // If the points are of type float then call OpenGL directly
  float *f = vtkFloatArray::SafeDownCast(points->GetData())->GetPointer(0);
  this->DrawPoints(f, n);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoints(float *points, int n)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }

  this->ApplyPen();
  if (this->Transform)
    {
    float *p = new float[2*n];
    this->Transform->TransformPoints(points, &p[0], n);
    this->Device->DrawPoints(p, n);
    delete[] p;
    }
  else
    {
    this->Device->DrawPoints(points, n);
    }
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawRect(float x1, float y1, float x2, float y2)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float p[] = { x1,    y1,
                x1+x2, y1,
                x1+x2, y1+y2,
                x1,    y1+y2,
                x1,    y1};
  if (this->Transform)
    {
    this->Transform->TransformPoints(&p[0], &p[0], 5);
    }

  // Draw the filled area of the rectangle.
  this->ApplyBrush();
  this->Device->DrawQuad(&p[0], 4);

  // Draw the outline now.
  this->ApplyPen();
  this->Device->DrawPoly(&p[0], 5);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawQuad(float x1, float y1, float x2, float y2,
                            float x3, float y3, float x4, float y4)
{
  float p[] = { x1, y1, x2, y2, x3, y3, x4, y4 };
  this->DrawQuad(&p[0]);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawQuad(float *p)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }

  // Draw the filled area of the quad.
  this->ApplyBrush();
  this->Device->DrawQuad(p, 4);

  // Draw the outline now.
  this->ApplyPen();
  this->Device->DrawPoly(p, 4);
  float closeLine[] = { p[0], p[1], p[6], p[7] };
  this->Device->DrawPoly(&closeLine[0], 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawEllipse(float x, float y, float rx, float ry)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  // Raterize an ellipse
  int iterations = 100;
  float *p = new float[2*(iterations+1)];
  float length = 2.0 * 3.14159265 / iterations;
  for (int i = 0; i <= iterations; ++i)
    {
    p[2*i  ] = rx * cos(i * length) + x;
    p[2*i+1] = ry * sin(i * length) + y;
    }
  this->ApplyPen();
  this->Device->DrawPoly(p, iterations + 1);
  delete[] p;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(vtkPoints2D *point, const vtkStdString &string)
{
  float *f = vtkFloatArray::SafeDownCast(point->GetData())->GetPointer(0);
  this->DrawString(f[0], f[1], string);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(float x, float y, const vtkStdString &string)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float f[] = { x, y };
  if (this->Transform)
    {
    this->Transform->TransformPoints(&f[0], &f[0], 1);
    }
  this->Device->DrawString(&f[0], this->TextProp, string);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(vtkPoints2D *point, const char *string)
{
  float *f = vtkFloatArray::SafeDownCast(point->GetData())->GetPointer(0);
  vtkStdString str = string;
  this->DrawString(f[0], f[1], str);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(float x, float y, const char *string)
{
  vtkStdString str = string;
  this->DrawString(x, y, str);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawImage(float x, float y, vtkImageData *image)
{
  float p[] = { x, y };
  if (this->Transform)
    {
    this->Transform->TransformPoints(&p[0], &p[0], 1);
    }
  this->Device->DrawImage(&p[0], 1, image);
}

//-----------------------------------------------------------------------------
unsigned int vtkContext2D::AddPointSprite(vtkImageData *image)
{
  this->Device->AddPointSprite(image);
  return 0;
}

//-----------------------------------------------------------------------------
inline void vtkContext2D::ApplyPen()
{
  this->Device->SetColor4(this->Pen->GetColor());
  this->Device->SetLineWidth(this->Pen->GetWidth());
  this->Device->SetPointSize(this->Pen->GetWidth());
}

//-----------------------------------------------------------------------------
inline void vtkContext2D::ApplyBrush()
{
  this->Device->SetColor4(this->Brush->GetColor());
}

//-----------------------------------------------------------------------------
vtkContext2D::vtkContext2D()
{
  this->Device = NULL;
  this->Pen = vtkPen::New();
  this->Brush = vtkBrush::New();
  this->TextProp = vtkTextProperty::New();
  this->Transform = NULL;
}

//-----------------------------------------------------------------------------
vtkContext2D::~vtkContext2D()
{
  this->Pen->Delete();
  this->Pen = 0;
  this->Brush->Delete();
  this->Brush = 0;
  this->TextProp->Delete();
  this->TextProp = 0;
  if (this->Device)
    {
    this->Device->Delete();
    this->Device = NULL;
    }
}

//-----------------------------------------------------------------------------
void vtkContext2D::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Context Device: ";
  if (this->Device)
    {
    os << endl;
    this->Device->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)" << endl;
    }
  os << indent << "Pen: ";
  this->Pen->PrintSelf(os, indent.GetNextIndent());
  os << indent << "Brush: ";
  this->Brush->PrintSelf(os, indent.GetNextIndent());
}

<commit_msg>BUG: Improved the reference counting on the ContextDevice2D pointer.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkContext2D.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkContext2D.h"

#include "vtkPoints2D.h"
#include "vtkTransform2D.h"
#include "vtkContextDevice2D.h"
#include "vtkPen.h"
#include "vtkBrush.h"
#include "vtkTextProperty.h"
#include "vtkFloatArray.h"

#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"

vtkCxxRevisionMacro(vtkContext2D, "1.8");
vtkCxxSetObjectMacro(vtkContext2D, Pen, vtkPen);
vtkCxxSetObjectMacro(vtkContext2D, Brush, vtkBrush);
vtkCxxSetObjectMacro(vtkContext2D, TextProp, vtkTextProperty);
vtkCxxSetObjectMacro(vtkContext2D, Transform, vtkTransform2D);

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkContext2D);

//-----------------------------------------------------------------------------
bool vtkContext2D::Begin(vtkContextDevice2D *device)
{
  if (this->Device)
    {
    this->Device->Delete();
    }
  this->Device = device;
  this->Device->Register(this);
  this->Modified();
  return true;
}

//-----------------------------------------------------------------------------
bool vtkContext2D::End()
{
  this->Device->End();
  this->Device->Delete();
  this->Device = NULL;
  this->Modified();
  return true;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawLine(float x1, float y1, float x2, float y2)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float x[] = { x1, y1, x2, y2 };

  this->ApplyPen();
  this->Device->DrawPoly(&x[0], 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawLine(float p[4])
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }

  this->ApplyPen();
  this->Device->DrawPoly(&p[0], 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawLine(vtkPoints2D *points)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  if (points->GetNumberOfPoints() < 2)
    {
    vtkErrorMacro(<< "Attempted to paint a line with <2 points.");
    return;
    }
  float *f = vtkFloatArray::SafeDownCast(points->GetData())->GetPointer(0);

  this->ApplyPen();
  this->Device->DrawPoly(f, 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoly(float *x, float *y, int n)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float *p = new float[2*n];
  for (int i = 0; i < n; ++i)
    {
    p[2*i]   = x[i];
    p[2*i+1] = y[i];
    }

  this->ApplyPen();
  this->Device->DrawPoly(p, n);
  delete[] p;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoly(vtkPoints2D *points)
{
  // Construct an array with the correct coordinate packing for OpenGL.
  int n = points->GetNumberOfPoints();
  // If the points are of type float then call OpenGL directly
  float *f = vtkFloatArray::SafeDownCast(points->GetData())->GetPointer(0);
  this->DrawPoly(f, n);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoly(float *points, int n)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  if (n < 2)
    {
    vtkErrorMacro(<< "Attempted to paint a line with <2 points.");
    return;
    }

  this->ApplyPen();

  if (this->Transform)
    {
    float *p = new float[2*n];
    this->Transform->TransformPoints(points, &p[0], n);
    this->Device->DrawPoly(p, n);
    delete[] p;
    }
  else
    {
    this->Device->DrawPoly(points, n);
    }
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoint(float x, float y)
{
  float p[] = { x, y };
  this->DrawPoints(&p[0], 1);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoints(float *x, float *y, int n)
{
  // Copy the points into an array and draw it.
  float *p = new float[2*n];
  for (int i = 0; i < n; ++i)
    {
    p[2*i]   = x[i];
    p[2*i+1] = y[i];
    }
  this->DrawPoints(&p[0], n);
  delete[] p;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoints(vtkPoints2D *points)
{
  // Construct an array with the correct coordinate packing for OpenGL.
  int n = points->GetNumberOfPoints();
  // If the points are of type float then call OpenGL directly
  float *f = vtkFloatArray::SafeDownCast(points->GetData())->GetPointer(0);
  this->DrawPoints(f, n);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawPoints(float *points, int n)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }

  this->ApplyPen();
  if (this->Transform)
    {
    float *p = new float[2*n];
    this->Transform->TransformPoints(points, &p[0], n);
    this->Device->DrawPoints(p, n);
    delete[] p;
    }
  else
    {
    this->Device->DrawPoints(points, n);
    }
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawRect(float x1, float y1, float x2, float y2)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float p[] = { x1,    y1,
                x1+x2, y1,
                x1+x2, y1+y2,
                x1,    y1+y2,
                x1,    y1};
  if (this->Transform)
    {
    this->Transform->TransformPoints(&p[0], &p[0], 5);
    }

  // Draw the filled area of the rectangle.
  this->ApplyBrush();
  this->Device->DrawQuad(&p[0], 4);

  // Draw the outline now.
  this->ApplyPen();
  this->Device->DrawPoly(&p[0], 5);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawQuad(float x1, float y1, float x2, float y2,
                            float x3, float y3, float x4, float y4)
{
  float p[] = { x1, y1, x2, y2, x3, y3, x4, y4 };
  this->DrawQuad(&p[0]);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawQuad(float *p)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }

  // Draw the filled area of the quad.
  this->ApplyBrush();
  this->Device->DrawQuad(p, 4);

  // Draw the outline now.
  this->ApplyPen();
  this->Device->DrawPoly(p, 4);
  float closeLine[] = { p[0], p[1], p[6], p[7] };
  this->Device->DrawPoly(&closeLine[0], 2);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawEllipse(float x, float y, float rx, float ry)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  // Raterize an ellipse
  int iterations = 100;
  float *p = new float[2*(iterations+1)];
  float length = 2.0 * 3.14159265 / iterations;
  for (int i = 0; i <= iterations; ++i)
    {
    p[2*i  ] = rx * cos(i * length) + x;
    p[2*i+1] = ry * sin(i * length) + y;
    }
  this->ApplyPen();
  this->Device->DrawPoly(p, iterations + 1);
  delete[] p;
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(vtkPoints2D *point, const vtkStdString &string)
{
  float *f = vtkFloatArray::SafeDownCast(point->GetData())->GetPointer(0);
  this->DrawString(f[0], f[1], string);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(float x, float y, const vtkStdString &string)
{
  if (!this->Device)
    {
    vtkErrorMacro(<< "Attempted to paint with no active vtkContextDevice2D.");
    return;
    }
  float f[] = { x, y };
  if (this->Transform)
    {
    this->Transform->TransformPoints(&f[0], &f[0], 1);
    }
  this->Device->DrawString(&f[0], this->TextProp, string);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(vtkPoints2D *point, const char *string)
{
  float *f = vtkFloatArray::SafeDownCast(point->GetData())->GetPointer(0);
  vtkStdString str = string;
  this->DrawString(f[0], f[1], str);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawString(float x, float y, const char *string)
{
  vtkStdString str = string;
  this->DrawString(x, y, str);
}

//-----------------------------------------------------------------------------
void vtkContext2D::DrawImage(float x, float y, vtkImageData *image)
{
  float p[] = { x, y };
  if (this->Transform)
    {
    this->Transform->TransformPoints(&p[0], &p[0], 1);
    }
  this->Device->DrawImage(&p[0], 1, image);
}

//-----------------------------------------------------------------------------
unsigned int vtkContext2D::AddPointSprite(vtkImageData *image)
{
  this->Device->AddPointSprite(image);
  return 0;
}

//-----------------------------------------------------------------------------
inline void vtkContext2D::ApplyPen()
{
  this->Device->SetColor4(this->Pen->GetColor());
  this->Device->SetLineWidth(this->Pen->GetWidth());
  this->Device->SetPointSize(this->Pen->GetWidth());
}

//-----------------------------------------------------------------------------
inline void vtkContext2D::ApplyBrush()
{
  this->Device->SetColor4(this->Brush->GetColor());
}

//-----------------------------------------------------------------------------
vtkContext2D::vtkContext2D()
{
  this->Device = NULL;
  this->Pen = vtkPen::New();
  this->Brush = vtkBrush::New();
  this->TextProp = vtkTextProperty::New();
  this->Transform = NULL;
}

//-----------------------------------------------------------------------------
vtkContext2D::~vtkContext2D()
{
  this->Pen->Delete();
  this->Pen = NULL;
  this->Brush->Delete();
  this->Brush = NULL;
  this->TextProp->Delete();
  this->TextProp = NULL;
  if (this->Device)
    {
    this->Device->Delete();
    this->Device = NULL;
    }
  if (this->Transform)
    {
    this->Transform->Delete();
    this->Transform = NULL;
    }
}

//-----------------------------------------------------------------------------
void vtkContext2D::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Context Device: ";
  if (this->Device)
    {
    os << endl;
    this->Device->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)" << endl;
    }
  os << indent << "Pen: ";
  this->Pen->PrintSelf(os, indent.GetNextIndent());
  os << indent << "Brush: ";
  this->Brush->PrintSelf(os, indent.GetNextIndent());
}

<|endoftext|>


<commit_before>/*******************************************************************************
GPU OPTIMIZED MONTE CARLO (GOMC) 2.70
Copyright (C) 2018  GOMC Group
A copy of the GNU General Public License can be found in the COPYRIGHT.txt
along with this program, also can be found at <http://www.gnu.org/licenses/>.
********************************************************************************/
#include "MoleculeLookup.h" //Header spec.
#include "EnsemblePreprocessor.h" //For box total
#include "PRNG.h" //For index selection
#include "PDBSetup.h" //For init.
#include "Molecules.h" //For init.
#include <algorithm>
#include <utility>
#include <iostream>
#ifdef GOMC_CUDA
#include <cuda.h>
#include <cuda_runtime.h>
#include "CUDAMemoryManager.cuh"
#include "VariablesCUDA.cuh"
#endif

void MoleculeLookup::Init(const Molecules& mols,
                          const pdb_setup::Atoms& atomData,
                          Forcefield &ff)
{
  numKinds = mols.GetKindsCount();
  molLookup.resize(mols.count);
  molLookupCount = mols.count;
  // beta has same size as total number of atoms
  molIndex.resize(atomData.beta.size());
  atomIndex.resize(atomData.beta.size());
  molKind.resize(atomData.beta.size());
  atomKind.resize(atomData.beta.size());
  atomCharge.resize(atomData.beta.size());

  //+1 to store end value
  boxAndKindStart.resize(numKinds * BOX_TOTAL + 1);
  boxAndKindSwappableCounts.resize(numKinds * BOX_TOTAL);

  boxAndKindStartCount = numKinds * BOX_TOTAL + 1;

  // vector[box][kind] = list of mol indices for kind in box
  std::vector<std::vector<std::vector<uint> > > indexVector;
  indexVector.resize(BOX_TOTAL);
  fixedMolecule.resize(mols.count);

  for (int i = 0; i < (int) numKinds * BOX_TOTAL; i++){
    boxAndKindSwappableCounts[i] = 0;
  }

  for (uint b = 0; b < BOX_TOTAL; ++b) {
    indexVector[b].resize(numKinds);
  }

  int counter = 0;
  for(uint m = 0; m < mols.count; ++m) {
    uint box = atomData.box[mols.start[m]];
    uint kind = mols.kIndex[m];
    indexVector[box][kind].push_back(m);
    const MoleculeKind& mk = mols.GetKind(m);
    for(uint a = 0; a < mk.NumAtoms(); ++a) {
      molIndex[counter] = int(m);
      atomIndex[counter] = int(a);
      molKind[counter] = int(kind);
      atomKind[counter] = int(mk.AtomKind(a));
      atomCharge[counter] = mk.AtomCharge(a);
      ++counter;
    }

    /* We don't currently support hybrid molecules - part fixed part flexible
      so we get a consensus based on the precendent of betas defined in this method */
    uint pStart = 0, pEnd = 0;
    mols.GetRangeStartStop(pStart, pEnd, m);
    fixedMolecule[m] = GetConsensusMolBeta(pStart, pEnd, atomData.beta, m, box, mols.kinds[mols.kIndex[m]].name);

    //Find the kind that can be swap(beta == 0) or move(beta == 0 or 2)
    if(fixedMolecule[m] == 0) {
      if(std::find(canSwapKind.begin(), canSwapKind.end(), kind) ==
          canSwapKind.end())
        canSwapKind.push_back(kind);

      if(std::find(canMoveKind.begin(), canMoveKind.end(), kind) ==
          canMoveKind.end())
        canMoveKind.push_back(kind);

      boxAndKindSwappableCounts[box * numKinds + kind]++;

    } else if(fixedMolecule[m] == 2) {
      if(std::find(canMoveKind.begin(), canMoveKind.end(), kind) ==
          canMoveKind.end())
        canMoveKind.push_back(kind);

    }
  }

  uint* progress = &molLookup[0];
  for (uint b = 0; b < BOX_TOTAL; ++b) {
    for (uint k = 0; k < numKinds; ++k) {
      boxAndKindStart[b * numKinds + k] = progress - &molLookup[0];
      progress = std::copy(indexVector[b][k].begin(),
                           indexVector[b][k].end(), progress);
    }
  }

  boxAndKindStart[numKinds * BOX_TOTAL] = mols.count;

// allocate and set gpu variables
#ifdef GOMC_CUDA
  VariablesCUDA *cudaVars = ff.particles->getCUDAVars();
  int numMol = mols.count + 1;
  // allocate memory to store molecule start atom index
  CUMALLOC((void**) &cudaVars->gpu_startAtomIdx, numMol * sizeof(int));
  // copy start atom index
  cudaMemcpy(cudaVars->gpu_startAtomIdx, mols.start, numMol * sizeof(int), cudaMemcpyHostToDevice);
#endif

}

uint MoleculeLookup::NumInBox(const uint box) const
{
  return boxAndKindStart[(box + 1) * numKinds]
         - boxAndKindStart[box * numKinds];
}

void MoleculeLookup::TotalAndDensity
(uint * numByBox, uint * numByKindBox, double * molFractionByKindBox,
 double * densityByKindBox, double const*const volInv) const
{
  for (uint b = 0; b < BOX_TOTAL; ++b) {
    numByBox[b] = 0.0;
    for (uint k = 0; k < numKinds; ++k) {
      uint numMK = NumKindInBox(k, b);
      uint mkIdx = k + numKinds * b;
      numByKindBox[mkIdx] = numMK;
      densityByKindBox[mkIdx] = numMK * volInv[b];
      numByBox[b] += numMK;
    }

    //Calculate mol fractions
    if (numKinds > 1) {
      for (uint k = 0; k < numKinds; ++k) {
        uint mkIdx = k + numKinds * b;
        if (numByBox[b] > 0) {
          molFractionByKindBox[mkIdx] = (double)numByKindBox[mkIdx] /
                                        (double)numByBox[b];
        } else {
          molFractionByKindBox[mkIdx] = 0.0;
        }
      }
    }

  }

}

#ifdef VARIABLE_PARTICLE_NUMBER

bool MoleculeLookup::ShiftMolBox(const uint mol, const uint currentBox,
                                 const uint intoBox, const uint kind)
{
  uint index = std::find(
                 molLookup.begin() + boxAndKindStart[currentBox * numKinds + kind],
                 molLookup.begin() + boxAndKindStart[currentBox * numKinds + kind + 1], mol)
               - molLookup.begin();
  assert(index != boxAndKindStart[currentBox * numKinds + kind + 1]);
  assert(molLookup[index] == mol);
  Shift(index, currentBox, intoBox, kind);
  return true;
}

void MoleculeLookup::Shift(const uint index, const uint currentBox,
                           const uint intoBox, const uint kind)
{
  uint oldIndex = index;
  uint newIndex;
  uint section = currentBox * numKinds + kind;

  boxAndKindSwappableCounts[section]--;
  boxAndKindSwappableCounts[intoBox * numKinds + kind]++;

  if(currentBox >= intoBox) {
    while (section != intoBox * numKinds + kind) {
      newIndex = boxAndKindStart[section]++;
      std::swap(molLookup[oldIndex], molLookup[newIndex]);
      std::swap(oldIndex, newIndex);
      --section;
    }
  } else {
    while (section != intoBox * numKinds + kind) {
      newIndex = --boxAndKindStart[++section];
      std::swap(molLookup[oldIndex], molLookup[newIndex]);
      std::swap(oldIndex, newIndex);
    }
  }
}

#endif /*ifdef VARIABLE_PARTICLE_NUMBER*/

uint MoleculeLookup::GetConsensusMolBeta( const uint pStart,
                                          const uint pEnd,
                                          const std::vector<double> & betas,
                                          const uint m,
                                          const uint box,
                                          const std::string & name){
  double firstBeta = 0.0;
  double consensusBeta = 0.0;
  for (uint p = pStart; p < pEnd; ++p) {
    if (p == pStart){
      firstBeta = betas[p];
      consensusBeta = firstBeta;
    }
    if (firstBeta != betas[p]){
      std::cout <<
      "\nWarning: Conflict between the beta values of atoms in the same molecule" <<
      "\nName : " << name <<
      "\nMol Index : " << m <<
      "\nConflicting Indices" <<
      "\nStarting Index : " << pStart <<
      "\nConflicting Index : " << p  << std::endl;
      /* A beta == 1 functions like multiplying any number  by 0,
        even if there is only 1 atom with beta == 1,
        the entire molecule will be fixed */
      if (firstBeta == 1.0 || betas[p] == 1.0){
        std::cout << "Beta == 1.0 takes precedent, so " <<
        "\nName : " << name <<
        "\nMol Index : " << m <<
        "\nis fixed in place."  << std::endl;
        consensusBeta = 1.0;
        break;
      } else {
        std::cout << "Beta == 2.0 takes precedent, so " <<
        "\nName: " << name <<
        "\nMol Index: " << m <<
        "\nis fixed in box " << box << std::endl;
        consensusBeta = 2.0;
      }
    }
  }
  return (uint)consensusBeta;
}

MoleculeLookup::box_iterator MoleculeLookup::box_iterator::operator++(int)
{
  box_iterator tmp = *this;
  ++(*this);
  return tmp;
}

MoleculeLookup::box_iterator::box_iterator(const uint* _pLook, const uint* _pSec)
  : pIt(_pLook + * _pSec) {}

MoleculeLookup::box_iterator MoleculeLookup::BoxBegin(const uint box) const
{
  return box_iterator(&molLookup[0], &boxAndKindStart[box * numKinds]);
}

MoleculeLookup::box_iterator MoleculeLookup::BoxEnd(const uint box) const
{
  return box_iterator(&molLookup[0], &boxAndKindStart[(box + 1)* numKinds]);
}

MoleculeLookup& MoleculeLookup::operator=(const MoleculeLookup & rhs){
  molLookup = rhs.molLookup;
  molLookupCount = rhs.molLookupCount;
  //index [BOX_TOTAL * kind + box] is the first element of that kind/box in
  //molLookup
  //index [BOX_TOTAL * kind + box + 1] is the element after the end
  //of that kind/box
  boxAndKindStart = rhs.boxAndKindStart;
  boxAndKindSwappableCounts = rhs.boxAndKindSwappableCounts;
  boxAndKindStartCount = rhs.boxAndKindStartCount;
  numKinds = rhs.numKinds;
  fixedMolecule = rhs.fixedMolecule;
  canSwapKind = rhs.canSwapKind; //Kinds that can move intra and inter box
  canMoveKind = rhs.canMoveKind; //Kinds that can move intra box only
  molIndex = rhs.molIndex; // stores the molecule index for global atom index
  atomIndex = rhs.atomIndex; // stores the local atom index for global atom index
  molKind = rhs.molKind; // stores the molecule kind for global atom index
  atomKind = rhs.atomKind; // stores the atom kind for global atom index
  atomCharge = rhs.atomCharge; // stores the atom's charge for global atom index

  /* For consistent trajectory ordering across checkpoints */
  restartMoleculeIndices = rhs.restartMoleculeIndices;
  for (int b = 0; b < BOX_TOTAL; ++b)
    restartedNumAtomsInBox[b] = rhs.restartedNumAtomsInBox[b];

  return *this;

}

bool MoleculeLookup::operator==(const MoleculeLookup & rhs){
  bool result = true;

  result &= (molLookup == rhs.molLookup);
  result &= (molLookupCount == rhs.molLookupCount);
  //index [BOX_TOTAL * kind + box] is the first element of that kind/box in
  //molLookup
  //index [BOX_TOTAL * kind + box + 1] is the element after the end
  //of that kind/box
  result &= (boxAndKindStart == rhs.boxAndKindStart);
  result &= (boxAndKindSwappableCounts == rhs.boxAndKindSwappableCounts);
  result &= (boxAndKindStartCount == rhs.boxAndKindStartCount);
  result &= (numKinds == rhs.numKinds);
  result &= (fixedMolecule == rhs.fixedMolecule);
  result &= (canSwapKind == rhs.canSwapKind); //Kinds that can move intra and inter box
  result &= (canMoveKind == rhs.canMoveKind); //Kinds that can move intra box only
  result &= (molIndex == rhs.molIndex); // stores the molecule index for global atom index
  result &= (atomIndex == rhs.atomIndex); // stores the local atom index for global atom index
  result &= (molKind == rhs.molKind); // stores the molecule kind for global atom index
  result &= (atomKind == rhs.atomKind); // stores the atom kind for global atom index
  result &= (atomCharge == rhs.atomCharge); // stores the atom's charge for global atom index

  /* For consistent trajectory ordering across checkpoints
  result &= (restartMoleculeIndices == rhs.restartMoleculeIndices);
  for (int b = 0; b < BOX_TOTAL; ++b)
    result &= (restartedNumAtomsInBox[b] == rhs.restartedNumAtomsInBox[b]);
  */
  return result;

}

void MoleculeLookup::swap(MoleculeLookup& oldMolLookup, MoleculeLookup& newMolLookup)
{
  using std::swap;
  swap(oldMolLookup.atomCharge, newMolLookup.atomCharge);
  swap(oldMolLookup.atomIndex, newMolLookup.atomIndex);
  swap(oldMolLookup.atomKind, newMolLookup.atomKind);
  swap(oldMolLookup.boxAndKindStart, newMolLookup.boxAndKindStart);
  swap(oldMolLookup.boxAndKindStartCount, newMolLookup.boxAndKindStartCount);
  swap(oldMolLookup.boxAndKindSwappableCounts, newMolLookup.boxAndKindSwappableCounts);
  swap(oldMolLookup.canMoveKind, newMolLookup.canMoveKind);
  swap(oldMolLookup.canSwapKind, newMolLookup.canSwapKind);
  swap(oldMolLookup.fixedMolecule, newMolLookup.fixedMolecule);
  swap(oldMolLookup.molIndex, newMolLookup.molIndex);
  swap(oldMolLookup.molKind, newMolLookup.molKind);
  swap(oldMolLookup.molLookup, newMolLookup.molLookup);
  swap(oldMolLookup.molLookupCount, newMolLookup.molLookupCount);
  swap(oldMolLookup.numKinds, newMolLookup.numKinds);
    /* For consistent trajectory ordering across checkpoints */
  swap(oldMolLookup.restartMoleculeIndices, newMolLookup.restartMoleculeIndices);
  for (int b = 0; b < BOX_TOTAL; ++b)
    swap(oldMolLookup.restartedNumAtomsInBox[b], newMolLookup.restartedNumAtomsInBox[b]);
}<commit_msg>added restart vects to assignment operator of mollook<commit_after>/*******************************************************************************
GPU OPTIMIZED MONTE CARLO (GOMC) 2.70
Copyright (C) 2018  GOMC Group
A copy of the GNU General Public License can be found in the COPYRIGHT.txt
along with this program, also can be found at <http://www.gnu.org/licenses/>.
********************************************************************************/
#include "MoleculeLookup.h" //Header spec.
#include "EnsemblePreprocessor.h" //For box total
#include "PRNG.h" //For index selection
#include "PDBSetup.h" //For init.
#include "Molecules.h" //For init.
#include <algorithm>
#include <utility>
#include <iostream>
#ifdef GOMC_CUDA
#include <cuda.h>
#include <cuda_runtime.h>
#include "CUDAMemoryManager.cuh"
#include "VariablesCUDA.cuh"
#endif

void MoleculeLookup::Init(const Molecules& mols,
                          const pdb_setup::Atoms& atomData,
                          Forcefield &ff)
{
  numKinds = mols.GetKindsCount();
  molLookup.resize(mols.count);
  molLookupCount = mols.count;
  // beta has same size as total number of atoms
  molIndex.resize(atomData.beta.size());
  atomIndex.resize(atomData.beta.size());
  molKind.resize(atomData.beta.size());
  atomKind.resize(atomData.beta.size());
  atomCharge.resize(atomData.beta.size());

  //+1 to store end value
  boxAndKindStart.resize(numKinds * BOX_TOTAL + 1);
  boxAndKindSwappableCounts.resize(numKinds * BOX_TOTAL);

  boxAndKindStartCount = numKinds * BOX_TOTAL + 1;

  // vector[box][kind] = list of mol indices for kind in box
  std::vector<std::vector<std::vector<uint> > > indexVector;
  indexVector.resize(BOX_TOTAL);
  fixedMolecule.resize(mols.count);

  for (int i = 0; i < (int) numKinds * BOX_TOTAL; i++){
    boxAndKindSwappableCounts[i] = 0;
  }

  for (uint b = 0; b < BOX_TOTAL; ++b) {
    indexVector[b].resize(numKinds);
  }

  int counter = 0;
  for(uint m = 0; m < mols.count; ++m) {
    uint box = atomData.box[mols.start[m]];
    uint kind = mols.kIndex[m];
    indexVector[box][kind].push_back(m);
    const MoleculeKind& mk = mols.GetKind(m);
    for(uint a = 0; a < mk.NumAtoms(); ++a) {
      molIndex[counter] = int(m);
      atomIndex[counter] = int(a);
      molKind[counter] = int(kind);
      atomKind[counter] = int(mk.AtomKind(a));
      atomCharge[counter] = mk.AtomCharge(a);
      ++counter;
    }

    /* We don't currently support hybrid molecules - part fixed part flexible
      so we get a consensus based on the precendent of betas defined in this method */
    uint pStart = 0, pEnd = 0;
    mols.GetRangeStartStop(pStart, pEnd, m);
    fixedMolecule[m] = GetConsensusMolBeta(pStart, pEnd, atomData.beta, m, box, mols.kinds[mols.kIndex[m]].name);

    //Find the kind that can be swap(beta == 0) or move(beta == 0 or 2)
    if(fixedMolecule[m] == 0) {
      if(std::find(canSwapKind.begin(), canSwapKind.end(), kind) ==
          canSwapKind.end())
        canSwapKind.push_back(kind);

      if(std::find(canMoveKind.begin(), canMoveKind.end(), kind) ==
          canMoveKind.end())
        canMoveKind.push_back(kind);

      boxAndKindSwappableCounts[box * numKinds + kind]++;

    } else if(fixedMolecule[m] == 2) {
      if(std::find(canMoveKind.begin(), canMoveKind.end(), kind) ==
          canMoveKind.end())
        canMoveKind.push_back(kind);

    }
  }

  uint* progress = &molLookup[0];
  for (uint b = 0; b < BOX_TOTAL; ++b) {
    for (uint k = 0; k < numKinds; ++k) {
      boxAndKindStart[b * numKinds + k] = progress - &molLookup[0];
      progress = std::copy(indexVector[b][k].begin(),
                           indexVector[b][k].end(), progress);
    }
  }

  boxAndKindStart[numKinds * BOX_TOTAL] = mols.count;

// allocate and set gpu variables
#ifdef GOMC_CUDA
  VariablesCUDA *cudaVars = ff.particles->getCUDAVars();
  int numMol = mols.count + 1;
  // allocate memory to store molecule start atom index
  CUMALLOC((void**) &cudaVars->gpu_startAtomIdx, numMol * sizeof(int));
  // copy start atom index
  cudaMemcpy(cudaVars->gpu_startAtomIdx, mols.start, numMol * sizeof(int), cudaMemcpyHostToDevice);
#endif

}

uint MoleculeLookup::NumInBox(const uint box) const
{
  return boxAndKindStart[(box + 1) * numKinds]
         - boxAndKindStart[box * numKinds];
}

void MoleculeLookup::TotalAndDensity
(uint * numByBox, uint * numByKindBox, double * molFractionByKindBox,
 double * densityByKindBox, double const*const volInv) const
{
  for (uint b = 0; b < BOX_TOTAL; ++b) {
    numByBox[b] = 0.0;
    for (uint k = 0; k < numKinds; ++k) {
      uint numMK = NumKindInBox(k, b);
      uint mkIdx = k + numKinds * b;
      numByKindBox[mkIdx] = numMK;
      densityByKindBox[mkIdx] = numMK * volInv[b];
      numByBox[b] += numMK;
    }

    //Calculate mol fractions
    if (numKinds > 1) {
      for (uint k = 0; k < numKinds; ++k) {
        uint mkIdx = k + numKinds * b;
        if (numByBox[b] > 0) {
          molFractionByKindBox[mkIdx] = (double)numByKindBox[mkIdx] /
                                        (double)numByBox[b];
        } else {
          molFractionByKindBox[mkIdx] = 0.0;
        }
      }
    }

  }

}

#ifdef VARIABLE_PARTICLE_NUMBER

bool MoleculeLookup::ShiftMolBox(const uint mol, const uint currentBox,
                                 const uint intoBox, const uint kind)
{
  uint index = std::find(
                 molLookup.begin() + boxAndKindStart[currentBox * numKinds + kind],
                 molLookup.begin() + boxAndKindStart[currentBox * numKinds + kind + 1], mol)
               - molLookup.begin();
  assert(index != boxAndKindStart[currentBox * numKinds + kind + 1]);
  assert(molLookup[index] == mol);
  Shift(index, currentBox, intoBox, kind);
  return true;
}

void MoleculeLookup::Shift(const uint index, const uint currentBox,
                           const uint intoBox, const uint kind)
{
  uint oldIndex = index;
  uint newIndex;
  uint section = currentBox * numKinds + kind;

  boxAndKindSwappableCounts[section]--;
  boxAndKindSwappableCounts[intoBox * numKinds + kind]++;

  if(currentBox >= intoBox) {
    while (section != intoBox * numKinds + kind) {
      newIndex = boxAndKindStart[section]++;
      std::swap(molLookup[oldIndex], molLookup[newIndex]);
      std::swap(oldIndex, newIndex);
      --section;
    }
  } else {
    while (section != intoBox * numKinds + kind) {
      newIndex = --boxAndKindStart[++section];
      std::swap(molLookup[oldIndex], molLookup[newIndex]);
      std::swap(oldIndex, newIndex);
    }
  }
}

#endif /*ifdef VARIABLE_PARTICLE_NUMBER*/

uint MoleculeLookup::GetConsensusMolBeta( const uint pStart,
                                          const uint pEnd,
                                          const std::vector<double> & betas,
                                          const uint m,
                                          const uint box,
                                          const std::string & name){
  double firstBeta = 0.0;
  double consensusBeta = 0.0;
  for (uint p = pStart; p < pEnd; ++p) {
    if (p == pStart){
      firstBeta = betas[p];
      consensusBeta = firstBeta;
    }
    if (firstBeta != betas[p]){
      std::cout <<
      "\nWarning: Conflict between the beta values of atoms in the same molecule" <<
      "\nName : " << name <<
      "\nMol Index : " << m <<
      "\nConflicting Indices" <<
      "\nStarting Index : " << pStart <<
      "\nConflicting Index : " << p  << std::endl;
      /* A beta == 1 functions like multiplying any number  by 0,
        even if there is only 1 atom with beta == 1,
        the entire molecule will be fixed */
      if (firstBeta == 1.0 || betas[p] == 1.0){
        std::cout << "Beta == 1.0 takes precedent, so " <<
        "\nName : " << name <<
        "\nMol Index : " << m <<
        "\nis fixed in place."  << std::endl;
        consensusBeta = 1.0;
        break;
      } else {
        std::cout << "Beta == 2.0 takes precedent, so " <<
        "\nName: " << name <<
        "\nMol Index: " << m <<
        "\nis fixed in box " << box << std::endl;
        consensusBeta = 2.0;
      }
    }
  }
  return (uint)consensusBeta;
}

MoleculeLookup::box_iterator MoleculeLookup::box_iterator::operator++(int)
{
  box_iterator tmp = *this;
  ++(*this);
  return tmp;
}

MoleculeLookup::box_iterator::box_iterator(const uint* _pLook, const uint* _pSec)
  : pIt(_pLook + * _pSec) {}

MoleculeLookup::box_iterator MoleculeLookup::BoxBegin(const uint box) const
{
  return box_iterator(&molLookup[0], &boxAndKindStart[box * numKinds]);
}

MoleculeLookup::box_iterator MoleculeLookup::BoxEnd(const uint box) const
{
  return box_iterator(&molLookup[0], &boxAndKindStart[(box + 1)* numKinds]);
}

MoleculeLookup& MoleculeLookup::operator=(const MoleculeLookup & rhs){
  molLookup = rhs.molLookup;
  molLookupCount = rhs.molLookupCount;
  //index [BOX_TOTAL * kind + box] is the first element of that kind/box in
  //molLookup
  //index [BOX_TOTAL * kind + box + 1] is the element after the end
  //of that kind/box
  boxAndKindStart = rhs.boxAndKindStart;
  boxAndKindSwappableCounts = rhs.boxAndKindSwappableCounts;
  boxAndKindStartCount = rhs.boxAndKindStartCount;
  numKinds = rhs.numKinds;
  fixedMolecule = rhs.fixedMolecule;
  canSwapKind = rhs.canSwapKind; //Kinds that can move intra and inter box
  canMoveKind = rhs.canMoveKind; //Kinds that can move intra box only
  molIndex = rhs.molIndex; // stores the molecule index for global atom index
  atomIndex = rhs.atomIndex; // stores the local atom index for global atom index
  molKind = rhs.molKind; // stores the molecule kind for global atom index
  atomKind = rhs.atomKind; // stores the atom kind for global atom index
  atomCharge = rhs.atomCharge; // stores the atom's charge for global atom index

  /* For consistent trajectory ordering across checkpoints */
  restartMoleculeIndices = rhs.restartMoleculeIndices;
  for (int b = 0; b < BOX_TOTAL; ++b)
    restartedNumAtomsInBox[b] = rhs.restartedNumAtomsInBox[b];

  return *this;

}

bool MoleculeLookup::operator==(const MoleculeLookup & rhs){
  bool result = true;

  result &= (molLookup == rhs.molLookup);
  result &= (molLookupCount == rhs.molLookupCount);
  //index [BOX_TOTAL * kind + box] is the first element of that kind/box in
  //molLookup
  //index [BOX_TOTAL * kind + box + 1] is the element after the end
  //of that kind/box
  result &= (boxAndKindStart == rhs.boxAndKindStart);
  result &= (boxAndKindSwappableCounts == rhs.boxAndKindSwappableCounts);
  result &= (boxAndKindStartCount == rhs.boxAndKindStartCount);
  result &= (numKinds == rhs.numKinds);
  result &= (fixedMolecule == rhs.fixedMolecule);
  result &= (canSwapKind == rhs.canSwapKind); //Kinds that can move intra and inter box
  result &= (canMoveKind == rhs.canMoveKind); //Kinds that can move intra box only
  result &= (molIndex == rhs.molIndex); // stores the molecule index for global atom index
  result &= (atomIndex == rhs.atomIndex); // stores the local atom index for global atom index
  result &= (molKind == rhs.molKind); // stores the molecule kind for global atom index
  result &= (atomKind == rhs.atomKind); // stores the atom kind for global atom index
  result &= (atomCharge == rhs.atomCharge); // stores the atom's charge for global atom index

  /* For consistent trajectory ordering across checkpoints
  result &= (restartMoleculeIndices == rhs.restartMoleculeIndices);
  for (int b = 0; b < BOX_TOTAL; ++b)
    result &= (restartedNumAtomsInBox[b] == rhs.restartedNumAtomsInBox[b]);
  */
  return result;

}

void MoleculeLookup::swap(MoleculeLookup& oldMolLookup, MoleculeLookup& newMolLookup)
{
  using std::swap;
  swap(oldMolLookup.atomCharge, newMolLookup.atomCharge);
  swap(oldMolLookup.atomIndex, newMolLookup.atomIndex);
  swap(oldMolLookup.atomKind, newMolLookup.atomKind);
  swap(oldMolLookup.boxAndKindStart, newMolLookup.boxAndKindStart);
  swap(oldMolLookup.boxAndKindStartCount, newMolLookup.boxAndKindStartCount);
  swap(oldMolLookup.boxAndKindSwappableCounts, newMolLookup.boxAndKindSwappableCounts);
  swap(oldMolLookup.canMoveKind, newMolLookup.canMoveKind);
  swap(oldMolLookup.canSwapKind, newMolLookup.canSwapKind);
  swap(oldMolLookup.fixedMolecule, newMolLookup.fixedMolecule);
  swap(oldMolLookup.molIndex, newMolLookup.molIndex);
  swap(oldMolLookup.molKind, newMolLookup.molKind);
  swap(oldMolLookup.molLookup, newMolLookup.molLookup);
  swap(oldMolLookup.molLookupCount, newMolLookup.molLookupCount);
  swap(oldMolLookup.numKinds, newMolLookup.numKinds);
    /* For consistent trajectory ordering across checkpoints */
  swap(oldMolLookup.restartMoleculeIndices, newMolLookup.restartMoleculeIndices);
  for (int b = 0; b < BOX_TOTAL; ++b)
    swap(oldMolLookup.restartedNumAtomsInBox[b], newMolLookup.restartedNumAtomsInBox[b]);
}
<|endoftext|>


<commit_before>#include "MqClientThread.h"

MqClientThread::MqClientThread (const char *name, QObject *parent)
: QThread(parent)
, mosquittopp(name)
, bQuit(false)
, strHost ("localhost")
, strTopic ("gv_notify")
{
}//MqClientThread::MqClientThread

void
MqClientThread::on_connect (int rc)
{
    if (0 != rc) {
        qWarning() << "Mosquitto: Failed in on_connect. Error =" << rc;
        return;
    }
    qDebug() << "Mosquitto: Connected to" << strHost;

    rc = this->subscribe (NULL, strTopic.toLatin1().constData ());
    if (0 != rc) {
        qWarning() << "Mosquitto: Failed in subscribe. Error =" << rc;
        emit status ("Failed to subscribe to Mosquitto server");
        return;
    }
    qDebug() << "Mosquitto: Subscribed to" << strTopic << "established.";
}//MqClientThread::on_connect

void
MqClientThread::on_message (const struct mosquitto_message *message)
{
    if (0 == message->payloadlen) {
        qDebug("Mosquitto: No payload!");
        return;
    }

    QString strPayload = (char*)message->payload;
    qDebug() << "Mosquitto: topic = " << message->topic
             << ". message = " << strPayload;

    if (strPayload.startsWith ("inbox")) {
        emit status ("Mosquitto: New inbox entry");
        emit sigUpdateInbox();
    }
    if (strPayload.startsWith ("contact")) {
        emit status ("Mosquitto: Contact changes");
        emit sigUpdateContacts ();
    }
}//MqClientThread::on_message

void
MqClientThread::run ()
{
    qDebug ("Mosquitto: Enter thread loop");

    do { // Begin cleanup block (not a loop)
        if (strHost.length () == 0) {
            qWarning ("Mosquitto: Invalid Host");
            break;
        }

        QHostInfo hInfo = QHostInfo::fromName (strHost);
        QString strFirst = hInfo.addresses().first().toString();

        qDebug() << "Mosquitto: Attempting to connect to" << strHost
                 << "at" << strFirst;
        int rv = ((mosquittopp*)this)->connect (strFirst.toLatin1().constData ());
        if (0 != rv) {
            qWarning() << "Mosquitto: Failed to connect. Error =" << rv;
            emit status ("Failed to connect to Mosquitto server");
            break;
        }

        while (!bQuit) {
            qDebug ("Mosquitto: Working the Mq loop");
            this->loop (1*1000);
        }

        qDebug ("Mosquitto: End Mq loop. Unsubscribe and disconnect");
        this->unsubscribe(NULL, strTopic.toLatin1().constData ());
        ((mosquittopp*)this)->disconnect ();
        this->loop (100);
    } while (0); // End cleanup block (not a loop)

    // Ready for the next time
    bQuit = false;
    qDebug ("Mosquitto: Exit thread loop");
}//MqClientThread::run

void
MqClientThread::setSettings (bool bEnable, const QString &host, int p,
                             const QString &topic)
{
    if (bEnable) {
        strHost = host;
        if (0 == p) {
            p = 1883;
        }
        port = p;
        strTopic = topic;
    } else {
        strHost.clear ();
        port = 0;
        strTopic.clear ();
    }
}//MqClientThread::setSettings

void
MqClientThread::setUserPass (const QString &user, const QString &pass)
{
    strUser = user;
    strPass = pass;
    int rv =
    this->username_pw_set(strUser.toLatin1().constData (),
                          strPass.toLatin1().constData ());
    if (0 != rv) {
        qWarning() << "Mosquitto: Failed to set user and pass. Error =" << rv;
    }
}//MqClientThread::setUserPass

void
MqClientThread::setQuit (bool set)
{
    bQuit = set;
    qDebug() << "Mosquitto: quit = " << (bQuit?"True":"False");
}//MqClientThread::setQuit
<commit_msg>dont display crap every second<commit_after>#include "MqClientThread.h"

MqClientThread::MqClientThread (const char *name, QObject *parent)
: QThread(parent)
, mosquittopp(name)
, bQuit(false)
, strHost ("localhost")
, strTopic ("gv_notify")
{
}//MqClientThread::MqClientThread

void
MqClientThread::on_connect (int rc)
{
    if (0 != rc) {
        qWarning() << "Mosquitto: Failed in on_connect. Error =" << rc;
        return;
    }
    qDebug() << "Mosquitto: Connected to" << strHost;

    rc = this->subscribe (NULL, strTopic.toLatin1().constData ());
    if (0 != rc) {
        qWarning() << "Mosquitto: Failed in subscribe. Error =" << rc;
        emit status ("Failed to subscribe to Mosquitto server");
        return;
    }
    qDebug() << "Mosquitto: Subscribed to" << strTopic << "established.";
}//MqClientThread::on_connect

void
MqClientThread::on_message (const struct mosquitto_message *message)
{
    if (0 == message->payloadlen) {
        qDebug("Mosquitto: No payload!");
        return;
    }

    QString strPayload = (char*)message->payload;
    qDebug() << "Mosquitto: topic = " << message->topic
             << ". message = " << strPayload;

    if (strPayload.startsWith ("inbox")) {
        emit status ("Mosquitto: New inbox entry");
        emit sigUpdateInbox();
    }
    if (strPayload.startsWith ("contact")) {
        emit status ("Mosquitto: Contact changes");
        emit sigUpdateContacts ();
    }
}//MqClientThread::on_message

void
MqClientThread::run ()
{
    qDebug ("Mosquitto: Enter thread loop");

    do { // Begin cleanup block (not a loop)
        if (strHost.length () == 0) {
            qWarning ("Mosquitto: Invalid Host");
            break;
        }

        QHostInfo hInfo = QHostInfo::fromName (strHost);
        QString strFirst = hInfo.addresses().first().toString();

        qDebug() << "Mosquitto: Attempting to connect to" << strHost
                 << "at" << strFirst;
        int rv = ((mosquittopp*)this)->connect (strFirst.toLatin1().constData ());
        if (0 != rv) {
            qWarning() << "Mosquitto: Failed to connect. Error =" << rv;
            emit status ("Failed to connect to Mosquitto server");
            break;
        }

        while (!bQuit) {
            this->loop (1*1000);
        }

        qDebug ("Mosquitto: End Mq loop. Unsubscribe and disconnect");
        this->unsubscribe(NULL, strTopic.toLatin1().constData ());
        ((mosquittopp*)this)->disconnect ();
        this->loop (100);
    } while (0); // End cleanup block (not a loop)

    // Ready for the next time
    bQuit = false;
    qDebug ("Mosquitto: Exit thread loop");
}//MqClientThread::run

void
MqClientThread::setSettings (bool bEnable, const QString &host, int p,
                             const QString &topic)
{
    if (bEnable) {
        strHost = host;
        if (0 == p) {
            p = 1883;
        }
        port = p;
        strTopic = topic;
    } else {
        strHost.clear ();
        port = 0;
        strTopic.clear ();
    }
}//MqClientThread::setSettings

void
MqClientThread::setUserPass (const QString &user, const QString &pass)
{
    strUser = user;
    strPass = pass;
    int rv =
    this->username_pw_set(strUser.toLatin1().constData (),
                          strPass.toLatin1().constData ());
    if (0 != rv) {
        qWarning() << "Mosquitto: Failed to set user and pass. Error =" << rv;
    }
}//MqClientThread::setUserPass

void
MqClientThread::setQuit (bool set)
{
    bQuit = set;
    qDebug() << "Mosquitto: quit = " << (bQuit?"True":"False");
}//MqClientThread::setQuit
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011, Paul Tagliamonte <tag@pault.ag>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "NcursesTerminal.hh"
#include "Shibuya.hh"

#include <iostream>
#include <malloc.h>
#include <signal.h>

NcursesTerminal::NcursesTerminal() {
	SDEBUG << "Default ncurses Constructor" << std::endl;
	this->_init_NcursesTerminal(80, 25, 0, 0);
	this->_init_ANSITerminal();
	this->_init_Terminal( 80, 25 );
}

NcursesTerminal::NcursesTerminal( int width, int height ) {
	SDEBUG << "Width / Height ncurses Constructor" << std::endl;
	this->_init_NcursesTerminal(width, height, 0, 0);
	this->_init_ANSITerminal();
	this->_init_Terminal( width, height );
}

NcursesTerminal::NcursesTerminal( int width, int height, int x, int y ) {
	SDEBUG << "Width / Height / x / y ncurses Constructor" << std::endl;
	this->_init_NcursesTerminal(width, height, x, y);
	this->_init_ANSITerminal();
	this->_init_Terminal( width, height );
}

void NcursesTerminal::_init_NcursesTerminal(
	int width, int height, int x, int y
) {
	this->pane = new Pane((width + 2), (height + 2), x, y);
	this->pane->setTitle( "Terminal ID: (1)" );
}

NcursesTerminal::~NcursesTerminal() {
	SDEBUG << "ncurses terminal destructor" << std::endl;
	delete this->pane;
}

bool NcursesTerminal::render( WINDOW * win ) {
	if ( ! this->tainted )
		return false;
	SDEBUG << "Tainted display. Rendering window" << std::endl;

	this->pane->render_frame();

	for ( int iy = 0; iy < this->height; ++iy ) {
		for ( int ix = 0; ix < this->width; ++ix ) {
			int offset = GET_OFFSET(ix, iy);

			/* By default, we'll disable everything. */
			wattroff( win, A_BOLD );

			char attrs = this->chars[offset].attr;
			if ( SHIBUYA_ATTR_HAS_BOLD(attrs) ) {
				wattron(win, A_BOLD);
			}

			mvwaddch(win, ( iy + 1 ), ( ix + 1 ),
				this->chars[offset].ch);
		}
	}

	wmove( win, this->cY + 1, this->cX + 1 );

	this->tainted = false;
	return true;
}

bool NcursesTerminal::render() {
	return this->render(this->pane->getWindow());
}

void NcursesTerminal::insert( unsigned char c ) {
	// SDEBUG << "Inserting: " << (int)c << std::endl;
	this->tainted = true;
	ANSITerminal::insert( c );
}

void NcursesTerminal::sigwinch() {
	/* XXX: Globalize this */
	SDEBUG << "Sending WINCH" << this->childpid << std::endl;
	pid_t pg = tcgetpgrp( this->pty );
	TerminalSize ts = { 0, 0, 0, 0 };
	ts.ws_row = this->height;
	ts.ws_col = this->width;
	int r = ioctl(this->pty, TIOCSWINSZ, (char *)&ts);
	/* This pseudo code taken from xterm. */
	kill( pg, SIGWINCH );
	SDEBUG << "Sent SIGWINCH to child. IO output is: " << r << std::endl;
}

void NcursesTerminal::resize( int x, int y ) {
	TerminalCell * tcTmp =
		(TerminalCell*) malloc(sizeof(TerminalCell) * (x * y));

	/* Let's do some costly allocation */

	for ( int i = 0; i < ( x * y ); ++i ) {
		tcTmp[i].ch   = ' ';
		tcTmp[i].attr = SHIBUYA_DEFAULT_CMODE;
	}

	/* And, now, let's copy over stuff in-range. */

	int resizeXMin = ( x < this->width )  ? x : this->width;
	int resizeYMin = ( y < this->height ) ? y : this->height;

	for ( int ix = 0; ix < resizeXMin; ++ix ) {
		for ( int iy = 0; iy < resizeYMin; ++iy ) {
			int hostOffset = GET_OFFSET( ix, iy );
			int nextOffset = (( y * iy ) + ix );
			tcTmp[nextOffset] = this->chars[hostOffset];
		}
	}

	free( this->chars );
	this->chars = tcTmp;
	this->width  = x;
	this->height = y;
	this->pane->resize( ( x + 2 ), (y + 2) );
	this->tainted = true;

	/* Now, let's tell the process group what's up */
	this->sigwinch();
}

void NcursesTerminal::move_to( int x, int y ) {
	this->pane->move_to( x, y );
}
<commit_msg>Fixing some resize bugs<commit_after>/*
 * Copyright (C) 2011, Paul Tagliamonte <tag@pault.ag>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "NcursesTerminal.hh"
#include "Shibuya.hh"

#include <iostream>
#include <malloc.h>
#include <signal.h>

NcursesTerminal::NcursesTerminal() {
	SDEBUG << "Default ncurses Constructor" << std::endl;
	this->_init_NcursesTerminal(80, 25, 0, 0);
	this->_init_ANSITerminal();
	this->_init_Terminal( 80, 25 );
}

NcursesTerminal::NcursesTerminal( int width, int height ) {
	SDEBUG << "Width / Height ncurses Constructor" << std::endl;
	this->_init_NcursesTerminal(width, height, 0, 0);
	this->_init_ANSITerminal();
	this->_init_Terminal( width, height );
}

NcursesTerminal::NcursesTerminal( int width, int height, int x, int y ) {
	SDEBUG << "Width / Height / x / y ncurses Constructor" << std::endl;
	this->_init_NcursesTerminal(width, height, x, y);
	this->_init_ANSITerminal();
	this->_init_Terminal( width, height );
}

void NcursesTerminal::_init_NcursesTerminal(
	int width, int height, int x, int y
) {
	this->pane = new Pane((width + 2), (height + 2), x, y);
	this->pane->setTitle( "Terminal ID: (1)" );
}

NcursesTerminal::~NcursesTerminal() {
	SDEBUG << "ncurses terminal destructor" << std::endl;
	delete this->pane;
}

bool NcursesTerminal::render( WINDOW * win ) {
	if ( ! this->tainted )
		return false;
	SDEBUG << "Tainted display. Rendering window" << std::endl;

	this->pane->render_frame();

	for ( int iy = 0; iy < this->height; ++iy ) {
		for ( int ix = 0; ix < this->width; ++ix ) {
			int offset = GET_OFFSET(ix, iy);

			/* By default, we'll disable everything. */
			wattroff( win, A_BOLD );

			char attrs = this->chars[offset].attr;
			if ( SHIBUYA_ATTR_HAS_BOLD(attrs) ) {
				wattron(win, A_BOLD);
			}

			mvwaddch(win, ( iy + 1 ), ( ix + 1 ),
				this->chars[offset].ch);
		}
	}

	wmove( win, this->cY + 1, this->cX + 1 );

	this->tainted = false;
	return true;
}

bool NcursesTerminal::render() {
	return this->render(this->pane->getWindow());
}

void NcursesTerminal::insert( unsigned char c ) {
	// SDEBUG << "Inserting: " << (int)c << std::endl;
	this->tainted = true;
	ANSITerminal::insert( c );
}

void NcursesTerminal::sigwinch() {
	/* XXX: Globalize this */
	SDEBUG << "Sending WINCH " << this->childpid << std::endl;
	pid_t pg = tcgetpgrp( this->pty );
	TerminalSize ts = { 0, 0, 0, 0 };

	ts.ws_row    = this->height;
	ts.ws_col    = this->width;
	ts.ws_xpixel = this->height;
	ts.ws_ypixel = this->width;

	this->scroll_frame_bottom = this->height;
	this->scroll_frame_top    = 0;

	int r = ioctl(this->pty, TIOCSWINSZ, (char * )&ts);
	/* This pseudo code taken from xterm. */
	kill( pg, SIGWINCH );
	SDEBUG << "Sent SIGWINCH to child. IO output is: " << r << std::endl;
}

void NcursesTerminal::resize( int x, int y ) {
	TerminalCell * tcTmp =
		(TerminalCell*) malloc(sizeof(TerminalCell) * (x * y));

	/* Let's do some costly allocation */

	for ( int i = 0; i < ( x * y ); ++i ) {
		tcTmp[i].ch   = ' ';
		tcTmp[i].attr = SHIBUYA_DEFAULT_CMODE;
	}

	/* And, now, let's copy over stuff in-range. */

	int resizeXMin = ( x < this->width )  ? x : this->width;
	int resizeYMin = ( y < this->height ) ? y : this->height;

	SDEBUG << "Limiting XY: " << resizeXMin << ", " << resizeYMin << std::endl;

	for ( int iy = 0; iy < this->height; ++iy ) {
		for ( int ix = 0; ix < this->width; ++ix ) {
			int hostOffset = GET_OFFSET( ix, iy );
			int nextOffset = (( x * iy ) + ix );
			SDEBUG << "XY: " << ix << "/" << iy << " -- " <<
				hostOffset << ", " << nextOffset << std::endl;
			tcTmp[nextOffset] = this->chars[hostOffset];
		}
	}

	free( this->chars );
	this->chars = tcTmp;
	this->width  = x;
	this->height = y;
	this->pane->resize( ( x + 2 ), (y + 2) );
	this->tainted = true;

	/* Now, let's tell the process group what's up */
	this->sigwinch();
}

void NcursesTerminal::move_to( int x, int y ) {
	this->pane->move_to( x, y );
}
<|endoftext|>


<commit_before>/*
 * File:   NetworkWrapper.cpp
 * Author: daniel
 *
 * Created on April 1, 2015, 6:19 PM
 */

#include "NetworkWrapper.h"

NetworkWrapper::NetworkWrapper() : AudioProcessor(NULL)
{
    Socket = -1;
}

NetworkWrapper::NetworkWrapper(const NetworkWrapper& orig) : AudioProcessor(orig)
{
    Socket = -1;
}

NetworkWrapper::~NetworkWrapper()
{
    if(Socket != -1)
    {
        //close socket
         #ifdef _WIN32
        closesocket(Socket);
        #else
        shutdown(Socket, SHUT_RDWR);
        #endif
    }
}

int NetworkWrapper::initializeNetwork()
{
    //dummy implementation, simply initialize socket
    int result = startWinsock();
    if(result != 0)
    {
        return result;
    }
    result = createSocket();
    if(result == -1)
    {
        return result;
    }
    //all okay
    return 0;
}

int NetworkWrapper::startWinsock()
{
    // Starting Winsock for Windows
    #ifdef _WIN32
    WSADATA w;
    if(int result = WSAStartup(MAKEWORD(2,2), &w) != 0)
    {
        std::cerr << "Failed to start Winsock 2! Error #" << result << std::endl;
        return result;
    }
    #endif
    return 0;
}

int NetworkWrapper::createSocket()
{
    // AF_INET - creating an IPv4 based socket
    Socket = socket(AF_INET, networkConfiguration.socketType, networkConfiguration.protocol);
    if(Socket == -1)
    {
        std::cerr << "Error on creating socket: " << errno << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Socket created for " << (networkConfiguration.protocol == IPPROTO_TCP ? "TCP" : "UDP") << std::endl;
    }

    //6. connect

    //local address
    if(bind(Socket, &networkConfiguration.localAddr, sizeof(networkConfiguration.localAddr)) == -1)
    {
        std::cerr << "Error binding the socket: " << errno << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Local port bound." << std::endl;
    }

    //remote address
    //for datagram-sockets, just sets default remote address
    if(connect(Socket,&networkConfiguration.remoteAddr,sizeof(networkConfiguration.remoteAddr)) == -1)
    {
        std::cerr << "Error connection the socket:" << errno << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Connection established." << std::endl;
    }

    return Socket;
}

uint8_t NetworkWrapper::getBytesFromAudioFormat(RtAudioFormat InputAudioFormat)
{
	switch (InputAudioFormat)
    {
        case RTAUDIO_SINT8:
            //1 byte signed integer
            return 1;
        case RTAUDIO_SINT16:
            //2 byte signed integer
            return 2;
        case RTAUDIO_SINT24:
            //3 byte signed integer
            return 3;
        case RTAUDIO_SINT32:
            //4 byte signed integer
        case RTAUDIO_FLOAT32:
            //4 byte float
            return 4;
        case RTAUDIO_FLOAT64:
            //8 byte signed integer
            return 8;
    }

    //TODO error-handling
    return 1;
}
<commit_msg>Update NetworkWrapper.cpp<commit_after>/*
 * File:   NetworkWrapper.cpp
 * Author: daniel
 *
 * Created on April 1, 2015, 6:19 PM
 */

#include "NetworkWrapper.h"

NetworkWrapper::NetworkWrapper() : AudioProcessor(NULL)
{
    Socket = -1;
}

NetworkWrapper::NetworkWrapper(const NetworkWrapper& orig) : AudioProcessor(orig)
{
    Socket = -1;
}

NetworkWrapper::~NetworkWrapper()
{
    if(Socket != -1)
    {
        //close socket
         #ifdef _WIN32
        closesocket(Socket);
        #else
        shutdown(Socket, SHUT_RDWR);
        #endif
    }
}

int NetworkWrapper::initializeNetwork()
{
    //dummy implementation, simply initialize socket
    int result = startWinsock();
    if(result != 0)
    {
        return result;
    }
    result = createSocket();
    if(result == -1)
    {
        return result;
    }
    //all okay
    return 0;
}

int NetworkWrapper::startWinsock()
{
    // Starting Winsock for Windows
    #ifdef _WIN32
    WSADATA w;
    if(int result = WSAStartup(MAKEWORD(2,2), &w) != 0)
    {
        std::cerr << "Failed to start Winsock 2! Error #" << result << std::endl;
        return result;
    }
    #endif
    return 0;
}

int NetworkWrapper::createSocket()
{
    // AF_INET - creating an IPv4 based socket
    Socket = socket(AF_INET, networkConfiguration.socketType, networkConfiguration.protocol);
    if(Socket == -1)
    {
        std::cerr << "Error on creating socket: " << errno << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Socket created for " << (networkConfiguration.protocol == IPPROTO_TCP ? "TCP" : "UDP") << std::endl;
    }

    //6. connect

    //local address
    if(bind(Socket, &networkConfiguration.localAddr, sizeof(networkConfiguration.localAddr)) == -1)
    {
        std::cerr << "Error binding the socket: " << errno << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Local port bound." << std::endl;
    }

    //remote address
    //for datagram-sockets, just sets default remote address
    if(connect(Socket,&networkConfiguration.remoteAddr,sizeof(networkConfiguration.remoteAddr)) == -1)
    {
        std::cerr << "Error connection the socket:" << errno << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Connection established." << std::endl;
    }

    return Socket;
}

uint8_t NetworkWrapper::getBytesFromAudioFormat(RtAudioFormat audioFormat)
{
	switch (audioFormat)
    {
        case RTAUDIO_SINT8:
            //1 byte signed integer
            return 1;
        case RTAUDIO_SINT16:
            //2 byte signed integer
            return 2;
        case RTAUDIO_SINT24:
            //3 byte signed integer
            return 3;
        case RTAUDIO_SINT32:
            //4 byte signed integer
        case RTAUDIO_FLOAT32:
            //4 byte float
            return 4;
        case RTAUDIO_FLOAT64:
            //8 byte signed integer
            return 8;
    }

    //TODO error-handling
    return 1;
}
<|endoftext|>


<commit_before>
// cFile.cpp

// Implements the cFile class providing an OS-independent abstraction of a file.

#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "File.h"
#include <fstream>

cFile::cFile(void) :
	#ifdef USE_STDIO_FILE
	m_File(NULL)
	#else
	m_File(INVALID_HANDLE_VALUE)
	#endif  // USE_STDIO_FILE
{
	// Nothing needed yet
}

cFile::cFile(const AString & iFileName, eMode iMode) :
	#ifdef USE_STDIO_FILE
	m_File(NULL)
	#else
	m_File(INVALID_HANDLE_VALUE)
	#endif  // USE_STDIO_FILE
{
	Open(iFileName, iMode);
}

cFile::~cFile()
{
	if (IsOpen())
	{
		Close();
	}
}

bool cFile::Open(const AString & iFileName, eMode iMode)
{
	ASSERT(!IsOpen());  // You should close the file before opening another one

	if (IsOpen())
	{
		Close();
	}

	const char * Mode = NULL;
	switch (iMode)
	{
		case fmRead:      Mode = "rb";  break;
		case fmWrite:     Mode = "wb";  break;
		case fmReadWrite: Mode = "rb+"; break;
		default:
		{
			ASSERT(!"Unhandled file mode");
			return false;
		}
	}
	m_File = fopen( (FILE_IO_PREFIX + iFileName).c_str(), Mode);
	if ((m_File == NULL) && (iMode == fmReadWrite))
	{
		// Fix for MS not following C spec, opening "a" mode files for writing at the end only
		// The file open operation has been tried with "read update", fails if file not found
		// So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents.
		// Simply re-open for read-writing, erasing existing contents:
		m_File = fopen( (FILE_IO_PREFIX + iFileName).c_str(), "wb+");
	}
	return (m_File != NULL);
}

void cFile::Close(void)
{
	if (!IsOpen())
	{
		// Closing an unopened file is a legal nop
		return;
	}

	fclose(m_File);
	m_File = NULL;
}

bool cFile::IsOpen(void) const
{
	return (m_File != NULL);
}

bool cFile::IsEOF(void) const
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		// Unopened files behave as at EOF
		return true;
	}

	return (feof(m_File) != 0);
}

int cFile::Read (void * iBuffer, int iNumBytes)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	return fread(iBuffer, 1, iNumBytes, m_File);  // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count
}

int cFile::Write(const void * iBuffer, int iNumBytes)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	int res = fwrite(iBuffer, 1, iNumBytes, m_File);  // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count
	return res;
}

int cFile::Seek (int iPosition)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	if (fseek(m_File, iPosition, SEEK_SET) != 0)
	{
		return -1;
	}
	return ftell(m_File);
}

int cFile::Tell (void) const
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	return ftell(m_File);
}

int cFile::GetSize(void) const
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	int CurPos = ftell(m_File);
	if (CurPos < 0)
	{
		return -1;
	}
	if (fseek(m_File, 0, SEEK_END) != 0)
	{
		return -1;
	}
	int res = ftell(m_File);
	if (fseek(m_File, CurPos, SEEK_SET) != 0)
	{
		return -1;
	}
	return res;
}

int cFile::ReadRestOfFile(AString & a_Contents)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	int DataSize = GetSize() - Tell();

	// HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly
	a_Contents.assign(DataSize, '\0');
	return Read((void *)a_Contents.data(), DataSize);
}

bool cFile::Exists(const AString & a_FileName)
{
	cFile test(a_FileName, fmRead);
	return test.IsOpen();
}

bool cFile::Delete(const AString & a_FileName)
{
	return (remove(a_FileName.c_str()) == 0);
}

bool cFile::Rename(const AString & a_OrigFileName, const AString & a_NewFileName)
{
	return (rename(a_OrigFileName.c_str(), a_NewFileName.c_str()) == 0);
}

bool cFile::Copy(const AString & a_SrcFileName, const AString & a_DstFileName)
{
	#ifdef _WIN32
		return (CopyFile(a_SrcFileName.c_str(), a_DstFileName.c_str(), true) != 0);
	#else
		// Other OSs don't have a direct CopyFile equivalent, do it the harder way:
		std::ifstream src(a_SrcFileName.c_str(), std::ios::binary);
		std::ofstream dst(a_DstFileName.c_str(), std::ios::binary);
		if (dst.good())
		{
			dst << src.rdbuf();
			return true;
		}
		else
		{
			return false;
		}
	#endif
}

bool cFile::IsFolder(const AString & a_Path)
{
	#ifdef _WIN32
		DWORD FileAttrib = GetFileAttributes(a_Path.c_str());
		return ((FileAttrib != INVALID_FILE_ATTRIBUTES) && ((FileAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0));
	#else
		struct stat st;
		return ((stat(a_Path.c_str(), &st) == 0) && S_ISDIR(st.st_mode));
	#endif
}

bool cFile::IsFile(const AString & a_Path)
{
	#ifdef _WIN32
		DWORD FileAttrib = GetFileAttributes(a_Path.c_str());
		return ((FileAttrib != INVALID_FILE_ATTRIBUTES) && ((FileAttrib & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0));
	#else
		struct stat st;
		return ((stat(a_Path.c_str(), &st) == 0) && S_ISREG(st.st_mode));
	#endif
}

int cFile::GetSize(const AString & a_FileName)
{
	struct stat st;
	if (stat(a_FileName.c_str(), &st) == 0)
	{
		return st.st_size;
	}
	return -1;
}

bool cFile::CreateFolder(const AString & a_FolderPath)
{
	#ifdef _WIN32
		return (CreateDirectory(a_FolderPath.c_str(), NULL) != 0);
	#else
		return (mkdir(a_FolderPath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0);
	#endif
}

AStringVector cFile::GetFolderContents(const AString & a_Folder)
{
	AStringVector AllFiles;

	#ifdef _WIN32

	// If the folder name doesn't contain the terminating slash / backslash, add it:
	AString FileFilter = a_Folder;
	if (
		!FileFilter.empty() &&
		(FileFilter[FileFilter.length() - 1] != '\\') &&
		(FileFilter[FileFilter.length() - 1] != '/')
	)
	{
		FileFilter.push_back('\\');
	}

	// Find all files / folders:
	FileFilter.append("*.*");
	HANDLE hFind;
	WIN32_FIND_DATA FindFileData;
	if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE)
	{
		do
		{
			AllFiles.push_back(FindFileData.cFileName);
		} while (FindNextFile(hFind, &FindFileData));
		FindClose(hFind);
	}

	#else  // _WIN32

	DIR * dp;
	struct dirent *dirp;
	AString Folder = a_Folder;
	if (Folder.empty())
	{
		Folder = ".";
	}
	if ((dp = opendir(Folder.c_str())) == NULL)
	{
		LOGERROR("Error (%i) opening directory \"%s\"\n", errno, Folder.c_str());
	}
	else
	{
		while ((dirp = readdir(dp)) != NULL)
		{
			AllFiles.push_back(dirp->d_name);
		}
		closedir(dp);
	}

	#endif  // else _WIN32

	return AllFiles;
}

AString cFile::ReadWholeFile(const AString & a_FileName)
{
	cFile f;
	if (!f.Open(a_FileName, fmRead))
	{
		return "";
	}
	AString Contents;
	f.ReadRestOfFile(Contents);
	return Contents;
}

int cFile::Printf(const char * a_Fmt, ...)
{
	AString buf;
	va_list args;
	va_start(args, a_Fmt);
	AppendVPrintf(buf, a_Fmt, args);
	va_end(args);
	return Write(buf.c_str(), buf.length());
}

void cFile::Flush(void)
{
	fflush(m_File);
}

<commit_msg>Fixed #491<commit_after>
// cFile.cpp

// Implements the cFile class providing an OS-independent abstraction of a file.

#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "File.h"
#include <fstream>

cFile::cFile(void) :
	#ifdef USE_STDIO_FILE
	m_File(NULL)
	#else
	m_File(INVALID_HANDLE_VALUE)
	#endif  // USE_STDIO_FILE
{
	// Nothing needed yet
}

cFile::cFile(const AString & iFileName, eMode iMode) :
	#ifdef USE_STDIO_FILE
	m_File(NULL)
	#else
	m_File(INVALID_HANDLE_VALUE)
	#endif  // USE_STDIO_FILE
{
	Open(iFileName, iMode);
}

cFile::~cFile()
{
	if (IsOpen())
	{
		Close();
	}
}

bool cFile::Open(const AString & iFileName, eMode iMode)
{
	ASSERT(!IsOpen());  // You should close the file before opening another one

	if (IsOpen())
	{
		Close();
	}

	const char * Mode = NULL;
	switch (iMode)
	{
		case fmRead:      Mode = "rb";  break;
		case fmWrite:     Mode = "wb";  break;
		case fmReadWrite: Mode = "rb+"; break;
		default:
		{
			ASSERT(!"Unhandled file mode");
			return false;
		}
	}

#ifdef _WIN32
	fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), Mode);
#else
	m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode);
#endif // _WIN32

	if ((m_File == NULL) && (iMode == fmReadWrite))
	{
		// Fix for MS not following C spec, opening "a" mode files for writing at the end only
		// The file open operation has been tried with "read update", fails if file not found
		// So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents.
		// Simply re-open for read-writing, erasing existing contents:

#ifdef _WIN32
		fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), "wb+");
#else
		m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+");
#endif // _WIN32

	}
	return (m_File != NULL);
}

void cFile::Close(void)
{
	if (!IsOpen())
	{
		// Closing an unopened file is a legal nop
		return;
	}

	fclose(m_File);
	m_File = NULL;
}

bool cFile::IsOpen(void) const
{
	return (m_File != NULL);
}

bool cFile::IsEOF(void) const
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		// Unopened files behave as at EOF
		return true;
	}

	return (feof(m_File) != 0);
}

int cFile::Read (void * iBuffer, int iNumBytes)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	return fread(iBuffer, 1, iNumBytes, m_File);  // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count
}

int cFile::Write(const void * iBuffer, int iNumBytes)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	int res = fwrite(iBuffer, 1, iNumBytes, m_File);  // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count
	return res;
}

int cFile::Seek (int iPosition)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	if (fseek(m_File, iPosition, SEEK_SET) != 0)
	{
		return -1;
	}
	return ftell(m_File);
}

int cFile::Tell (void) const
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	return ftell(m_File);
}

int cFile::GetSize(void) const
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	int CurPos = ftell(m_File);
	if (CurPos < 0)
	{
		return -1;
	}
	if (fseek(m_File, 0, SEEK_END) != 0)
	{
		return -1;
	}
	int res = ftell(m_File);
	if (fseek(m_File, CurPos, SEEK_SET) != 0)
	{
		return -1;
	}
	return res;
}

int cFile::ReadRestOfFile(AString & a_Contents)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	int DataSize = GetSize() - Tell();

	// HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly
	a_Contents.assign(DataSize, '\0');
	return Read((void *)a_Contents.data(), DataSize);
}

bool cFile::Exists(const AString & a_FileName)
{
	cFile test(a_FileName, fmRead);
	return test.IsOpen();
}

bool cFile::Delete(const AString & a_FileName)
{
	return (remove(a_FileName.c_str()) == 0);
}

bool cFile::Rename(const AString & a_OrigFileName, const AString & a_NewFileName)
{
	return (rename(a_OrigFileName.c_str(), a_NewFileName.c_str()) == 0);
}

bool cFile::Copy(const AString & a_SrcFileName, const AString & a_DstFileName)
{
	#ifdef _WIN32
		return (CopyFile(a_SrcFileName.c_str(), a_DstFileName.c_str(), true) != 0);
	#else
		// Other OSs don't have a direct CopyFile equivalent, do it the harder way:
		std::ifstream src(a_SrcFileName.c_str(), std::ios::binary);
		std::ofstream dst(a_DstFileName.c_str(), std::ios::binary);
		if (dst.good())
		{
			dst << src.rdbuf();
			return true;
		}
		else
		{
			return false;
		}
	#endif
}

bool cFile::IsFolder(const AString & a_Path)
{
	#ifdef _WIN32
		DWORD FileAttrib = GetFileAttributes(a_Path.c_str());
		return ((FileAttrib != INVALID_FILE_ATTRIBUTES) && ((FileAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0));
	#else
		struct stat st;
		return ((stat(a_Path.c_str(), &st) == 0) && S_ISDIR(st.st_mode));
	#endif
}

bool cFile::IsFile(const AString & a_Path)
{
	#ifdef _WIN32
		DWORD FileAttrib = GetFileAttributes(a_Path.c_str());
		return ((FileAttrib != INVALID_FILE_ATTRIBUTES) && ((FileAttrib & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0));
	#else
		struct stat st;
		return ((stat(a_Path.c_str(), &st) == 0) && S_ISREG(st.st_mode));
	#endif
}

int cFile::GetSize(const AString & a_FileName)
{
	struct stat st;
	if (stat(a_FileName.c_str(), &st) == 0)
	{
		return st.st_size;
	}
	return -1;
}

bool cFile::CreateFolder(const AString & a_FolderPath)
{
	#ifdef _WIN32
		return (CreateDirectory(a_FolderPath.c_str(), NULL) != 0);
	#else
		return (mkdir(a_FolderPath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0);
	#endif
}

AStringVector cFile::GetFolderContents(const AString & a_Folder)
{
	AStringVector AllFiles;

	#ifdef _WIN32

	// If the folder name doesn't contain the terminating slash / backslash, add it:
	AString FileFilter = a_Folder;
	if (
		!FileFilter.empty() &&
		(FileFilter[FileFilter.length() - 1] != '\\') &&
		(FileFilter[FileFilter.length() - 1] != '/')
	)
	{
		FileFilter.push_back('\\');
	}

	// Find all files / folders:
	FileFilter.append("*.*");
	HANDLE hFind;
	WIN32_FIND_DATA FindFileData;
	if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE)
	{
		do
		{
			AllFiles.push_back(FindFileData.cFileName);
		} while (FindNextFile(hFind, &FindFileData));
		FindClose(hFind);
	}

	#else  // _WIN32

	DIR * dp;
	struct dirent *dirp;
	AString Folder = a_Folder;
	if (Folder.empty())
	{
		Folder = ".";
	}
	if ((dp = opendir(Folder.c_str())) == NULL)
	{
		LOGERROR("Error (%i) opening directory \"%s\"\n", errno, Folder.c_str());
	}
	else
	{
		while ((dirp = readdir(dp)) != NULL)
		{
			AllFiles.push_back(dirp->d_name);
		}
		closedir(dp);
	}

	#endif  // else _WIN32

	return AllFiles;
}

AString cFile::ReadWholeFile(const AString & a_FileName)
{
	cFile f;
	if (!f.Open(a_FileName, fmRead))
	{
		return "";
	}
	AString Contents;
	f.ReadRestOfFile(Contents);
	return Contents;
}

int cFile::Printf(const char * a_Fmt, ...)
{
	AString buf;
	va_list args;
	va_start(args, a_Fmt);
	AppendVPrintf(buf, a_Fmt, args);
	va_end(args);
	return Write(buf.c_str(), buf.length());
}

void cFile::Flush(void)
{
	fflush(m_File);
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "OgreNoVRRender.hpp"

#include "AnnLogger.hpp"
#include "AnnGetter.hpp"

OgreNoVRRender* OgreNoVRRender::noVRself(nullptr);

OgreNoVRRender::OgreNoVRRender(std::string name) : OgreVRRender(name),
noVRViewport(nullptr),
running(true)
{
	rendererName = "OpenGL/NoVR";
	noVRself = dynamic_cast<OgreNoVRRender*>(self);
}

void OgreNoVRRender::initVrHmd()
{}

void OgreNoVRRender::initScene()
{
	smgr = root->createSceneManager("OctreeSceneManager", "OSMSMGR");
	smgr->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE);
}

void OgreNoVRRender::initRttRendering()
{
	noVRViewport = window->addViewport(monoCam);
	noVRViewport->setBackgroundColour(backgroundColor);
}

void OgreNoVRRender::initClientHmdRendering()
{
	loadOpenGLFunctions();

	//No HMD to initialize rendering for.
}

bool OgreNoVRRender::shouldQuit()
{
	return !running;
}

void OgreNoVRRender::getTrackingPoseAndVRTiming()
{
	calculateTimingFromOgre();

	trackedHeadPose.position = feetPosition + Annwvyn::AnnGetPlayer()->getEyeTranslation();
	trackedHeadPose.orientation = bodyOrientation;
}

void OgreNoVRRender::renderAndSubmitFrame()
{
	Ogre::WindowEventUtilities::messagePump();
	if (window->isClosed())
	{
		running = false;
		return;
	}

	root->_fireFrameRenderingQueued();
	noVRViewport->update();
	window->update();
}

void OgreNoVRRender::recenter()
{}

void OgreNoVRRender::changeViewportBackgroundColor(Ogre::ColourValue color)
{
	backgroundColor = color;

	noVRViewport->setBackgroundColour(color);
}

void OgreNoVRRender::showDebug(DebugMode mode)
{}

void OgreNoVRRender::updateProjectionMatrix()
{
	if (!monoCam) return;

	//Here we don't use a custom projection matrix. Just tell the Ogre Camera to use the current near/far clip planes
	monoCam->setNearClipDistance(nearClippingDistance);
	monoCam->setFarClipDistance(farClippingDistance);
}

bool OgreNoVRRender::shouldRecenter()
{
	return false;
}

bool OgreNoVRRender::isVisibleInHmd()
{
	return true;
}

void OgreNoVRRender::handleIPDChange()
{}

OgreNoVRRender::~OgreNoVRRender()
{
	root->destroySceneManager(smgr);
	noVRself = nullptr;
	rttTexture.setNull();
}<commit_msg>slight framerate limitation in no-vr mode<commit_after>#include "stdafx.h"
#include "OgreNoVRRender.hpp"

#include "AnnLogger.hpp"
#include "AnnGetter.hpp"

OgreNoVRRender* OgreNoVRRender::noVRself(nullptr);

OgreNoVRRender::OgreNoVRRender(std::string name) : OgreVRRender(name),
noVRViewport(nullptr),
running(true)
{
	rendererName = "OpenGL/NoVR";
	noVRself = dynamic_cast<OgreNoVRRender*>(self);
}

void OgreNoVRRender::initVrHmd()
{}

void OgreNoVRRender::initScene()
{
	smgr = root->createSceneManager("OctreeSceneManager", "OSMSMGR");
	smgr->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE);
}

void OgreNoVRRender::initRttRendering()
{
	noVRViewport = window->addViewport(monoCam);
	noVRViewport->setBackgroundColour(backgroundColor);
}

void OgreNoVRRender::initClientHmdRendering()
{
	loadOpenGLFunctions();

	//No HMD to initialize rendering for.
}

bool OgreNoVRRender::shouldQuit()
{
	return !running;
}

void OgreNoVRRender::getTrackingPoseAndVRTiming()
{
	calculateTimingFromOgre();

	trackedHeadPose.position = feetPosition + Annwvyn::AnnGetPlayer()->getEyeTranslation();
	trackedHeadPose.orientation = bodyOrientation;
}

void OgreNoVRRender::renderAndSubmitFrame()
{
	Ogre::WindowEventUtilities::messagePump();
	if (window->isClosed())
	{
		running = false;
		return;
	}

	root->_fireFrameRenderingQueued();
	noVRViewport->update();
	window->update();

	//Sleep for one ms
	std::this_thread::sleep_for(std::chrono::milliseconds(1));
}

void OgreNoVRRender::recenter()
{}

void OgreNoVRRender::changeViewportBackgroundColor(Ogre::ColourValue color)
{
	backgroundColor = color;

	noVRViewport->setBackgroundColour(color);
}

void OgreNoVRRender::showDebug(DebugMode mode)
{}

void OgreNoVRRender::updateProjectionMatrix()
{
	if (!monoCam) return;

	//Here we don't use a custom projection matrix. Just tell the Ogre Camera to use the current near/far clip planes
	monoCam->setNearClipDistance(nearClippingDistance);
	monoCam->setFarClipDistance(farClippingDistance);
}

bool OgreNoVRRender::shouldRecenter()
{
	return false;
}

bool OgreNoVRRender::isVisibleInHmd()
{
	return true;
}

void OgreNoVRRender::handleIPDChange()
{}

OgreNoVRRender::~OgreNoVRRender()
{
	root->destroySceneManager(smgr);
	noVRself = nullptr;
	rttTexture.setNull();
}<|endoftext|>