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

  Program:   Visualization Toolkit
  Module:    vtkTubeFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkTubeFilter.h"
#include "vtkPolyLine.h"
#include "vtkMath.h"

// Description:
// Construct object with radius 0.5, radius variation turned off, the number
// of sides set to 3, and radius factor of 10.
vtkTubeFilter::vtkTubeFilter()
{
  this->Radius = 0.5;
  this->VaryRadius = VTK_VARY_RADIUS_OFF;
  this->NumberOfSides = 3;
  this->RadiusFactor = 10;

  this->DefaultNormal[0] = this->DefaultNormal[1] = 0.0;
  this->DefaultNormal[2] = 1.0;

  this->UseDefaultNormal = 0;
}

void vtkTubeFilter::Execute()
{
  int i, j, k;
  vtkPoints *inPts;
  vtkCellArray *inLines = NULL;
  vtkNormals *inNormals;
  vtkScalars *inScalars=NULL;
  vtkVectors *inVectors=NULL;
  int numPts = 0;
  int numNewPts;
  vtkFloatPoints *newPts;
  vtkFloatNormals *newNormals;
  vtkCellArray *newStrips;
  int npts, *pts, i1, i2, ptOffset=0;
  float p[3], pNext[3];
  float maxSpeed = 0;
  float *n, normal[3], nP[3];
  float s[3], sNext[3], sPrev[3], w[3];
  double BevelAngle;
  float theta=2.0*vtkMath::Pi()/this->NumberOfSides;
  int deleteNormals=0, ptId;
  float sFactor=1.0, range[2];
  vtkPointData *pd, *outPD;
  vtkPolyData *input=(vtkPolyData *)this->Input;
  vtkPolyData *output=(vtkPolyData *)this->Output;
//
// Initialize
//
  vtkDebugMacro(<<"Creating tube");

  if ( !(inPts=input->GetPoints()) ||
  (numPts = inPts->GetNumberOfPoints()) < 1 ||
  !(inLines = input->GetLines()) || inLines->GetNumberOfCells() < 1 )
    {
    vtkErrorMacro(<< ": No input data!\n");
    return;
    }
  numNewPts = numPts * this->NumberOfSides;

  // copy scalars, vectors, tcoords. Normals may be computed here.
  pd = input->GetPointData();
  outPD = output->GetPointData();
  outPD->CopyNormalsOff();
  outPD->CopyAllocate(pd,numNewPts);

  if ( !(inNormals=pd->GetNormals()) || this->UseDefaultNormal )
    {
    vtkPolyLine lineNormalGenerator;
    deleteNormals = 1;
    inNormals = vtkFloatNormals::New();
    inNormals->SetNumberOfNormals(numPts);

    if ( this->UseDefaultNormal )
      {
      for ( i=0; i < numPts; i++)
	{
	inNormals->SetNormal(i,this->DefaultNormal);
	}
      }
    else
      {
      if ( !lineNormalGenerator.GenerateSlidingNormals(inPts,inLines,(vtkFloatNormals*)inNormals) )
        {
        vtkErrorMacro(<< "No normals for line!\n");
        if (deleteNormals) inNormals->Delete();
        return;
        }
      }
    }
//
// If varying width, get appropriate info.
//
  if ( this->VaryRadius == VTK_VARY_RADIUS_BY_SCALAR &&
  (inScalars=pd->GetScalars()) )
    {
    inScalars->GetRange(range);
    }
  else if ( this->VaryRadius == VTK_VARY_RADIUS_BY_VECTOR &&
  (inVectors=pd->GetVectors()) )
    {
    maxSpeed = inVectors->GetMaxNorm();
    }

  newPts = vtkFloatPoints::New();
  newPts->Allocate(numNewPts);
  newNormals = vtkFloatNormals::New();
  newNormals->Allocate(numNewPts);
  newStrips = vtkCellArray::New();
  newStrips->Allocate(newStrips->EstimateSize(1,numNewPts));
//
//  Create points along the line that are later connected into a
//  triangle strip.
//
  for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); )
    {
//
// Use "averaged" segment to create beveled effect. Watch out for first and
// last points.
//
    for (j=0; j < npts; j++)
      {
      if (npts < 2)
	{
	vtkErrorMacro(<< "less than two points");
	}

      if ( j == 0 ) //first point
        {
        inPts->GetPoint(pts[0],p);
        inPts->GetPoint(pts[1],pNext);
        for (i=0; i<3; i++)
          {
          sNext[i] = pNext[i] - p[i];
          sPrev[i] = sNext[i];
          }
        }

      else if ( j == (npts-1) ) //last point
        {
        for (i=0; i<3; i++)
          {
          sPrev[i] = sNext[i];
          p[i] = pNext[i];
          }
        }

      else
        {
        for (i=0; i<3; i++) p[i] = pNext[i];
        inPts->GetPoint(pts[j+1],pNext);
        for (i=0; i<3; i++)
          {
          sPrev[i] = sNext[i];
          sNext[i] = pNext[i] - p[i];
          }
        }

      n = inNormals->GetNormal(pts[j]);

      if ( vtkMath::Normalize(sNext) == 0.0 )
        {
        vtkErrorMacro(<<"Coincident points!");
        inNormals->Delete();
        newPts->Delete();
        newNormals->Delete();
        newStrips->Delete();
        return;
        }

      for (i=0; i<3; i++) s[i] = (sPrev[i] + sNext[i]) / 2.0; //average vector
      // if s is zero then just use sPrev cross n
      if (vtkMath::Normalize(s) == 0.0)
	{
	vtkWarningMacro(<< "using alternate bevel vector");
	vtkMath::Cross(sPrev,n,s);
	if (vtkMath::Normalize(s) == 0.0)
	  {
	  vtkErrorMacro(<< "using alternate bevel vector");
	  }
	}

      if ( (BevelAngle = vtkMath::Dot(sNext,sPrev)) > 1.0 ) BevelAngle = 1.0;
      if ( BevelAngle < -1.0 ) BevelAngle = -1.0;
      BevelAngle = acos((double)BevelAngle) / 2.0; //(0->90 degrees)
      if ( (BevelAngle = cos(BevelAngle)) == 0.0 ) BevelAngle = 1.0;

      BevelAngle = this->Radius / BevelAngle; //keep tube constant radius

      vtkMath::Cross(s,n,w);
      if ( vtkMath::Normalize(w) == 0.0)
        {
        vtkErrorMacro(<<"Bad normal s = " << s[0] << " " << s[1] << " " << s[2] << " n = " << n[0] << " " << n[1] << " " << n[2]);
        if (deleteNormals) inNormals->Delete();
        newPts->Delete();
        newNormals->Delete();
        newStrips->Delete();
        return;
        }

      vtkMath::Cross(w,s,nP); //create orthogonal coordinate system
      vtkMath::Normalize(nP);

      if ( inScalars ) // varying by scalar values
        {
        sFactor = 1.0 + ((this->RadiusFactor - 1.0) *
                  (inScalars->GetScalar(j) - range[0]) / (range[1]-range[0]));
	if ((range[1] - range[0]) == 0.0)
	  {
	  vtkErrorMacro(<< "Dividing by zero");
	  }
        }
      else if ( inVectors ) // use flux preserving relationship
        {
        sFactor =
	  sqrt((double)maxSpeed/vtkMath::Norm(inVectors->GetVector(j)));
        if ( sFactor > this->RadiusFactor ) sFactor = this->RadiusFactor;
        }

      //create points around line
      for (k=0; k < this->NumberOfSides; k++)
        {
        for (i=0; i<3; i++)
          {
          normal[i] = w[i]*cos((double)k*theta) + nP[i]*sin((double)k*theta);
          s[i] = p[i] + this->Radius * sFactor * normal[i];
          }
        ptId = newPts->InsertNextPoint(s);
        newNormals->InsertNormal(ptId,normal);
        outPD->CopyData(pd,pts[j],ptId);
        }
      }
//
// Generate the strips
//
    for (k=0; k<this->NumberOfSides; k++)
      {
      i1 = (k+1) % this->NumberOfSides;
      newStrips->InsertNextCell(npts*2);
      for (i=0; i < npts; i++)
        {
        i2 = i*this->NumberOfSides;
        newStrips->InsertCellPoint(ptOffset+i2+i1);
        newStrips->InsertCellPoint(ptOffset+i2+k);
        }
      } //for this line

    ptOffset += this->NumberOfSides*npts;
    }
//
// Update ourselves
//
  if ( deleteNormals ) inNormals->Delete();

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetStrips(newStrips);
  newStrips->Delete();

  outPD->SetNormals(newNormals);
  newNormals->Delete();

  output->Squeeze();
}

void vtkTubeFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Radius: " << this->Radius << "\n";
  os << indent << "Vary Radius: " << (this->VaryRadius ? "On\n" : "Off\n");
  os << indent << "Number Of Sides: " << this->NumberOfSides << "\n";
}

<commit_msg>FIX: Normals for multiple polylines are now computed independently, allowing shared vertices to exist between polylines but not allowing this sharing to affect the tubing of the individual polylines.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTubeFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkTubeFilter.h"
#include "vtkPolyLine.h"
#include "vtkMath.h"

// Description:
// Construct object with radius 0.5, radius variation turned off, the number
// of sides set to 3, and radius factor of 10.
vtkTubeFilter::vtkTubeFilter()
{
  this->Radius = 0.5;
  this->VaryRadius = VTK_VARY_RADIUS_OFF;
  this->NumberOfSides = 3;
  this->RadiusFactor = 10;

  this->DefaultNormal[0] = this->DefaultNormal[1] = 0.0;
  this->DefaultNormal[2] = 1.0;

  this->UseDefaultNormal = 0;
}

void vtkTubeFilter::Execute()
{
  int i, j, k;
  vtkPoints *inPts;
  vtkCellArray *inLines = NULL;
  vtkNormals *inNormals;
  vtkScalars *inScalars=NULL;
  vtkVectors *inVectors=NULL;
  int numPts = 0;
  int numNewPts;
  vtkFloatPoints *newPts;
  vtkFloatNormals *newNormals;
  vtkCellArray *newStrips;
  int npts, *pts, i1, i2, ptOffset=0;
  float p[3], pNext[3];
  float maxSpeed = 0;
  float *n, normal[3], nP[3];
  float s[3], sNext[3], sPrev[3], w[3];
  double BevelAngle;
  float theta=2.0*vtkMath::Pi()/this->NumberOfSides;
  int deleteNormals=0, ptId;
  float sFactor=1.0, range[2];
  vtkPointData *pd, *outPD;
  vtkPolyData *input=(vtkPolyData *)this->Input;
  vtkPolyData *output=(vtkPolyData *)this->Output;
//
// Initialize
//
  vtkDebugMacro(<<"Creating tube");

  if ( !(inPts=input->GetPoints()) ||
  (numPts = inPts->GetNumberOfPoints()) < 1 ||
  !(inLines = input->GetLines()) || inLines->GetNumberOfCells() < 1 )
    {
    vtkErrorMacro(<< ": No input data!\n");
    return;
    }
  numNewPts = numPts * this->NumberOfSides;

  // copy scalars, vectors, tcoords. Normals may be computed here.
  pd = input->GetPointData();
  outPD = output->GetPointData();
  outPD->CopyNormalsOff();
  outPD->CopyAllocate(pd,numNewPts);

  int generate_normals = 0;
  vtkPolyLine lineNormalGenerator;

  if ( !(inNormals=pd->GetNormals()) || this->UseDefaultNormal )
    {
    deleteNormals = 1;
    inNormals = vtkFloatNormals::New();
    inNormals->SetNumberOfNormals(numPts);

    if ( this->UseDefaultNormal )
      {
      for ( i=0; i < numPts; i++)
	{
	inNormals->SetNormal(i,this->DefaultNormal);
	}
      }
    else
      {
      // Normal generation has been moved to lower in the function.
      // This allows each different polylines to share vertices, but have
      // their normals (and hence their tubes) calculated independently
      generate_normals = 1;

      }
    }
//
// If varying width, get appropriate info.
//
  if ( this->VaryRadius == VTK_VARY_RADIUS_BY_SCALAR &&
  (inScalars=pd->GetScalars()) )
    {
    inScalars->GetRange(range);
    }
  else if ( this->VaryRadius == VTK_VARY_RADIUS_BY_VECTOR &&
  (inVectors=pd->GetVectors()) )
    {
    maxSpeed = inVectors->GetMaxNorm();
    }

  newPts = vtkFloatPoints::New();
  newPts->Allocate(numNewPts);
  newNormals = vtkFloatNormals::New();
  newNormals->Allocate(numNewPts);
  newStrips = vtkCellArray::New();
  newStrips->Allocate(newStrips->EstimateSize(1,numNewPts));
//
//  Create points along the line that are later connected into a
//  triangle strip.
//
  for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); )
  {
    // if necessary calculate normals, each polyline calculates it's
    // normals independently, avoiding conflicts at shared vertices
    vtkCellArray *single_polyline = vtkCellArray::New();
    if (generate_normals) {
      single_polyline->InsertNextCell( npts, pts );

      if ( !lineNormalGenerator.GenerateSlidingNormals(inPts,single_polyline,
					  (vtkFloatNormals*)inNormals) )
      {
        vtkErrorMacro(<< "No normals for line!\n");
        if (deleteNormals) inNormals->Delete();
        return;
      }
    }
//
// Use "averaged" segment to create beveled effect. Watch out for first and
// last points.
//
    for (j=0; j < npts; j++)
      {
      if (npts < 2)
	{
	vtkErrorMacro(<< "less than two points");
	}

      if ( j == 0 ) //first point
        {
        inPts->GetPoint(pts[0],p);
        inPts->GetPoint(pts[1],pNext);
        for (i=0; i<3; i++)
          {
          sNext[i] = pNext[i] - p[i];
          sPrev[i] = sNext[i];
          }
        }

      else if ( j == (npts-1) ) //last point
        {
        for (i=0; i<3; i++)
          {
          sPrev[i] = sNext[i];
          p[i] = pNext[i];
          }
        }

      else
        {
        for (i=0; i<3; i++) p[i] = pNext[i];
        inPts->GetPoint(pts[j+1],pNext);
        for (i=0; i<3; i++)
          {
          sPrev[i] = sNext[i];
          sNext[i] = pNext[i] - p[i];
          }
        }

      n = inNormals->GetNormal(pts[j]);

      if ( vtkMath::Normalize(sNext) == 0.0 )
        {
        vtkErrorMacro(<<"Coincident points!");
        inNormals->Delete();
        newPts->Delete();
        newNormals->Delete();
        newStrips->Delete();
        return;
        }

      for (i=0; i<3; i++) s[i] = (sPrev[i] + sNext[i]) / 2.0; //average vector
      // if s is zero then just use sPrev cross n
      if (vtkMath::Normalize(s) == 0.0)
	{
	vtkWarningMacro(<< "using alternate bevel vector");
	vtkMath::Cross(sPrev,n,s);
	if (vtkMath::Normalize(s) == 0.0)
	  {
	  vtkErrorMacro(<< "using alternate bevel vector");
	  }
	}

      if ( (BevelAngle = vtkMath::Dot(sNext,sPrev)) > 1.0 ) BevelAngle = 1.0;
      if ( BevelAngle < -1.0 ) BevelAngle = -1.0;
      BevelAngle = acos((double)BevelAngle) / 2.0; //(0->90 degrees)
      if ( (BevelAngle = cos(BevelAngle)) == 0.0 ) BevelAngle = 1.0;

      BevelAngle = this->Radius / BevelAngle; //keep tube constant radius

      vtkMath::Cross(s,n,w);
      if ( vtkMath::Normalize(w) == 0.0)
        {
        vtkErrorMacro(<<"Bad normal s = " << s[0] << " " << s[1] << " " << s[2] << " n = " << n[0] << " " << n[1] << " " << n[2]);
        if (deleteNormals) inNormals->Delete();
        newPts->Delete();
        newNormals->Delete();
        newStrips->Delete();
        return;
        }

      vtkMath::Cross(w,s,nP); //create orthogonal coordinate system
      vtkMath::Normalize(nP);

      if ( inScalars ) // varying by scalar values
        {
        sFactor = 1.0 + ((this->RadiusFactor - 1.0) *
                  (inScalars->GetScalar(j) - range[0]) / (range[1]-range[0]));
	if ((range[1] - range[0]) == 0.0)
	  {
	  vtkErrorMacro(<< "Dividing by zero");
	  }
        }
      else if ( inVectors ) // use flux preserving relationship
        {
        sFactor =
	  sqrt((double)maxSpeed/vtkMath::Norm(inVectors->GetVector(j)));
        if ( sFactor > this->RadiusFactor ) sFactor = this->RadiusFactor;
        }

      //create points around line
      for (k=0; k < this->NumberOfSides; k++)
        {
        for (i=0; i<3; i++)
          {
          normal[i] = w[i]*cos((double)k*theta) + nP[i]*sin((double)k*theta);
          s[i] = p[i] + this->Radius * sFactor * normal[i];
          }
        ptId = newPts->InsertNextPoint(s);
        newNormals->InsertNormal(ptId,normal);
        outPD->CopyData(pd,pts[j],ptId);
        }
      }
//
// Generate the strips
//
    for (k=0; k<this->NumberOfSides; k++)
      {
      i1 = (k+1) % this->NumberOfSides;
      newStrips->InsertNextCell(npts*2);
      for (i=0; i < npts; i++)
        {
        i2 = i*this->NumberOfSides;
        newStrips->InsertCellPoint(ptOffset+i2+i1);
        newStrips->InsertCellPoint(ptOffset+i2+k);
        }
      } //for this line

    ptOffset += this->NumberOfSides*npts;
    single_polyline->Delete();
  }
//
// Update ourselves
//
  if ( deleteNormals ) inNormals->Delete();

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetStrips(newStrips);
  newStrips->Delete();

  outPD->SetNormals(newNormals);
  newNormals->Delete();

  output->Squeeze();
}

void vtkTubeFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Radius: " << this->Radius << "\n";
  os << indent << "Vary Radius: " << (this->VaryRadius ? "On\n" : "Off\n");
  os << indent << "Number Of Sides: " << this->NumberOfSides << "\n";
}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    quadraticEvaluation.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 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.

=========================================================================*/
// .NAME
// .SECTION Description
// This program tests quadratic cell EvaluatePosition() and EvaluateLocation()
// methods.

#include "vtkDebugLeaks.h"

#include "vtkIdList.h"
#include "vtkQuadraticEdge.h"
#include "vtkQuadraticTriangle.h"
#include "vtkQuadraticQuad.h"
#include "vtkQuadraticHexahedron.h"
#include "vtkQuadraticTetra.h"

void  ComputeDataValues(vtkPoints *pts, float *edgeValues)
{
  float x[3];
  int numPts = pts->GetNumberOfPoints();
  for (int i=0; i<numPts; i++)
    {
    pts->GetPoint(i,x);
    float dem = (1.0 + x[0]);
    if(fabs(dem) < 1.e-08)
      {
      edgeValues[i] = 0;
      }
    else
      {
      edgeValues[i] = 1.0 / dem; //simple linear function for now
      }
    }
}

int TestQE(ostream& strm)
{
  // actual test
  float dist2;
  int subId;

  //-----------------------------------------------------------
  strm << "Test instantiation New() and NewInstance() Start" << endl;
  vtkQuadraticEdge *edge = vtkQuadraticEdge::New();
  vtkQuadraticEdge *edge2 = edge->NewInstance();

  vtkQuadraticTriangle *tri = vtkQuadraticTriangle::New();
  vtkQuadraticTriangle *tri2 = tri->NewInstance();

  vtkQuadraticQuad *quad = vtkQuadraticQuad::New();
  vtkQuadraticQuad *quad2 = quad->NewInstance();

  vtkQuadraticTetra *tetra = vtkQuadraticTetra::New();
  vtkQuadraticTetra *tetra2 = tetra->NewInstance();

  vtkQuadraticHexahedron *hex = vtkQuadraticHexahedron::New();
  vtkQuadraticHexahedron *hex2 = hex->NewInstance();

  edge2->Delete();
  tri2->Delete();
  quad2->Delete();
  tetra2->Delete();
  hex2->Delete();

  strm << "Test instantiation New() and NewInstance() End" << endl;

  //-------------------------------------------------------------
  strm << "Test vtkCell::EvaluatePosition Start" << endl;

  // vtkQuadraticEdge
  float edgePCoords[3], edgeWeights[3], edgePosition[3];
  float edgePoint[1][3] = {{0.25, 0.125, 0.0}};
  float edgeClosest[3];

  edge->GetPointIds()->SetId(0,0);
  edge->GetPointIds()->SetId(1,1);
  edge->GetPointIds()->SetId(2,2);

  edge->GetPoints()->SetPoint(0, 0, 0, 0);
  edge->GetPoints()->SetPoint(1, 1, 0, 0);
  edge->GetPoints()->SetPoint(2, 0.5, 0.25, 0);

  edge->EvaluatePosition(edgePoint[0], edgeClosest, subId, edgePCoords,
                         dist2, edgeWeights);

  // vtkQuadraticTriangle
  float triPCoords[3], triWeights[6], triPosition[3];
  float triPoint[1][3] = {{0.5, 0.266667, 0.0}};
  float triClosest[3];

  tri->GetPointIds()->SetId(0,0);
  tri->GetPointIds()->SetId(1,1);
  tri->GetPointIds()->SetId(2,2);
  tri->GetPointIds()->SetId(3,3);
  tri->GetPointIds()->SetId(4,4);
  tri->GetPointIds()->SetId(5,5);

  tri->GetPoints()->SetPoint(0, 0, 0, 0);
  tri->GetPoints()->SetPoint(1, 1, 0, 0);
  tri->GetPoints()->SetPoint(2, 0.5, 0.8, 0);
  tri->GetPoints()->SetPoint(3, 0.5, 0.0, 0);
  tri->GetPoints()->SetPoint(4, 0.75, 0.4, 0);
  tri->GetPoints()->SetPoint(5, 0.25, 0.4, 0);

  tri->EvaluatePosition(triPoint[0], triClosest, subId, triPCoords,
                        dist2, triWeights);

  // vtkQuadraticQuad
  float quadPCoords[3], quadWeights[8], quadPosition[3];
  float quadPoint[1][3] = {{0.25, 0.33, 0.0}};
  float quadClosest[3];

  quad->GetPointIds()->SetId(0,0);
  quad->GetPointIds()->SetId(1,1);
  quad->GetPointIds()->SetId(2,2);
  quad->GetPointIds()->SetId(3,3);
  quad->GetPointIds()->SetId(4,4);
  quad->GetPointIds()->SetId(5,5);
  quad->GetPointIds()->SetId(6,6);
  quad->GetPointIds()->SetId(7,7);

  quad->GetPoints()->SetPoint(0, 0.0, 0.0, 0.0);
  quad->GetPoints()->SetPoint(1, 1.0, 0.0, 0.0);
  quad->GetPoints()->SetPoint(2, 1.0, 1.0, 0.0);
  quad->GetPoints()->SetPoint(3, 0.0, 1.0, 0.0);
  quad->GetPoints()->SetPoint(4, 0.5, 0.0, 0.0);
  quad->GetPoints()->SetPoint(5, 1.0, 0.5, 0.0);
  quad->GetPoints()->SetPoint(6, 0.5, 1.0, 0.0);
  quad->GetPoints()->SetPoint(7, 0.0, 0.5, 0.0);

  quad->EvaluatePosition(quadPoint[0], quadClosest, subId, quadPCoords,
                         dist2, quadWeights);

  // vtkQuadraticTetra
  float tetraPCoords[3], tetraWeights[10], tetraPosition[3];
  float tetraPoint[1][3] = {{0.5, 0.266667, 0.333333}};
  float tetraClosest[3];

  tetra->GetPointIds()->SetId(0,0);
  tetra->GetPointIds()->SetId(1,1);
  tetra->GetPointIds()->SetId(2,2);
  tetra->GetPointIds()->SetId(3,3);
  tetra->GetPointIds()->SetId(4,4);
  tetra->GetPointIds()->SetId(5,5);
  tetra->GetPointIds()->SetId(6,6);
  tetra->GetPointIds()->SetId(7,7);
  tetra->GetPointIds()->SetId(8,8);
  tetra->GetPointIds()->SetId(9,9);

  tetra->GetPoints()->SetPoint(0, 0.0, 0.0, 0.0);
  tetra->GetPoints()->SetPoint(1, 1.0, 0.0, 0.0);
  tetra->GetPoints()->SetPoint(2, 0.5, 0.8, 0.0);
  tetra->GetPoints()->SetPoint(3, 0.5, 0.4, 1.0);
  tetra->GetPoints()->SetPoint(4, 0.5, 0.0,  0.0);
  tetra->GetPoints()->SetPoint(5, 0.75, 0.4, 0.0);
  tetra->GetPoints()->SetPoint(6, 0.25, 0.4, 0.0);
  tetra->GetPoints()->SetPoint(7, 0.25, 0.2, 0.5);
  tetra->GetPoints()->SetPoint(8, 0.75, 0.2, 0.5);
  tetra->GetPoints()->SetPoint(9, 0.50, 0.6, 0.5);

  tetra->EvaluatePosition(tetraPoint[0], tetraClosest, subId, tetraPCoords,
                         dist2, tetraWeights);

  // vtkQuadraticHexahedron
  float hexPCoords[3], hexWeights[20], hexPosition[3];
  float hexPoint[1][3] = {{0.25, 0.33333, 0.666667}};
  float hexClosest[3];

  hex->GetPointIds()->SetId(0,0);
  hex->GetPointIds()->SetId(1,1);
  hex->GetPointIds()->SetId(2,2);
  hex->GetPointIds()->SetId(3,3);
  hex->GetPointIds()->SetId(4,4);
  hex->GetPointIds()->SetId(5,5);
  hex->GetPointIds()->SetId(6,6);
  hex->GetPointIds()->SetId(7,7);
  hex->GetPointIds()->SetId(8,8);
  hex->GetPointIds()->SetId(9,9);
  hex->GetPointIds()->SetId(10,10);
  hex->GetPointIds()->SetId(11,11);
  hex->GetPointIds()->SetId(12,12);
  hex->GetPointIds()->SetId(13,13);
  hex->GetPointIds()->SetId(14,14);
  hex->GetPointIds()->SetId(15,15);
  hex->GetPointIds()->SetId(16,16);
  hex->GetPointIds()->SetId(17,17);
  hex->GetPointIds()->SetId(18,18);
  hex->GetPointIds()->SetId(19,19);

  hex->GetPoints()->SetPoint( 0, 0, 0, 0  );
  hex->GetPoints()->SetPoint( 1, 1, 0, 0  );
  hex->GetPoints()->SetPoint( 2, 1, 1, 0  );
  hex->GetPoints()->SetPoint( 3, 0, 1, 0  );
  hex->GetPoints()->SetPoint( 4, 0, 0, 1  );
  hex->GetPoints()->SetPoint( 5, 1, 0, 1  );
  hex->GetPoints()->SetPoint( 6, 1, 1, 1  );
  hex->GetPoints()->SetPoint( 7, 0, 1, 1  );
  hex->GetPoints()->SetPoint( 8, 0.5, 0, 0);
  hex->GetPoints()->SetPoint( 9, 1, 0.5, 0);
  hex->GetPoints()->SetPoint(10, 0.5, 1, 0);
  hex->GetPoints()->SetPoint(11, 0, 0.5, 0);
  hex->GetPoints()->SetPoint(12, 0.5, 0, 1);
  hex->GetPoints()->SetPoint(13, 1, 0.5, 1);
  hex->GetPoints()->SetPoint(14, 0.5, 1, 1);
  hex->GetPoints()->SetPoint(15, 0, 0.5, 1);
  hex->GetPoints()->SetPoint(16, 0, 0, 0.5);
  hex->GetPoints()->SetPoint(17, 1, 0, 0.5);
  hex->GetPoints()->SetPoint(18, 1, 1, 0.5);
  hex->GetPoints()->SetPoint(19, 0, 1, 0.5);

  hex->EvaluatePosition(hexPoint[0], hexClosest, subId, hexPCoords,
                         dist2, hexWeights);

  strm << "Test vtkCell::EvaluatePosition End" << endl;

  //-------------------------------------------------------------
  strm << "Test vtkCell::EvaluateLocation Start" << endl;
  // vtkQuadraticEdge
  edge->EvaluateLocation(subId, edgePCoords, edgePosition, edgeWeights);

  // vtkQuadraticTriangle
  tri->EvaluateLocation(subId, triPCoords, triPosition, triWeights);

  // vtkQuadraticQuad
  quad->EvaluateLocation(subId, quadPCoords, quadPosition, quadWeights);

  // vtkQuadraticTetra
  tetra->EvaluateLocation(subId, tetraPCoords, tetraPosition, tetraWeights);

  // vtkQuadraticHexahedron
  hexPCoords[0] = 0.25;
  hexPCoords[1] = 0.33;
  hexPCoords[2] = 0.75;
  hex->EvaluateLocation(subId, hexPCoords, hexPosition, hexWeights);

  strm << "Test vtkCell::EvaluateLocation End" << endl;

  //-------------------------------------------------------------
  strm << "Test vtkCell::CellDerivs Start" << endl;

  // vtkQuadraticEdge
  float edgeValues[3], edgeDerivs[3];
  ComputeDataValues(edge->Points,edgeValues);
  edge->Derivatives(subId, edgePCoords, edgeValues, 1, edgeDerivs);

  // vtkQuadraticTriangle
  float triValues[6], triDerivs[3];
  ComputeDataValues(tri->Points,triValues);
  tri->Derivatives(subId, triPCoords, triValues, 1, triDerivs);

  // vtkQuadraticQuad
  float quadValues[8], quadDerivs[3];
  ComputeDataValues(quad->Points,quadValues);
  quad->Derivatives(subId, quadPCoords, quadValues, 1, quadDerivs);

  // vtkQuadraticTetra
  float tetraValues[10], tetraDerivs[3];
  ComputeDataValues(tetra->Points,tetraValues);
  tetra->Derivatives(subId, tetraPCoords, tetraValues, 1, tetraDerivs);

  // vtkQuadraticHexahedron
  float hexValues[20], hexDerivs[3];
  ComputeDataValues(hex->Points,hexValues);
  hex->Derivatives(subId, hexPCoords, hexValues, 1, hexDerivs);

  strm << "Test vtkCell::CellDerivs End" << endl;

  edge->Delete();
  tri->Delete();
  quad->Delete();
  tetra->Delete();
  hex->Delete();

  return 0;
}

int quadraticEvaluation(int,char *[])
{
  vtkDebugLeaks::PromptUserOff();

  ostrstream vtkmsg;
  return TestQE(vtkmsg);
}
<commit_msg>ENH:Temporary fix until pseudo-inverse is computed right<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    quadraticEvaluation.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 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.

=========================================================================*/
// .NAME
// .SECTION Description
// This program tests quadratic cell EvaluatePosition() and EvaluateLocation()
// methods.

#include "vtkDebugLeaks.h"

#include "vtkIdList.h"
#include "vtkQuadraticEdge.h"
#include "vtkQuadraticTriangle.h"
#include "vtkQuadraticQuad.h"
#include "vtkQuadraticHexahedron.h"
#include "vtkQuadraticTetra.h"

void  ComputeDataValues(vtkPoints *pts, float *edgeValues)
{
  float x[3];
  int numPts = pts->GetNumberOfPoints();
  for (int i=0; i<numPts; i++)
    {
    pts->GetPoint(i,x);
    float dem = (1.0 + x[0]);
    if(fabs(dem) < 1.e-08)
      {
      edgeValues[i] = 0;
      }
    else
      {
      edgeValues[i] = 1.0 / dem; //simple linear function for now
      }
    }
}

int TestQE(ostream& strm)
{
  // actual test
  float dist2;
  int subId;

  //-----------------------------------------------------------
  strm << "Test instantiation New() and NewInstance() Start" << endl;
  vtkQuadraticEdge *edge = vtkQuadraticEdge::New();
  vtkQuadraticEdge *edge2 = edge->NewInstance();

  vtkQuadraticTriangle *tri = vtkQuadraticTriangle::New();
  vtkQuadraticTriangle *tri2 = tri->NewInstance();

  vtkQuadraticQuad *quad = vtkQuadraticQuad::New();
  vtkQuadraticQuad *quad2 = quad->NewInstance();

  vtkQuadraticTetra *tetra = vtkQuadraticTetra::New();
  vtkQuadraticTetra *tetra2 = tetra->NewInstance();

  vtkQuadraticHexahedron *hex = vtkQuadraticHexahedron::New();
  vtkQuadraticHexahedron *hex2 = hex->NewInstance();

  edge2->Delete();
  tri2->Delete();
  quad2->Delete();
  tetra2->Delete();
  hex2->Delete();

  strm << "Test instantiation New() and NewInstance() End" << endl;

  //-------------------------------------------------------------
  strm << "Test vtkCell::EvaluatePosition Start" << endl;

  // vtkQuadraticEdge
  float edgePCoords[3], edgeWeights[3], edgePosition[3];
  float edgePoint[1][3] = {{0.25, 0.125, 0.0}};
  float edgeClosest[3];

  edge->GetPointIds()->SetId(0,0);
  edge->GetPointIds()->SetId(1,1);
  edge->GetPointIds()->SetId(2,2);

  edge->GetPoints()->SetPoint(0, 0, 0, 0);
  edge->GetPoints()->SetPoint(1, 1, 0, .5);
  edge->GetPoints()->SetPoint(2, 0.5, 0.25, .2);

  edge->EvaluatePosition(edgePoint[0], edgeClosest, subId, edgePCoords,
                         dist2, edgeWeights);

  // vtkQuadraticTriangle
  float triPCoords[3], triWeights[6], triPosition[3];
  float triPoint[1][3] = {{0.5, 0.266667, 0.0}};
  float triClosest[3];

  tri->GetPointIds()->SetId(0,0);
  tri->GetPointIds()->SetId(1,1);
  tri->GetPointIds()->SetId(2,2);
  tri->GetPointIds()->SetId(3,3);
  tri->GetPointIds()->SetId(4,4);
  tri->GetPointIds()->SetId(5,5);

  tri->GetPoints()->SetPoint(0, 0, 0, 0);
  tri->GetPoints()->SetPoint(1, 1, 0, 0);
  tri->GetPoints()->SetPoint(2, 0.5, 0.8, 0);
  tri->GetPoints()->SetPoint(3, 0.5, 0.0, 0);
  tri->GetPoints()->SetPoint(4, 0.75, 0.4, 0);
  tri->GetPoints()->SetPoint(5, 0.25, 0.4, 0);

  tri->EvaluatePosition(triPoint[0], triClosest, subId, triPCoords,
                        dist2, triWeights);

  // vtkQuadraticQuad
  float quadPCoords[3], quadWeights[8], quadPosition[3];
  float quadPoint[1][3] = {{0.25, 0.33, 0.0}};
  float quadClosest[3];

  quad->GetPointIds()->SetId(0,0);
  quad->GetPointIds()->SetId(1,1);
  quad->GetPointIds()->SetId(2,2);
  quad->GetPointIds()->SetId(3,3);
  quad->GetPointIds()->SetId(4,4);
  quad->GetPointIds()->SetId(5,5);
  quad->GetPointIds()->SetId(6,6);
  quad->GetPointIds()->SetId(7,7);

  quad->GetPoints()->SetPoint(0, 0.0, 0.0, 0.0);
  quad->GetPoints()->SetPoint(1, 1.0, 0.0, 0.0);
  quad->GetPoints()->SetPoint(2, 1.0, 1.0, 0.0);
  quad->GetPoints()->SetPoint(3, 0.0, 1.0, 0.0);
  quad->GetPoints()->SetPoint(4, 0.5, 0.0, 0.0);
  quad->GetPoints()->SetPoint(5, 1.0, 0.5, 0.0);
  quad->GetPoints()->SetPoint(6, 0.5, 1.0, 0.0);
  quad->GetPoints()->SetPoint(7, 0.0, 0.5, 0.0);

  quad->EvaluatePosition(quadPoint[0], quadClosest, subId, quadPCoords,
                         dist2, quadWeights);

  // vtkQuadraticTetra
  float tetraPCoords[3], tetraWeights[10], tetraPosition[3];
  float tetraPoint[1][3] = {{0.5, 0.266667, 0.333333}};
  float tetraClosest[3];

  tetra->GetPointIds()->SetId(0,0);
  tetra->GetPointIds()->SetId(1,1);
  tetra->GetPointIds()->SetId(2,2);
  tetra->GetPointIds()->SetId(3,3);
  tetra->GetPointIds()->SetId(4,4);
  tetra->GetPointIds()->SetId(5,5);
  tetra->GetPointIds()->SetId(6,6);
  tetra->GetPointIds()->SetId(7,7);
  tetra->GetPointIds()->SetId(8,8);
  tetra->GetPointIds()->SetId(9,9);

  tetra->GetPoints()->SetPoint(0, 0.0, 0.0, 0.0);
  tetra->GetPoints()->SetPoint(1, 1.0, 0.0, 0.0);
  tetra->GetPoints()->SetPoint(2, 0.5, 0.8, 0.0);
  tetra->GetPoints()->SetPoint(3, 0.5, 0.4, 1.0);
  tetra->GetPoints()->SetPoint(4, 0.5, 0.0,  0.0);
  tetra->GetPoints()->SetPoint(5, 0.75, 0.4, 0.0);
  tetra->GetPoints()->SetPoint(6, 0.25, 0.4, 0.0);
  tetra->GetPoints()->SetPoint(7, 0.25, 0.2, 0.5);
  tetra->GetPoints()->SetPoint(8, 0.75, 0.2, 0.5);
  tetra->GetPoints()->SetPoint(9, 0.50, 0.6, 0.5);

  tetra->EvaluatePosition(tetraPoint[0], tetraClosest, subId, tetraPCoords,
                         dist2, tetraWeights);

  // vtkQuadraticHexahedron
  float hexPCoords[3], hexWeights[20], hexPosition[3];
  float hexPoint[1][3] = {{0.25, 0.33333, 0.666667}};
  float hexClosest[3];

  hex->GetPointIds()->SetId(0,0);
  hex->GetPointIds()->SetId(1,1);
  hex->GetPointIds()->SetId(2,2);
  hex->GetPointIds()->SetId(3,3);
  hex->GetPointIds()->SetId(4,4);
  hex->GetPointIds()->SetId(5,5);
  hex->GetPointIds()->SetId(6,6);
  hex->GetPointIds()->SetId(7,7);
  hex->GetPointIds()->SetId(8,8);
  hex->GetPointIds()->SetId(9,9);
  hex->GetPointIds()->SetId(10,10);
  hex->GetPointIds()->SetId(11,11);
  hex->GetPointIds()->SetId(12,12);
  hex->GetPointIds()->SetId(13,13);
  hex->GetPointIds()->SetId(14,14);
  hex->GetPointIds()->SetId(15,15);
  hex->GetPointIds()->SetId(16,16);
  hex->GetPointIds()->SetId(17,17);
  hex->GetPointIds()->SetId(18,18);
  hex->GetPointIds()->SetId(19,19);

  hex->GetPoints()->SetPoint( 0, 0, 0, 0  );
  hex->GetPoints()->SetPoint( 1, 1, 0, 0  );
  hex->GetPoints()->SetPoint( 2, 1, 1, 0  );
  hex->GetPoints()->SetPoint( 3, 0, 1, 0  );
  hex->GetPoints()->SetPoint( 4, 0, 0, 1  );
  hex->GetPoints()->SetPoint( 5, 1, 0, 1  );
  hex->GetPoints()->SetPoint( 6, 1, 1, 1  );
  hex->GetPoints()->SetPoint( 7, 0, 1, 1  );
  hex->GetPoints()->SetPoint( 8, 0.5, 0, 0);
  hex->GetPoints()->SetPoint( 9, 1, 0.5, 0);
  hex->GetPoints()->SetPoint(10, 0.5, 1, 0);
  hex->GetPoints()->SetPoint(11, 0, 0.5, 0);
  hex->GetPoints()->SetPoint(12, 0.5, 0, 1);
  hex->GetPoints()->SetPoint(13, 1, 0.5, 1);
  hex->GetPoints()->SetPoint(14, 0.5, 1, 1);
  hex->GetPoints()->SetPoint(15, 0, 0.5, 1);
  hex->GetPoints()->SetPoint(16, 0, 0, 0.5);
  hex->GetPoints()->SetPoint(17, 1, 0, 0.5);
  hex->GetPoints()->SetPoint(18, 1, 1, 0.5);
  hex->GetPoints()->SetPoint(19, 0, 1, 0.5);

  hex->EvaluatePosition(hexPoint[0], hexClosest, subId, hexPCoords,
                         dist2, hexWeights);

  strm << "Test vtkCell::EvaluatePosition End" << endl;

  //-------------------------------------------------------------
  strm << "Test vtkCell::EvaluateLocation Start" << endl;
  // vtkQuadraticEdge
  edge->EvaluateLocation(subId, edgePCoords, edgePosition, edgeWeights);

  // vtkQuadraticTriangle
  tri->EvaluateLocation(subId, triPCoords, triPosition, triWeights);

  // vtkQuadraticQuad
  quad->EvaluateLocation(subId, quadPCoords, quadPosition, quadWeights);

  // vtkQuadraticTetra
  tetra->EvaluateLocation(subId, tetraPCoords, tetraPosition, tetraWeights);

  // vtkQuadraticHexahedron
  hexPCoords[0] = 0.25;
  hexPCoords[1] = 0.33;
  hexPCoords[2] = 0.75;
  hex->EvaluateLocation(subId, hexPCoords, hexPosition, hexWeights);

  strm << "Test vtkCell::EvaluateLocation End" << endl;

  //-------------------------------------------------------------
  strm << "Test vtkCell::CellDerivs Start" << endl;

  // vtkQuadraticEdge - temporarily commented out
//  float edgeValues[3], edgeDerivs[3];
//  ComputeDataValues(edge->Points,edgeValues);
//  edge->Derivatives(subId, edgePCoords, edgeValues, 1, edgeDerivs);

  // vtkQuadraticTriangle
  float triValues[6], triDerivs[3];
  ComputeDataValues(tri->Points,triValues);
  tri->Derivatives(subId, triPCoords, triValues, 1, triDerivs);

  // vtkQuadraticQuad
  float quadValues[8], quadDerivs[3];
  ComputeDataValues(quad->Points,quadValues);
  quad->Derivatives(subId, quadPCoords, quadValues, 1, quadDerivs);

  // vtkQuadraticTetra
  float tetraValues[10], tetraDerivs[3];
  ComputeDataValues(tetra->Points,tetraValues);
  tetra->Derivatives(subId, tetraPCoords, tetraValues, 1, tetraDerivs);

  // vtkQuadraticHexahedron
  float hexValues[20], hexDerivs[3];
  ComputeDataValues(hex->Points,hexValues);
  hex->Derivatives(subId, hexPCoords, hexValues, 1, hexDerivs);

  strm << "Test vtkCell::CellDerivs End" << endl;

  edge->Delete();
  tri->Delete();
  quad->Delete();
  tetra->Delete();
  hex->Delete();

  return 0;
}

int quadraticEvaluation(int,char *[])
{
  vtkDebugLeaks::PromptUserOff();

  ostrstream vtkmsg;
  return TestQE(vtkmsg);
}
<|endoftext|>


<commit_before>#ifndef FEK_SIGNALS_HPP
#define FEK_SIGNALS_HPP

// posix
#if !defined(NDEBUG)
#include <unistd.h> // write, STDOUT_FILENO, only for debugging
#endif

// libc
#include <csignal>
#include <cassert>

// std

/// signal handlers
// https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=3903
// https://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler

/// reloads configuration:
// https://en.wikipedia.org/wiki/Unix_signal#SIGHUP

enum reload_conf_stat : sig_atomic_t {
	done, // should be first "valid" status, reset to this status when finische loading configuration
	reload, // intermediary status while loading configuration
	reloading, // should be last "valid" status, used for avoiding to update config when already updating it
};

static volatile sig_atomic_t g_reload_conf_flag = reload_conf_stat::done;
inline void handle_SIGHUP(const int sig){
	assert(sig == SIGHUP && "signal handler not registered corretcly");
	if(sig != SIGHUP){
		return;
	}
#if !defined(NDEBUG)
	const char msg[] = "received SIGHUP signal";
	write(1, msg, sizeof(msg)-1); // strlen is not "signal safe" on posix, 1 is stdout
#endif
	 // do not update if reloading or already set on reload
	auto new_flag = g_reload_conf_flag;
	new_flag = (new_flag == reload_conf_stat::done) ? reload_conf_stat::reloading : new_flag;
	g_reload_conf_flag = new_flag;
}

enum sig_int_stat : sig_atomic_t{
	not_received,
	received,
};
static volatile sig_atomic_t g_sig_int_flag = sig_int_stat::not_received;
inline void handle_SIGINT(const int sig){
	assert(sig == SIGINT && "signal handler not registered corretcly");
	if (sig != SIGINT) {
		return;
	}
#if !defined(NDEBUG)
	const char msg[] = "received SIGINT signal";
	write(STDOUT_FILENO, msg, sizeof(msg)-1); // strlen is not "signal safe" on posix
#endif
	g_sig_int_flag = sig_int_stat::received;
}

#endif
<commit_msg>updated comments, flag was not set correctly<commit_after>#ifndef FEK_SIGNALS_HPP
#define FEK_SIGNALS_HPP

// posix
#if !defined(NDEBUG)
#include <unistd.h> // write, STDOUT_FILENO, only for debugging
#endif

// libc
#include <csignal>
#include <cassert>

// std

/// signal handlers
// https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=3903
// https://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler

/// reloads configuration:
// https://en.wikipedia.org/wiki/Unix_signal#SIGHUP

enum reload_conf_stat : sig_atomic_t {
	done,      // reset to this status when finished loading configuration
	reload,    // the event loop will reload the cofiguration if this value has been set
	reloading, // intermediary status while loading configuration, used for avoiding to update config when already updating it
};

static volatile sig_atomic_t g_reload_conf_flag = reload_conf_stat::done;
inline void handle_SIGHUP(const int sig){
	assert(sig == SIGHUP && "signal handler not registered corretcly");
	if(sig != SIGHUP){
		return;
	}
#if !defined(NDEBUG)
	const char msg[] = "received SIGHUP signal";
	write(1, msg, sizeof(msg)-1); // strlen is not "signal safe" on posix, 1 is stdout
#endif
	 // do not update if reloading or already set on reload (and therefore not reloaded yet)
	auto new_flag = g_reload_conf_flag;
	new_flag = (new_flag == reload_conf_stat::done) ? reload_conf_stat::reload : new_flag;
	g_reload_conf_flag = new_flag;
}

enum sig_int_stat : sig_atomic_t{
	not_received,
	received,
};
static volatile sig_atomic_t g_sig_int_flag = sig_int_stat::not_received;
inline void handle_SIGINT(const int sig){
	assert(sig == SIGINT && "signal handler not registered corretcly");
	if (sig != SIGINT) {
		return;
	}
#if !defined(NDEBUG)
	const char msg[] = "received SIGINT signal";
	write(STDOUT_FILENO, msg, sizeof(msg)-1); // strlen is not "signal safe" on posix
#endif
	g_sig_int_flag = sig_int_stat::received;
}

#endif
<|endoftext|>


<commit_before>/***********************************************************************
    filename:   CEGUIFalWidgetLookFeel.cpp
    created:    Mon Jun 13 2005
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "falagard/CEGUIFalWidgetLookFeel.h"
#include "CEGUIExceptions.h"
#include "CEGUILogger.h"
#include "CEGUIWindowManager.h"
#include "CEGUIAnimationManager.h"
#include "CEGUIAnimationInstance.h"
#include <iostream>
#include <algorithm>

// Start of CEGUI namespace section
namespace CEGUI
{
    WidgetLookFeel::WidgetLookFeel(const String& name) :
        d_lookName(name)
    {}

    const StateImagery& WidgetLookFeel::getStateImagery(const CEGUI::String& state) const
    {
        StateList::const_iterator imagery = d_stateImagery.find(state);

        if (imagery == d_stateImagery.end())
        {
            CEGUI_THROW(UnknownObjectException("WidgetLookFeel::getStateImagery - unknown state '" + state + "' in look '" + d_lookName + "'."));
        }

        return (*imagery).second;
    }

    const ImagerySection& WidgetLookFeel::getImagerySection(const CEGUI::String& section) const
    {
        ImageryList::const_iterator imgSect = d_imagerySections.find(section);

        if (imgSect == d_imagerySections.end())
        {
            CEGUI_THROW(UnknownObjectException("WidgetLookFeel::getImagerySection - unknown imagery section '" + section +  "' in look '" + d_lookName + "'."));
        }

        return (*imgSect).second;
    }

    const String& WidgetLookFeel::getName() const
    {
        return d_lookName;
    }

    void WidgetLookFeel::addImagerySection(const ImagerySection& section)
    {
        if (d_imagerySections.find(section.getName()) != d_imagerySections.end())
        {
            Logger::getSingleton().logEvent(
                "WidgetLookFeel::addImagerySection - Defintion for imagery section '" + section.getName() + "' already exists.  Replacing previous definition.");
        }

        d_imagerySections[section.getName()] = section;
    }

    void WidgetLookFeel::addWidgetComponent(const WidgetComponent& widget)
    {
        d_childWidgets.push_back(widget);
    }

    void WidgetLookFeel::addStateSpecification(const StateImagery& state)
    {
        if (d_stateImagery.find(state.getName()) != d_stateImagery.end())
        {
            Logger::getSingleton().logEvent(
                "WidgetLookFeel::addStateSpecification - Defintion for state '" + state.getName() + "' already exists.  Replacing previous definition.");
        }

        d_stateImagery[state.getName()] = state;
    }

    void WidgetLookFeel::addPropertyInitialiser(const PropertyInitialiser& initialiser)
    {
        d_properties.push_back(initialiser);
    }

    void WidgetLookFeel::clearImagerySections()
    {
        d_imagerySections.clear();
    }

    void WidgetLookFeel::clearWidgetComponents()
    {
        d_childWidgets.clear();
    }

    void WidgetLookFeel::clearStateSpecifications()
    {
        d_stateImagery.clear();
    }

    void WidgetLookFeel::clearPropertyInitialisers()
    {
        d_properties.clear();
    }

    /*************************************************************************
        Initialise a widget for this look'n'feel
    *************************************************************************/
    void WidgetLookFeel::initialiseWidget(Window& widget) const
    {
        // add required child widgets
        for(WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
        {
            (*curr).create(widget);
        }

        // add new property definitions
        for(PropertyDefinitionList::iterator propdef = d_propertyDefinitions.begin(); propdef != d_propertyDefinitions.end(); ++propdef)
        {
            // add the property to the window
            widget.addProperty(&(*propdef));
            // write default value to get things set up properly
            widget.setProperty((*propdef).getName(), (*propdef).getDefault(&widget));
        }

        // add new property link definitions
        for(PropertyLinkDefinitionList::iterator linkdef = d_propertyLinkDefinitions.begin(); linkdef != d_propertyLinkDefinitions.end(); ++linkdef)
        {
            // add the property to the window
            widget.addProperty(&(*linkdef));
            // write default value to get things set up properly
            widget.setProperty((*linkdef).getName(), (*linkdef).getDefault(&widget));
        }

        // apply properties to the parent window
        for(PropertyList::const_iterator prop = d_properties.begin(); prop != d_properties.end(); ++prop)
        {
            (*prop).apply(widget);
        }

        // create animation instances
        for (AnimationList::const_iterator anim = d_animations.begin(); anim != d_animations.end(); ++anim)
        {
            AnimationInstance* instance =
                AnimationManager::getSingleton().instantiateAnimation(*anim);

            d_animationInstances.insert(std::make_pair(&widget, instance));
            instance->setTargetWindow(&widget);
        }

    }

    /*************************************************************************
        Clean up a widget currently using this look'n'feel
    *************************************************************************/
    void WidgetLookFeel::cleanUpWidget(Window& widget) const
    {
        if (widget.getLookNFeel() != getName())
        {
            CEGUI_THROW(InvalidRequestException(
                "WidgetLookFeel::cleanUpWidget - The window '"
                + widget.getName() +
                "' does not have this look'n'feel assigned"));
        }

        // remove added child widgets
        for(WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
        {
            WindowManager::getSingleton().destroyWindow(widget.getName() + (*curr).getWidgetNameSuffix());
        }

        // remove added property definitions
        for(PropertyDefinitionList::iterator propdef = d_propertyDefinitions.begin(); propdef != d_propertyDefinitions.end(); ++propdef)
        {
            // remove the property from the window
            widget.removeProperty((*propdef).getName());
        }

        // remove added property link definitions
        for(PropertyLinkDefinitionList::iterator linkdef = d_propertyLinkDefinitions.begin(); linkdef != d_propertyLinkDefinitions.end(); ++linkdef)
        {
            // remove the property from the window
            widget.removeProperty((*linkdef).getName());
        }

        // clean up animation instances assoicated wit the window.
        AnimationInstanceMap::iterator anim;
        while ((anim = d_animationInstances.find(&widget)) != d_animationInstances.end())
        {
            AnimationManager::getSingleton().destroyAnimationInstance(anim->second);
            d_animationInstances.erase(anim);
        }
    }

    bool WidgetLookFeel::isStateImageryPresent(const String& state) const
    {
        return d_stateImagery.find(state) != d_stateImagery.end();
    }

    void WidgetLookFeel::addNamedArea(const NamedArea& area)
    {
        if (d_namedAreas.find(area.getName()) != d_namedAreas.end())
        {
            Logger::getSingleton().logEvent(
                "WidgetLookFeel::addNamedArea - Defintion for area '" + area.getName() + "' already exists.  Replacing previous definition.");
        }

        d_namedAreas[area.getName()] = area;
    }

    void WidgetLookFeel::clearNamedAreas()
    {
        d_namedAreas.clear();
    }

    const NamedArea& WidgetLookFeel::getNamedArea(const String& name) const
    {
        NamedAreaList::const_iterator area = d_namedAreas.find(name);

        if (area == d_namedAreas.end())
        {
            CEGUI_THROW(UnknownObjectException("WidgetLookFeel::getNamedArea - unknown named area: '" + name +  "' in look '" + d_lookName + "'."));
        }

        return (*area).second;
    }

    bool WidgetLookFeel::isNamedAreaDefined(const String& name) const
    {
        return d_namedAreas.find(name) != d_namedAreas.end();
    }

    void WidgetLookFeel::layoutChildWidgets(const Window& owner) const
    {
        // apply properties to the parent window
        for(WidgetList::const_iterator wdgt = d_childWidgets.begin(); wdgt != d_childWidgets.end(); ++wdgt)
        {
            (*wdgt).layout(owner);
        }
    }

    void WidgetLookFeel::addPropertyDefinition(const PropertyDefinition& propdef)
    {
        d_propertyDefinitions.push_back(propdef);
    }

    void WidgetLookFeel::clearPropertyDefinitions()
    {
        d_propertyDefinitions.clear();
    }

    void WidgetLookFeel::addPropertyLinkDefinition(const PropertyLinkDefinition& propdef)
    {
        d_propertyLinkDefinitions.push_back(propdef);
    }

    void WidgetLookFeel::clearPropertyLinkDefinitions()
    {
        d_propertyLinkDefinitions.clear();
    }

    void WidgetLookFeel::writeXMLToStream(XMLSerializer& xml_stream) const
    {

        xml_stream.openTag("WidgetLook")
                .attribute("name", d_lookName);

        // These sub-scobes of the loops avoid the "'curr'-already-initialized" compile error on VC6++
        {
          // output property definitions
          for (PropertyDefinitionList::const_iterator curr = d_propertyDefinitions.begin(); curr != d_propertyDefinitions.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output property link definitions
          for (PropertyLinkDefinitionList::const_iterator curr = d_propertyLinkDefinitions.begin(); curr != d_propertyLinkDefinitions.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output property initialisers.
          for (PropertyList::const_iterator curr = d_properties.begin(); curr != d_properties.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output named areas
          for (NamedAreaList::const_iterator curr = d_namedAreas.begin(); curr != d_namedAreas.end(); ++curr)
              (*curr).second.writeXMLToStream(xml_stream);
        }

        {
          // output child widgets
          for (WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output imagery sections
          for (ImageryList::const_iterator curr = d_imagerySections.begin(); curr != d_imagerySections.end(); ++curr)
              (*curr).second.writeXMLToStream(xml_stream);
        }

        {
          // output states
          for (StateList::const_iterator curr = d_stateImagery.begin(); curr != d_stateImagery.end(); ++curr)
              (*curr).second.writeXMLToStream(xml_stream);
        }

        xml_stream.closeTag();
    }

    void WidgetLookFeel::renameChildren(const Window& widget, const String& newBaseName) const
    {
        WindowManager& winMgr = WindowManager::getSingleton();

        for(WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
            winMgr.renameWindow(widget.getName() + (*curr).getWidgetNameSuffix(),
                                newBaseName + (*curr).getWidgetNameSuffix());
    }

    const PropertyInitialiser* WidgetLookFeel::findPropertyInitialiser(const String& propertyName) const
    {
        PropertyList::const_reverse_iterator i = d_properties.rbegin();
        while (i != d_properties.rend())
        {
            if ((*i).getTargetPropertyName() == propertyName)
                return &(*i);
            ++i;
        }
        return 0;
    }

    const WidgetComponent* WidgetLookFeel::findWidgetComponent(const String& nameSuffix) const
    {
        WidgetList::const_iterator i = d_childWidgets.begin();
        while (i != d_childWidgets.end())
        {
            if ((*i).getWidgetNameSuffix() == nameSuffix)
                return &(*i);
            ++i;
        }
        return 0;
    }

    void WidgetLookFeel::addAnimationName(const String& anim_name)
    {
        AnimationList::iterator it = std::find(d_animations.begin(),
                                               d_animations.end(),
                                               anim_name);

        if (it == d_animations.end())
            d_animations.push_back(anim_name);
    }

} // End of  CEGUI namespace section
<commit_msg>FIX: Ensure properties defined via PropertyDefinition are added to the target widget first, to avoid situations where they might be accessed before they are added.  See: http://www.cegui.org.uk/phpBB2/viewtopic.php?f=10&t=6019<commit_after>/***********************************************************************
    filename:   CEGUIFalWidgetLookFeel.cpp
    created:    Mon Jun 13 2005
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "falagard/CEGUIFalWidgetLookFeel.h"
#include "CEGUIExceptions.h"
#include "CEGUILogger.h"
#include "CEGUIWindowManager.h"
#include "CEGUIAnimationManager.h"
#include "CEGUIAnimationInstance.h"
#include <iostream>
#include <algorithm>

// Start of CEGUI namespace section
namespace CEGUI
{
    WidgetLookFeel::WidgetLookFeel(const String& name) :
        d_lookName(name)
    {}

    const StateImagery& WidgetLookFeel::getStateImagery(const CEGUI::String& state) const
    {
        StateList::const_iterator imagery = d_stateImagery.find(state);

        if (imagery == d_stateImagery.end())
        {
            CEGUI_THROW(UnknownObjectException("WidgetLookFeel::getStateImagery - unknown state '" + state + "' in look '" + d_lookName + "'."));
        }

        return (*imagery).second;
    }

    const ImagerySection& WidgetLookFeel::getImagerySection(const CEGUI::String& section) const
    {
        ImageryList::const_iterator imgSect = d_imagerySections.find(section);

        if (imgSect == d_imagerySections.end())
        {
            CEGUI_THROW(UnknownObjectException("WidgetLookFeel::getImagerySection - unknown imagery section '" + section +  "' in look '" + d_lookName + "'."));
        }

        return (*imgSect).second;
    }

    const String& WidgetLookFeel::getName() const
    {
        return d_lookName;
    }

    void WidgetLookFeel::addImagerySection(const ImagerySection& section)
    {
        if (d_imagerySections.find(section.getName()) != d_imagerySections.end())
        {
            Logger::getSingleton().logEvent(
                "WidgetLookFeel::addImagerySection - Defintion for imagery section '" + section.getName() + "' already exists.  Replacing previous definition.");
        }

        d_imagerySections[section.getName()] = section;
    }

    void WidgetLookFeel::addWidgetComponent(const WidgetComponent& widget)
    {
        d_childWidgets.push_back(widget);
    }

    void WidgetLookFeel::addStateSpecification(const StateImagery& state)
    {
        if (d_stateImagery.find(state.getName()) != d_stateImagery.end())
        {
            Logger::getSingleton().logEvent(
                "WidgetLookFeel::addStateSpecification - Defintion for state '" + state.getName() + "' already exists.  Replacing previous definition.");
        }

        d_stateImagery[state.getName()] = state;
    }

    void WidgetLookFeel::addPropertyInitialiser(const PropertyInitialiser& initialiser)
    {
        d_properties.push_back(initialiser);
    }

    void WidgetLookFeel::clearImagerySections()
    {
        d_imagerySections.clear();
    }

    void WidgetLookFeel::clearWidgetComponents()
    {
        d_childWidgets.clear();
    }

    void WidgetLookFeel::clearStateSpecifications()
    {
        d_stateImagery.clear();
    }

    void WidgetLookFeel::clearPropertyInitialisers()
    {
        d_properties.clear();
    }

    /*************************************************************************
        Initialise a widget for this look'n'feel
    *************************************************************************/
    void WidgetLookFeel::initialiseWidget(Window& widget) const
    {
        // add new property definitions
        for(PropertyDefinitionList::iterator propdef = d_propertyDefinitions.begin(); propdef != d_propertyDefinitions.end(); ++propdef)
        {
            // add the property to the window
            widget.addProperty(&(*propdef));
            // write default value to get things set up properly
            widget.setProperty((*propdef).getName(), (*propdef).getDefault(&widget));
        }

        // add required child widgets
        for(WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
        {
            (*curr).create(widget);
        }

        // add new property link definitions
        for(PropertyLinkDefinitionList::iterator linkdef = d_propertyLinkDefinitions.begin(); linkdef != d_propertyLinkDefinitions.end(); ++linkdef)
        {
            // add the property to the window
            widget.addProperty(&(*linkdef));
            // write default value to get things set up properly
            widget.setProperty((*linkdef).getName(), (*linkdef).getDefault(&widget));
        }

        // apply properties to the parent window
        for(PropertyList::const_iterator prop = d_properties.begin(); prop != d_properties.end(); ++prop)
        {
            (*prop).apply(widget);
        }

        // create animation instances
        for (AnimationList::const_iterator anim = d_animations.begin(); anim != d_animations.end(); ++anim)
        {
            AnimationInstance* instance =
                AnimationManager::getSingleton().instantiateAnimation(*anim);

            d_animationInstances.insert(std::make_pair(&widget, instance));
            instance->setTargetWindow(&widget);
        }

    }

    /*************************************************************************
        Clean up a widget currently using this look'n'feel
    *************************************************************************/
    void WidgetLookFeel::cleanUpWidget(Window& widget) const
    {
        if (widget.getLookNFeel() != getName())
        {
            CEGUI_THROW(InvalidRequestException(
                "WidgetLookFeel::cleanUpWidget - The window '"
                + widget.getName() +
                "' does not have this look'n'feel assigned"));
        }

        // remove added child widgets
        for(WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
        {
            WindowManager::getSingleton().destroyWindow(widget.getName() + (*curr).getWidgetNameSuffix());
        }

        // remove added property definitions
        for(PropertyDefinitionList::iterator propdef = d_propertyDefinitions.begin(); propdef != d_propertyDefinitions.end(); ++propdef)
        {
            // remove the property from the window
            widget.removeProperty((*propdef).getName());
        }

        // remove added property link definitions
        for(PropertyLinkDefinitionList::iterator linkdef = d_propertyLinkDefinitions.begin(); linkdef != d_propertyLinkDefinitions.end(); ++linkdef)
        {
            // remove the property from the window
            widget.removeProperty((*linkdef).getName());
        }

        // clean up animation instances assoicated wit the window.
        AnimationInstanceMap::iterator anim;
        while ((anim = d_animationInstances.find(&widget)) != d_animationInstances.end())
        {
            AnimationManager::getSingleton().destroyAnimationInstance(anim->second);
            d_animationInstances.erase(anim);
        }
    }

    bool WidgetLookFeel::isStateImageryPresent(const String& state) const
    {
        return d_stateImagery.find(state) != d_stateImagery.end();
    }

    void WidgetLookFeel::addNamedArea(const NamedArea& area)
    {
        if (d_namedAreas.find(area.getName()) != d_namedAreas.end())
        {
            Logger::getSingleton().logEvent(
                "WidgetLookFeel::addNamedArea - Defintion for area '" + area.getName() + "' already exists.  Replacing previous definition.");
        }

        d_namedAreas[area.getName()] = area;
    }

    void WidgetLookFeel::clearNamedAreas()
    {
        d_namedAreas.clear();
    }

    const NamedArea& WidgetLookFeel::getNamedArea(const String& name) const
    {
        NamedAreaList::const_iterator area = d_namedAreas.find(name);

        if (area == d_namedAreas.end())
        {
            CEGUI_THROW(UnknownObjectException("WidgetLookFeel::getNamedArea - unknown named area: '" + name +  "' in look '" + d_lookName + "'."));
        }

        return (*area).second;
    }

    bool WidgetLookFeel::isNamedAreaDefined(const String& name) const
    {
        return d_namedAreas.find(name) != d_namedAreas.end();
    }

    void WidgetLookFeel::layoutChildWidgets(const Window& owner) const
    {
        // apply properties to the parent window
        for(WidgetList::const_iterator wdgt = d_childWidgets.begin(); wdgt != d_childWidgets.end(); ++wdgt)
        {
            (*wdgt).layout(owner);
        }
    }

    void WidgetLookFeel::addPropertyDefinition(const PropertyDefinition& propdef)
    {
        d_propertyDefinitions.push_back(propdef);
    }

    void WidgetLookFeel::clearPropertyDefinitions()
    {
        d_propertyDefinitions.clear();
    }

    void WidgetLookFeel::addPropertyLinkDefinition(const PropertyLinkDefinition& propdef)
    {
        d_propertyLinkDefinitions.push_back(propdef);
    }

    void WidgetLookFeel::clearPropertyLinkDefinitions()
    {
        d_propertyLinkDefinitions.clear();
    }

    void WidgetLookFeel::writeXMLToStream(XMLSerializer& xml_stream) const
    {

        xml_stream.openTag("WidgetLook")
                .attribute("name", d_lookName);

        // These sub-scobes of the loops avoid the "'curr'-already-initialized" compile error on VC6++
        {
          // output property definitions
          for (PropertyDefinitionList::const_iterator curr = d_propertyDefinitions.begin(); curr != d_propertyDefinitions.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output property link definitions
          for (PropertyLinkDefinitionList::const_iterator curr = d_propertyLinkDefinitions.begin(); curr != d_propertyLinkDefinitions.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output property initialisers.
          for (PropertyList::const_iterator curr = d_properties.begin(); curr != d_properties.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output named areas
          for (NamedAreaList::const_iterator curr = d_namedAreas.begin(); curr != d_namedAreas.end(); ++curr)
              (*curr).second.writeXMLToStream(xml_stream);
        }

        {
          // output child widgets
          for (WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
              (*curr).writeXMLToStream(xml_stream);
        }

        {
          // output imagery sections
          for (ImageryList::const_iterator curr = d_imagerySections.begin(); curr != d_imagerySections.end(); ++curr)
              (*curr).second.writeXMLToStream(xml_stream);
        }

        {
          // output states
          for (StateList::const_iterator curr = d_stateImagery.begin(); curr != d_stateImagery.end(); ++curr)
              (*curr).second.writeXMLToStream(xml_stream);
        }

        xml_stream.closeTag();
    }

    void WidgetLookFeel::renameChildren(const Window& widget, const String& newBaseName) const
    {
        WindowManager& winMgr = WindowManager::getSingleton();

        for(WidgetList::const_iterator curr = d_childWidgets.begin(); curr != d_childWidgets.end(); ++curr)
            winMgr.renameWindow(widget.getName() + (*curr).getWidgetNameSuffix(),
                                newBaseName + (*curr).getWidgetNameSuffix());
    }

    const PropertyInitialiser* WidgetLookFeel::findPropertyInitialiser(const String& propertyName) const
    {
        PropertyList::const_reverse_iterator i = d_properties.rbegin();
        while (i != d_properties.rend())
        {
            if ((*i).getTargetPropertyName() == propertyName)
                return &(*i);
            ++i;
        }
        return 0;
    }

    const WidgetComponent* WidgetLookFeel::findWidgetComponent(const String& nameSuffix) const
    {
        WidgetList::const_iterator i = d_childWidgets.begin();
        while (i != d_childWidgets.end())
        {
            if ((*i).getWidgetNameSuffix() == nameSuffix)
                return &(*i);
            ++i;
        }
        return 0;
    }

    void WidgetLookFeel::addAnimationName(const String& anim_name)
    {
        AnimationList::iterator it = std::find(d_animations.begin(),
                                               d_animations.end(),
                                               anim_name);

        if (it == d_animations.end())
            d_animations.push_back(anim_name);
    }

} // End of  CEGUI namespace section
<|endoftext|>


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

#include "config.h"
#include "TestInterfaces.h"

#include "AccessibilityControllerChromium.h"
#include "EventSender.h"
#include "GamepadController.h"
#include "TestRunner.h"
#include "TextInputController.h"
#include "WebCache.h"
#include "WebKit.h"
#include "WebRuntimeFeatures.h"
#include <public/WebString.h>
#include <public/WebURL.h>
#include <string>

using namespace WebKit;
using namespace std;

namespace WebTestRunner {

TestInterfaces::TestInterfaces()
    : m_accessibilityController(new AccessibilityController())
    , m_eventSender(new EventSender())
    , m_gamepadController(new GamepadController())
    , m_textInputController(new TextInputController())
    , m_testRunner(new TestRunner(this))
    , m_webView(0)
    , m_delegate(0)
{
    WebKit::setLayoutTestMode(true);

    WebRuntimeFeatures::enableDeviceMotion(false);
    WebRuntimeFeatures::enableGeolocation(true);
    WebRuntimeFeatures::enableIndexedDatabase(true);
    WebRuntimeFeatures::enableInputTypeDateTime(true);
    WebRuntimeFeatures::enableInputTypeWeek(true);
    WebRuntimeFeatures::enableFileSystem(true);
    WebRuntimeFeatures::enableFontLoadEvents(true);
    WebRuntimeFeatures::enableJavaScriptI18NAPI(true);
    WebRuntimeFeatures::enableMediaSource(true);
    WebRuntimeFeatures::enableEncryptedMedia(true);
    WebRuntimeFeatures::enableMediaStream(true);
    WebRuntimeFeatures::enablePeerConnection(true);
    WebRuntimeFeatures::enableWebAudio(true);
    WebRuntimeFeatures::enableWebMIDI(true);
    WebRuntimeFeatures::enableVideoTrack(true);
    WebRuntimeFeatures::enableGamepad(true);
    WebRuntimeFeatures::enableCustomDOMElements(true);
    WebRuntimeFeatures::enableStyleScoped(true);
    WebRuntimeFeatures::enableScriptedSpeech(true);
    WebRuntimeFeatures::enableRequestAutocomplete(true);
    WebRuntimeFeatures::enableExperimentalContentSecurityPolicyFeatures(true);
    WebRuntimeFeatures::enableSeamlessIFrames(true);
    WebRuntimeFeatures::enableCanvasPath(true);

    resetAll();
}

TestInterfaces::~TestInterfaces()
{
    m_accessibilityController->setWebView(0);
    m_eventSender->setWebView(0);
    // m_gamepadController doesn't depend on WebView.
    m_textInputController->setWebView(0);
    m_testRunner->setWebView(0, 0);

    m_accessibilityController->setDelegate(0);
    m_eventSender->setDelegate(0);
    m_gamepadController->setDelegate(0);
    // m_textInputController doesn't depend on WebTestDelegate.
    m_testRunner->setDelegate(0);
}

void TestInterfaces::setWebView(WebView* webView, WebTestProxyBase* proxy)
{
    m_webView = webView;
    m_proxy = proxy;
    m_accessibilityController->setWebView(webView);
    m_eventSender->setWebView(webView);
    // m_gamepadController doesn't depend on WebView.
    m_textInputController->setWebView(webView);
    m_testRunner->setWebView(webView, proxy);
}

void TestInterfaces::setDelegate(WebTestDelegate* delegate)
{
    m_accessibilityController->setDelegate(delegate);
    m_eventSender->setDelegate(delegate);
    m_gamepadController->setDelegate(delegate);
    // m_textInputController doesn't depend on WebTestDelegate.
    m_testRunner->setDelegate(delegate);
    m_delegate = delegate;
}

void TestInterfaces::bindTo(WebFrame* frame)
{
    m_accessibilityController->bindToJavascript(frame, WebString::fromUTF8("accessibilityController"));
    m_eventSender->bindToJavascript(frame, WebString::fromUTF8("eventSender"));
    m_gamepadController->bindToJavascript(frame, WebString::fromUTF8("gamepadController"));
    m_textInputController->bindToJavascript(frame, WebString::fromUTF8("textInputController"));
    m_testRunner->bindToJavascript(frame, WebString::fromUTF8("testRunner"));
    m_testRunner->bindToJavascript(frame, WebString::fromUTF8("layoutTestController"));
}

void TestInterfaces::resetAll()
{
    m_accessibilityController->reset();
    m_eventSender->reset();
    m_gamepadController->reset();
    // m_textInputController doesn't have any state to reset.
    m_testRunner->reset();
    WebCache::clear();
}

void TestInterfaces::setTestIsRunning(bool running)
{
    m_testRunner->setTestIsRunning(running);
}

void TestInterfaces::configureForTestWithURL(const WebURL& testURL, bool generatePixels)
{
    string spec = GURL(testURL).spec();
    m_testRunner->setShouldGeneratePixelResults(generatePixels);
    if (spec.find("loading/") != string::npos)
        m_testRunner->setShouldDumpFrameLoadCallbacks(true);
    if (spec.find("/dumpAsText/") != string::npos) {
        m_testRunner->setShouldDumpAsText(true);
        m_testRunner->setShouldGeneratePixelResults(false);
    }
    if (spec.find("/inspector/") != string::npos)
        m_testRunner->showDevTools();
}

void TestInterfaces::windowOpened(WebTestProxyBase* proxy)
{
    m_windowList.push_back(proxy);
}

void TestInterfaces::windowClosed(WebTestProxyBase* proxy)
{
    vector<WebTestProxyBase*>::iterator pos = find(m_windowList.begin(), m_windowList.end(), proxy);
    if (pos == m_windowList.end()) {
        WEBKIT_ASSERT_NOT_REACHED();
        return;
    }
    m_windowList.erase(pos);
}

AccessibilityController* TestInterfaces::accessibilityController()
{
    return m_accessibilityController.get();
}

EventSender* TestInterfaces::eventSender()
{
    return m_eventSender.get();
}

TestRunner* TestInterfaces::testRunner()
{
    return m_testRunner.get();
}

WebView* TestInterfaces::webView()
{
    return m_webView;
}

WebTestDelegate* TestInterfaces::delegate()
{
    return m_delegate;
}

WebTestProxyBase* TestInterfaces::proxy()
{
    return m_proxy;
}

const vector<WebTestProxyBase*>& TestInterfaces::windowList()
{
    return m_windowList;
}

WebThemeEngine* TestInterfaces::themeEngine()
{
#if defined(USE_DEFAULT_RENDER_THEME) || !(defined(WIN32) || defined(__APPLE__))
    return 0;
#elif defined(WIN32)
    if (!m_themeEngine.get())
        m_themeEngine.reset(new WebTestThemeEngineWin());
    return m_themeEngine.get();
#elif defined(__APPLE__)
    if (!m_themeEngine.get())
        m_themeEngine.reset(new WebTestThemeEngineMac());
    return m_themeEngine.get();
#endif
}

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

#include "config.h"
#include "TestInterfaces.h"

#include "AccessibilityControllerChromium.h"
#include "EventSender.h"
#include "GamepadController.h"
#include "TestRunner.h"
#include "TextInputController.h"
#include "WebCache.h"
#include "WebKit.h"
#include "WebRuntimeFeatures.h"
#include <public/WebString.h>
#include <public/WebURL.h>
#include <string>

using namespace WebKit;
using namespace std;

namespace WebTestRunner {

TestInterfaces::TestInterfaces()
    : m_accessibilityController(new AccessibilityController())
    , m_eventSender(new EventSender())
    , m_gamepadController(new GamepadController())
    , m_textInputController(new TextInputController())
    , m_testRunner(new TestRunner(this))
    , m_webView(0)
    , m_delegate(0)
{
    WebKit::setLayoutTestMode(true);

    WebRuntimeFeatures::enableDeviceMotion(false);
    WebRuntimeFeatures::enableGeolocation(true);
    WebRuntimeFeatures::enableIndexedDatabase(true);
    WebRuntimeFeatures::enableInputTypeDateTime(true);
    WebRuntimeFeatures::enableInputTypeWeek(true);
    WebRuntimeFeatures::enableFileSystem(true);
    WebRuntimeFeatures::enableFontLoadEvents(true);
    WebRuntimeFeatures::enableJavaScriptI18NAPI(true);
    WebRuntimeFeatures::enableMediaSource(true);
    WebRuntimeFeatures::enableEncryptedMedia(true);
    WebRuntimeFeatures::enableMediaStream(true);
    WebRuntimeFeatures::enablePeerConnection(true);
    WebRuntimeFeatures::enableWebAudio(true);
    WebRuntimeFeatures::enableWebMIDI(true);
    WebRuntimeFeatures::enableVideoTrack(true);
    WebRuntimeFeatures::enableGamepad(true);
    WebRuntimeFeatures::enableCustomDOMElements(true);
    WebRuntimeFeatures::enableStyleScoped(true);
    WebRuntimeFeatures::enableScriptedSpeech(true);
    WebRuntimeFeatures::enableRequestAutocomplete(true);
    WebRuntimeFeatures::enableExperimentalContentSecurityPolicyFeatures(true);
    WebRuntimeFeatures::enableSeamlessIFrames(true);
    WebRuntimeFeatures::enableCanvasPath(true);
    WebRuntimeFeatures::enableExperimentalShadowDOM(true);

    resetAll();
}

TestInterfaces::~TestInterfaces()
{
    m_accessibilityController->setWebView(0);
    m_eventSender->setWebView(0);
    // m_gamepadController doesn't depend on WebView.
    m_textInputController->setWebView(0);
    m_testRunner->setWebView(0, 0);

    m_accessibilityController->setDelegate(0);
    m_eventSender->setDelegate(0);
    m_gamepadController->setDelegate(0);
    // m_textInputController doesn't depend on WebTestDelegate.
    m_testRunner->setDelegate(0);
}

void TestInterfaces::setWebView(WebView* webView, WebTestProxyBase* proxy)
{
    m_webView = webView;
    m_proxy = proxy;
    m_accessibilityController->setWebView(webView);
    m_eventSender->setWebView(webView);
    // m_gamepadController doesn't depend on WebView.
    m_textInputController->setWebView(webView);
    m_testRunner->setWebView(webView, proxy);
}

void TestInterfaces::setDelegate(WebTestDelegate* delegate)
{
    m_accessibilityController->setDelegate(delegate);
    m_eventSender->setDelegate(delegate);
    m_gamepadController->setDelegate(delegate);
    // m_textInputController doesn't depend on WebTestDelegate.
    m_testRunner->setDelegate(delegate);
    m_delegate = delegate;
}

void TestInterfaces::bindTo(WebFrame* frame)
{
    m_accessibilityController->bindToJavascript(frame, WebString::fromUTF8("accessibilityController"));
    m_eventSender->bindToJavascript(frame, WebString::fromUTF8("eventSender"));
    m_gamepadController->bindToJavascript(frame, WebString::fromUTF8("gamepadController"));
    m_textInputController->bindToJavascript(frame, WebString::fromUTF8("textInputController"));
    m_testRunner->bindToJavascript(frame, WebString::fromUTF8("testRunner"));
    m_testRunner->bindToJavascript(frame, WebString::fromUTF8("layoutTestController"));
}

void TestInterfaces::resetAll()
{
    m_accessibilityController->reset();
    m_eventSender->reset();
    m_gamepadController->reset();
    // m_textInputController doesn't have any state to reset.
    m_testRunner->reset();
    WebCache::clear();
}

void TestInterfaces::setTestIsRunning(bool running)
{
    m_testRunner->setTestIsRunning(running);
}

void TestInterfaces::configureForTestWithURL(const WebURL& testURL, bool generatePixels)
{
    string spec = GURL(testURL).spec();
    m_testRunner->setShouldGeneratePixelResults(generatePixels);
    if (spec.find("loading/") != string::npos)
        m_testRunner->setShouldDumpFrameLoadCallbacks(true);
    if (spec.find("/dumpAsText/") != string::npos) {
        m_testRunner->setShouldDumpAsText(true);
        m_testRunner->setShouldGeneratePixelResults(false);
    }
    if (spec.find("/inspector/") != string::npos)
        m_testRunner->showDevTools();
}

void TestInterfaces::windowOpened(WebTestProxyBase* proxy)
{
    m_windowList.push_back(proxy);
}

void TestInterfaces::windowClosed(WebTestProxyBase* proxy)
{
    vector<WebTestProxyBase*>::iterator pos = find(m_windowList.begin(), m_windowList.end(), proxy);
    if (pos == m_windowList.end()) {
        WEBKIT_ASSERT_NOT_REACHED();
        return;
    }
    m_windowList.erase(pos);
}

AccessibilityController* TestInterfaces::accessibilityController()
{
    return m_accessibilityController.get();
}

EventSender* TestInterfaces::eventSender()
{
    return m_eventSender.get();
}

TestRunner* TestInterfaces::testRunner()
{
    return m_testRunner.get();
}

WebView* TestInterfaces::webView()
{
    return m_webView;
}

WebTestDelegate* TestInterfaces::delegate()
{
    return m_delegate;
}

WebTestProxyBase* TestInterfaces::proxy()
{
    return m_proxy;
}

const vector<WebTestProxyBase*>& TestInterfaces::windowList()
{
    return m_windowList;
}

WebThemeEngine* TestInterfaces::themeEngine()
{
#if defined(USE_DEFAULT_RENDER_THEME) || !(defined(WIN32) || defined(__APPLE__))
    return 0;
#elif defined(WIN32)
    if (!m_themeEngine.get())
        m_themeEngine.reset(new WebTestThemeEngineWin());
    return m_themeEngine.get();
#elif defined(__APPLE__)
    if (!m_themeEngine.get())
        m_themeEngine.reset(new WebTestThemeEngineMac());
    return m_themeEngine.get();
#endif
}

}
<|endoftext|>


<commit_before>
#include "../../Flare.h"
#include "FlareShipStatus.h"
#include "../../Player/FlareMenuManager.h"

#define LOCTEXT_NAMESPACE "FlareShipStatus"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareShipStatus::Construct(const FArguments& InArgs)
{
	TargetShip = InArgs._Ship;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	ChildSlot
	.VAlign(VAlign_Fill)
	.HAlign(HAlign_Fill)
	.Padding(FMargin(8, 8, 32, 8))
	[
		SNew(SHorizontalBox)

		// Power icon
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SImage)
			.Image(FFlareStyleSet::GetIcon("Propulsion"))
			.ColorAndOpacity(this, &SFlareShipStatus::GetIconColor, EFlareSubsystem::SYS_Propulsion)
		]

		// RCS icon
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SImage)
			.Image(FFlareStyleSet::GetIcon("RCS"))
			.ColorAndOpacity(this, &SFlareShipStatus::GetIconColor, EFlareSubsystem::SYS_RCS)
		]

		// Weapon icon
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SAssignNew(WeaponIndicator, SImage)
			.Image(FFlareStyleSet::GetIcon("Shell"))
			.ColorAndOpacity(this, &SFlareShipStatus::GetIconColor, EFlareSubsystem::SYS_Weapon)
		]

		// Health
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SBox)
			.WidthOverride(60)
			.VAlign(VAlign_Center)
			[
				SNew(SProgressBar)
				.Percent(this, &SFlareShipStatus::GetGlobalHealth)
				.BorderPadding( FVector2D(0,0))
				.Style(&Theme.ProgressBarStyle)
			]
		]
	];

	SetVisibility(EVisibility::Hidden);
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareShipStatus::SetTargetShip(UFlareSimulatedSpacecraft* Target)
{
	TargetShip = Target;

	if (TargetShip)
	{
		SetVisibility(EVisibility::Visible);
		if (TargetShip->IsMilitary())
		{
			WeaponIndicator->SetVisibility(EVisibility::Visible);
		}
		else
		{
			WeaponIndicator->SetVisibility(EVisibility::Hidden);
		}
	}
	else
	{
		SetVisibility(EVisibility::Hidden);
	}
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

void SFlareShipStatus::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	SWidget::OnMouseEnter(MyGeometry, MouseEvent);

	AFlareMenuManager* MenuManager = AFlareMenuManager::GetSingleton();
	if (MenuManager && TargetShip)
	{
		FText Info;
		UFlareSimulatedSpacecraftDamageSystem* DamageSystem = TargetShip->GetDamageSystem();

		if (DamageSystem->IsStranded())
		{
			Info = FText::Format(LOCTEXT("ShipStrandedFormat", "{0}This ship is stranded and can't exit the sector !\n"), Info);
		}

		if (DamageSystem->IsUncontrollable())
		{
			Info = FText::Format(LOCTEXT("ShipUncontrollableFormat", "{0}This ship is uncontrollable and can't move in the local space !\n"), Info);
		}

		if (TargetShip->IsMilitary() && DamageSystem->IsDisarmed())
		{
			Info = FText::Format(LOCTEXT("ShipDisarmedFormat", "{0}This ship is disarmed and unable to fight back !\n"), Info);
		}

		for (int32 Index = EFlareSubsystem::SYS_None + 1; Index <= EFlareSubsystem::SYS_Weapon; Index++)
		{
			if (Index == EFlareSubsystem::SYS_Weapon && !TargetShip->IsMilitary())
			{
				continue;
			}
			Info = FText::Format(LOCTEXT("HealthInfoFormat", "{0}\n{1} : {2}%"),
				Info,
				UFlareSimulatedSpacecraftDamageSystem::GetSubsystemName((EFlareSubsystem::Type)Index),
				FText::AsNumber(FMath::RoundToInt(100 * DamageSystem->GetSubsystemHealth((EFlareSubsystem::Type)Index, false)))
				);
		}

		MenuManager->ShowTooltip(this, LOCTEXT("Status", "SHIP STATUS"), Info);
	}
}

void SFlareShipStatus::OnMouseLeave(const FPointerEvent& MouseEvent)
{
	SWidget::OnMouseLeave(MouseEvent);

	AFlareMenuManager* MenuManager = AFlareMenuManager::GetSingleton();
	if (MenuManager)
	{
		MenuManager->HideTooltip(this);
	}
}

TOptional<float> SFlareShipStatus::GetGlobalHealth() const
{
	if (TargetShip)
	{
		return TargetShip->GetDamageSystem()->GetGlobalHealth();
	}
	else
	{
		return 0;
	}
}

FSlateColor SFlareShipStatus::GetIconColor(EFlareSubsystem::Type Type) const
{
	FLinearColor Result = FLinearColor::Black;
	Result.A = 0.0f;

	// Ignore stations
	if (TargetShip && !TargetShip->IsStation())
	{
		bool IsIncapacitated = false;
		UFlareSimulatedSpacecraftDamageSystem* DamageSystem = TargetShip->GetDamageSystem();

		// Only those are used (see above)
		switch (Type)
		{
			case EFlareSubsystem::SYS_Propulsion:    IsIncapacitated = DamageSystem->IsStranded();         break;
			case EFlareSubsystem::SYS_RCS:           IsIncapacitated = DamageSystem->IsUncontrollable();   break;
			case EFlareSubsystem::SYS_Weapon:        IsIncapacitated = DamageSystem->IsDisarmed();         break;
			default: break;
		}

		// Show in red when disabled
		if (IsIncapacitated)
		{
			const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
			Result = Theme.DamageColor;
			Result.A = 1.0f;
		}
	}

	return Result;
}

#undef LOCTEXT_NAMESPACE
<commit_msg>#519 Fixed wrong ship status tooltip for station<commit_after>
#include "../../Flare.h"
#include "FlareShipStatus.h"
#include "../../Player/FlareMenuManager.h"

#define LOCTEXT_NAMESPACE "FlareShipStatus"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareShipStatus::Construct(const FArguments& InArgs)
{
	TargetShip = InArgs._Ship;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	ChildSlot
	.VAlign(VAlign_Fill)
	.HAlign(HAlign_Fill)
	.Padding(FMargin(8, 8, 32, 8))
	[
		SNew(SHorizontalBox)

		// Power icon
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SImage)
			.Image(FFlareStyleSet::GetIcon("Propulsion"))
			.ColorAndOpacity(this, &SFlareShipStatus::GetIconColor, EFlareSubsystem::SYS_Propulsion)
		]

		// RCS icon
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SImage)
			.Image(FFlareStyleSet::GetIcon("RCS"))
			.ColorAndOpacity(this, &SFlareShipStatus::GetIconColor, EFlareSubsystem::SYS_RCS)
		]

		// Weapon icon
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SAssignNew(WeaponIndicator, SImage)
			.Image(FFlareStyleSet::GetIcon("Shell"))
			.ColorAndOpacity(this, &SFlareShipStatus::GetIconColor, EFlareSubsystem::SYS_Weapon)
		]

		// Health
		+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SBox)
			.WidthOverride(60)
			.VAlign(VAlign_Center)
			[
				SNew(SProgressBar)
				.Percent(this, &SFlareShipStatus::GetGlobalHealth)
				.BorderPadding( FVector2D(0,0))
				.Style(&Theme.ProgressBarStyle)
			]
		]
	];

	SetVisibility(EVisibility::Hidden);
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareShipStatus::SetTargetShip(UFlareSimulatedSpacecraft* Target)
{
	TargetShip = Target;

	if (TargetShip)
	{
		SetVisibility(EVisibility::Visible);
		if (TargetShip->IsMilitary())
		{
			WeaponIndicator->SetVisibility(EVisibility::Visible);
		}
		else
		{
			WeaponIndicator->SetVisibility(EVisibility::Hidden);
		}
	}
	else
	{
		SetVisibility(EVisibility::Hidden);
	}
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

void SFlareShipStatus::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	SWidget::OnMouseEnter(MyGeometry, MouseEvent);

	AFlareMenuManager* MenuManager = AFlareMenuManager::GetSingleton();
	if (MenuManager && TargetShip)
	{
		FText Info;
		UFlareSimulatedSpacecraftDamageSystem* DamageSystem = TargetShip->GetDamageSystem();

		// Station-specific damage & info
		if (TargetShip->IsStation())
		{
			// Structure
			Info = FText::Format(LOCTEXT("HealthInfoFormat", "Structure : {0}{1}%"),
				Info,
				FText::AsNumber(FMath::RoundToInt(100 * DamageSystem->GetGlobalHealth())));
		}

		// Ship-specific damage
		else
		{
			if (DamageSystem->IsStranded())
			{
				Info = FText::Format(LOCTEXT("ShipStrandedFormat", "{0}This ship is stranded and can't exit the sector !\n"), Info);
			}

			if (DamageSystem->IsUncontrollable())
			{
				Info = FText::Format(LOCTEXT("ShipUncontrollableFormat", "{0}This ship is uncontrollable and can't move in the local space !\n"), Info);
			}

			if (TargetShip->IsMilitary() && DamageSystem->IsDisarmed())
			{
				Info = FText::Format(LOCTEXT("ShipDisarmedFormat", "{0}This ship is disarmed and unable to fight back !\n"), Info);
			}

			// Subsystems
			for (int32 Index = EFlareSubsystem::SYS_None + 1; Index <= EFlareSubsystem::SYS_Weapon; Index++)
			{
				if (Index == EFlareSubsystem::SYS_Weapon && !TargetShip->IsMilitary())
				{
					continue;
				}
				Info = FText::Format(LOCTEXT("HealthInfoFormat", "{0}\n{1} : {2}%"),
					Info,
					UFlareSimulatedSpacecraftDamageSystem::GetSubsystemName((EFlareSubsystem::Type)Index),
					FText::AsNumber(FMath::RoundToInt(100 * DamageSystem->GetSubsystemHealth((EFlareSubsystem::Type)Index, false))));
			}
		}

		MenuManager->ShowTooltip(this, LOCTEXT("Status", "SPACECRAFT STATUS"), Info);
	}
}

void SFlareShipStatus::OnMouseLeave(const FPointerEvent& MouseEvent)
{
	SWidget::OnMouseLeave(MouseEvent);

	AFlareMenuManager* MenuManager = AFlareMenuManager::GetSingleton();
	if (MenuManager)
	{
		MenuManager->HideTooltip(this);
	}
}

TOptional<float> SFlareShipStatus::GetGlobalHealth() const
{
	if (TargetShip)
	{
		return TargetShip->GetDamageSystem()->GetGlobalHealth();
	}
	else
	{
		return 0;
	}
}

FSlateColor SFlareShipStatus::GetIconColor(EFlareSubsystem::Type Type) const
{
	FLinearColor Result = FLinearColor::Black;
	Result.A = 0.0f;

	// Ignore stations
	if (TargetShip && !TargetShip->IsStation())
	{
		bool IsIncapacitated = false;
		UFlareSimulatedSpacecraftDamageSystem* DamageSystem = TargetShip->GetDamageSystem();

		// Only those are used (see above)
		switch (Type)
		{
			case EFlareSubsystem::SYS_Propulsion:    IsIncapacitated = DamageSystem->IsStranded();         break;
			case EFlareSubsystem::SYS_RCS:           IsIncapacitated = DamageSystem->IsUncontrollable();   break;
			case EFlareSubsystem::SYS_Weapon:        IsIncapacitated = DamageSystem->IsDisarmed();         break;
			default: break;
		}

		// Show in red when disabled
		if (IsIncapacitated)
		{
			const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
			Result = Theme.DamageColor;
			Result.A = 1.0f;
		}
	}

	return Result;
}

#undef LOCTEXT_NAMESPACE
<|endoftext|>