<commit_before>/***************************************************************************
 *   Copyright (c) 2019 WandererFan <wandererfan@gmail.com>                *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS_Edge.hxx>
# include <gp_Pnt.hxx>
# include <BRepBuilderAPI_MakeEdge.hxx>
#endif  // #ifndef _PreComp_

#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Parameter.h>
#include <Base/Tools2D.h>
#include <Base/Vector3D.h>

#include <App/Application.h>
#include <App/Material.h>

#include "DrawUtil.h"
#include "Geometry.h"

#include "Cosmetic.h"

using namespace TechDraw;

CosmeticVertex::CosmeticVertex()
{
    pageLocation = Base::Vector3d(0.0, 0.0, 0.0);
    modelLocation = Base::Vector3d(0.0, 0.0, 0.0);
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                         GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    App::Color fcColor;
    fcColor.setPackedValue(hGrp->GetUnsigned("VertexColor", 0x00000000));

    linkGeom = -1;
    color = fcColor;
    size  = 3.0;
    style = 1;
    visible = true;
}

CosmeticVertex::CosmeticVertex(Base::Vector3d loc)
{
    pageLocation = loc;
    modelLocation = loc;

    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                         GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    App::Color fcColor;
    fcColor.setPackedValue(hGrp->GetUnsigned("VertexColor", 0xff000000));

    linkGeom = -1;
    color = fcColor;
    //TODO: size = hGrp->getFloat("VertexSize",30.0);
    size  = 30.0;
    style = 1;        //TODO: implement styled vertexes
    visible = true;
}

std::string CosmeticVertex::toCSV(void) const
{
    std::stringstream ss;
    ss << pageLocation.x << "," <<
          pageLocation.y << "," <<
          pageLocation.z << "," <<

          modelLocation.x << "," <<
          modelLocation.y << "," <<
          modelLocation.z << "," <<

          linkGeom << "," <<
          color.asHexString() << ","  <<
          size << "," <<
          style << ","  <<
          visible <<
          std::endl;
    return ss.str();
}

bool CosmeticVertex::fromCSV(std::string& lineSpec)
{
    unsigned int maxCells = 11;
    if (lineSpec.length() == 0) {
        Base::Console().Message( "CosmeticVertex::fromCSV - lineSpec empty\n");
        return false;
    }
    std::vector<std::string> values = split(lineSpec);
    if (values.size() < maxCells) {
        Base::Console().Message( "CosmeticVertex::fromCSV(%s) invalid CSV entry\n",lineSpec.c_str() );
        return false;
    }
    double x = atof(values[0].c_str());
    double y = atof(values[1].c_str());
    double z = atof(values[2].c_str());
    pageLocation = Base::Vector3d (x,y,z);
    x = atof(values[3].c_str());
    y = atof(values[4].c_str());
    z = atof(values[5].c_str());
    modelLocation = Base::Vector3d (x,y,z);
    linkGeom = atoi(values[6].c_str());
    color.fromHexString(values[7]);
    size = atof(values[8].c_str());
    style = atoi(values[9].c_str());
    visible = atoi(values[10].c_str());
    return true;
}

std::vector<std::string> CosmeticVertex::split(std::string csvLine)
{
//    Base::Console().Message("CV::split - csvLine: %s\n",csvLine.c_str());
    std::vector<std::string>  result;
    std::stringstream     lineStream(csvLine);
    std::string           cell;

    while(std::getline(lineStream,cell, ','))
    {
        result.push_back(cell);
    }
    return result;
}

void CosmeticVertex::dump(char* title)
{
    Base::Console().Message("CV::dump - %s \n",title);
    Base::Console().Message("CV::dump - %s \n",toCSV().c_str());
}

//******************************************

CosmeticEdge::CosmeticEdge()
{
    geometry = new TechDrawGeometry::BaseGeom();
    linkGeom = -1;
    color = getDefEdgeColor();
    width  = getDefEdgeWidth();
    style = getDefEdgeStyle();
    visible = true;
}

CosmeticEdge::CosmeticEdge(Base::Vector3d p1, Base::Vector3d p2)
{
    gp_Pnt gp1(p1.x,p1.y,p1.z);
    gp_Pnt gp2(p2.x,p2.y,p2.z);
    TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp1, gp2);
    geometry = TechDrawGeometry::BaseGeom::baseFactory(e);
    linkGeom = -1;
    color = getDefEdgeColor();
    width  = getDefEdgeWidth();
    style = getDefEdgeStyle();
    visible = true;
}

CosmeticEdge::CosmeticEdge(TopoDS_Edge e)
{
    geometry = TechDrawGeometry::BaseGeom::baseFactory(e);
    linkGeom = -1;
    color = getDefEdgeColor();
    width  = getDefEdgeWidth();
    style = getDefEdgeStyle();
    visible = true;
}

double CosmeticEdge::getDefEdgeWidth()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                                    GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    std::string lgName = hGrp->GetASCII("LineGroup","FC 0.70mm");
    auto lg = TechDraw::LineGroup::lineGroupFactory(lgName);

    double width = lg->getWeight("Graphic");
    delete lg;
    return width;
}

App::Color CosmeticEdge::getDefEdgeColor()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
        .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors");
    App::Color fcColor;
    fcColor.setPackedValue(hGrp->GetUnsigned("NormalColor", 0x00000000));
    return fcColor;
}

int CosmeticEdge::getDefEdgeStyle()
{
    return 1;
}

std::string CosmeticEdge::toCSV(void) const
{
    std::stringstream ss;
    Base::Vector3d start, end;
    if (geometry != nullptr) {
        Base::Vector2d getStartPoint();
        Base::Vector2d getEndPoint();

        Base::Vector2d p2d = geometry->getStartPoint();
        start = Base::Vector3d(p2d.x, p2d.y, 0.0);
        p2d = geometry->getEndPoint();
        end = Base::Vector3d(p2d.x, p2d.y, 0.0);
    }
    ss << start.x << "," <<
        start.y << "," <<
        start.z << "," <<
        end.x << "," <<
        end.y << "," <<
        end.z << "," <<
        linkGeom << "," <<
        color.asHexString() << ","  <<
        width << "," <<
        style << ","  <<
        visible <<
        std::endl;
    return ss.str();
}

bool CosmeticEdge::fromCSV(std::string& lineSpec)
{
    unsigned int maxCells = 11;
    if (lineSpec.length() == 0) {
        Base::Console().Message( "CosmeticEdge::fromCSV - lineSpec empty\n");
        return false;
    }
    std::vector<std::string> values = split(lineSpec);
    Base::Console().Message("CE::fromCSV - values: %d\n",values.size());
    if (values.size() < maxCells) {
        Base::Console().Message( "CosmeticEdge::fromCSV(%s) invalid CSV entry\n",lineSpec.c_str() );
        return false;
    }
    Base::Vector3d start, end;
    double x = atof(values[0].c_str());
    double y = atof(values[1].c_str());
    double z = atof(values[2].c_str());
    start = Base::Vector3d (x,y,z);
    x = atof(values[3].c_str());
    y = atof(values[4].c_str());
    z = atof(values[5].c_str());
    end = Base::Vector3d (x,y,z);

    linkGeom = atoi(values[6].c_str());
    color.fromHexString(values[7]);
    width = atof(values[8].c_str());
    style = atoi(values[9].c_str());
    visible = atoi(values[10].c_str());
    return true;
}

//duplicate of CV routine.  make static? or base class?
std::vector<std::string> CosmeticEdge::split(std::string csvLine)
{
    Base::Console().Message("CE::split - csvLine: %s\n",csvLine.c_str());
    std::vector<std::string>  result;
    std::stringstream     lineStream(csvLine);
    std::string           cell;

    while(std::getline(lineStream,cell, ','))
    {
        result.push_back(cell);
    }
    return result;
}

//duplicate of CV routine.  make static? or base class?
void CosmeticEdge::dump(char* title)
{
    Base::Console().Message("CE::dump - %s \n",title);
    Base::Console().Message("CE::dump - %s \n",toCSV().c_str());
}

<commit_msg>fix warning C4930: prototyped function not called<commit_after>/***************************************************************************
 *   Copyright (c) 2019 WandererFan <wandererfan@gmail.com>                *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS_Edge.hxx>
# include <gp_Pnt.hxx>
# include <BRepBuilderAPI_MakeEdge.hxx>
#endif  // #ifndef _PreComp_

#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Parameter.h>
#include <Base/Tools2D.h>
#include <Base/Vector3D.h>

#include <App/Application.h>
#include <App/Material.h>

#include "DrawUtil.h"
#include "Geometry.h"

#include "Cosmetic.h"

using namespace TechDraw;

CosmeticVertex::CosmeticVertex()
{
    pageLocation = Base::Vector3d(0.0, 0.0, 0.0);
    modelLocation = Base::Vector3d(0.0, 0.0, 0.0);
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                         GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    App::Color fcColor;
    fcColor.setPackedValue(hGrp->GetUnsigned("VertexColor", 0x00000000));

    linkGeom = -1;
    color = fcColor;
    size  = 3.0;
    style = 1;
    visible = true;
}

CosmeticVertex::CosmeticVertex(Base::Vector3d loc)
{
    pageLocation = loc;
    modelLocation = loc;

    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                         GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    App::Color fcColor;
    fcColor.setPackedValue(hGrp->GetUnsigned("VertexColor", 0xff000000));

    linkGeom = -1;
    color = fcColor;
    //TODO: size = hGrp->getFloat("VertexSize",30.0);
    size  = 30.0;
    style = 1;        //TODO: implement styled vertexes
    visible = true;
}

std::string CosmeticVertex::toCSV(void) const
{
    std::stringstream ss;
    ss << pageLocation.x << "," <<
          pageLocation.y << "," <<
          pageLocation.z << "," <<

          modelLocation.x << "," <<
          modelLocation.y << "," <<
          modelLocation.z << "," <<

          linkGeom << "," <<
          color.asHexString() << ","  <<
          size << "," <<
          style << ","  <<
          visible <<
          std::endl;
    return ss.str();
}

bool CosmeticVertex::fromCSV(std::string& lineSpec)
{
    unsigned int maxCells = 11;
    if (lineSpec.length() == 0) {
        Base::Console().Message( "CosmeticVertex::fromCSV - lineSpec empty\n");
        return false;
    }
    std::vector<std::string> values = split(lineSpec);
    if (values.size() < maxCells) {
        Base::Console().Message( "CosmeticVertex::fromCSV(%s) invalid CSV entry\n",lineSpec.c_str() );
        return false;
    }
    double x = atof(values[0].c_str());
    double y = atof(values[1].c_str());
    double z = atof(values[2].c_str());
    pageLocation = Base::Vector3d (x,y,z);
    x = atof(values[3].c_str());
    y = atof(values[4].c_str());
    z = atof(values[5].c_str());
    modelLocation = Base::Vector3d (x,y,z);
    linkGeom = atoi(values[6].c_str());
    color.fromHexString(values[7]);
    size = atof(values[8].c_str());
    style = atoi(values[9].c_str());
    visible = atoi(values[10].c_str());
    return true;
}

std::vector<std::string> CosmeticVertex::split(std::string csvLine)
{
//    Base::Console().Message("CV::split - csvLine: %s\n",csvLine.c_str());
    std::vector<std::string>  result;
    std::stringstream     lineStream(csvLine);
    std::string           cell;

    while(std::getline(lineStream,cell, ','))
    {
        result.push_back(cell);
    }
    return result;
}

void CosmeticVertex::dump(char* title)
{
    Base::Console().Message("CV::dump - %s \n",title);
    Base::Console().Message("CV::dump - %s \n",toCSV().c_str());
}

//******************************************

CosmeticEdge::CosmeticEdge()
{
    geometry = new TechDrawGeometry::BaseGeom();
    linkGeom = -1;
    color = getDefEdgeColor();
    width  = getDefEdgeWidth();
    style = getDefEdgeStyle();
    visible = true;
}

CosmeticEdge::CosmeticEdge(Base::Vector3d p1, Base::Vector3d p2)
{
    gp_Pnt gp1(p1.x,p1.y,p1.z);
    gp_Pnt gp2(p2.x,p2.y,p2.z);
    TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp1, gp2);
    geometry = TechDrawGeometry::BaseGeom::baseFactory(e);
    linkGeom = -1;
    color = getDefEdgeColor();
    width  = getDefEdgeWidth();
    style = getDefEdgeStyle();
    visible = true;
}

CosmeticEdge::CosmeticEdge(TopoDS_Edge e)
{
    geometry = TechDrawGeometry::BaseGeom::baseFactory(e);
    linkGeom = -1;
    color = getDefEdgeColor();
    width  = getDefEdgeWidth();
    style = getDefEdgeStyle();
    visible = true;
}

double CosmeticEdge::getDefEdgeWidth()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                                    GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    std::string lgName = hGrp->GetASCII("LineGroup","FC 0.70mm");
    auto lg = TechDraw::LineGroup::lineGroupFactory(lgName);

    double width = lg->getWeight("Graphic");
    delete lg;
    return width;
}

App::Color CosmeticEdge::getDefEdgeColor()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
        .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors");
    App::Color fcColor;
    fcColor.setPackedValue(hGrp->GetUnsigned("NormalColor", 0x00000000));
    return fcColor;
}

int CosmeticEdge::getDefEdgeStyle()
{
    return 1;
}

std::string CosmeticEdge::toCSV(void) const
{
    std::stringstream ss;
    Base::Vector3d start, end;
    if (geometry != nullptr) {
        Base::Vector2d p2d = geometry->getStartPoint();
        start = Base::Vector3d(p2d.x, p2d.y, 0.0);
        p2d = geometry->getEndPoint();
        end = Base::Vector3d(p2d.x, p2d.y, 0.0);
    }
    ss << start.x << "," <<
        start.y << "," <<
        start.z << "," <<
        end.x << "," <<
        end.y << "," <<
        end.z << "," <<
        linkGeom << "," <<
        color.asHexString() << ","  <<
        width << "," <<
        style << ","  <<
        visible <<
        std::endl;
    return ss.str();
}

bool CosmeticEdge::fromCSV(std::string& lineSpec)
{
    unsigned int maxCells = 11;
    if (lineSpec.length() == 0) {
        Base::Console().Message( "CosmeticEdge::fromCSV - lineSpec empty\n");
        return false;
    }
    std::vector<std::string> values = split(lineSpec);
    Base::Console().Message("CE::fromCSV - values: %d\n",values.size());
    if (values.size() < maxCells) {
        Base::Console().Message( "CosmeticEdge::fromCSV(%s) invalid CSV entry\n",lineSpec.c_str() );
        return false;
    }
    Base::Vector3d start, end;
    double x = atof(values[0].c_str());
    double y = atof(values[1].c_str());
    double z = atof(values[2].c_str());
    start = Base::Vector3d (x,y,z);
    x = atof(values[3].c_str());
    y = atof(values[4].c_str());
    z = atof(values[5].c_str());
    end = Base::Vector3d (x,y,z);

    linkGeom = atoi(values[6].c_str());
    color.fromHexString(values[7]);
    width = atof(values[8].c_str());
    style = atoi(values[9].c_str());
    visible = atoi(values[10].c_str());
    return true;
}

//duplicate of CV routine.  make static? or base class?
std::vector<std::string> CosmeticEdge::split(std::string csvLine)
{
    Base::Console().Message("CE::split - csvLine: %s\n",csvLine.c_str());
    std::vector<std::string>  result;
    std::stringstream     lineStream(csvLine);
    std::string           cell;

    while(std::getline(lineStream,cell, ','))
    {
        result.push_back(cell);
    }
    return result;
}

//duplicate of CV routine.  make static? or base class?
void CosmeticEdge::dump(char* title)
{
    Base::Console().Message("CE::dump - %s \n",title);
    Base::Console().Message("CE::dump - %s \n",toCSV().c_str());
}

<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <sstream>
# include <Standard_Failure.hxx>
#endif

#include <strstream>
#include <App/Application.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include <Base/FileInfo.h>
#include <Base/Console.h>

#include "DrawView.h"
#include "DrawPage.h"
#include "DrawViewCollection.h"
#include "DrawViewClip.h"

#include "DrawViewPy.h"  // generated from DrawViewPy.xml

using namespace TechDraw;

//===========================================================================
// DrawView
//===========================================================================

const char* DrawView::ScaleTypeEnums[]= {"Document",
                                            "Automatic",
                                            "Custom",
                                             NULL};

PROPERTY_SOURCE(TechDraw::DrawView, App::DocumentObject)

DrawView::DrawView(void)
{
    static const char *group = "Drawing view";
    ADD_PROPERTY_TYPE(X ,(0),group,App::Prop_None,"X position of the view on the page in modelling units (mm)");
    ADD_PROPERTY_TYPE(Y ,(0),group,App::Prop_None,"Y position of the view on the page in modelling units (mm)");
    ADD_PROPERTY_TYPE(Rotation ,(0),group,App::Prop_None,"Rotation of the view on the page in degrees counterclockwise");

    ScaleType.setEnums(ScaleTypeEnums);
    ADD_PROPERTY_TYPE(ScaleType,((long)0),group, App::Prop_None, "Scale Type");
    ADD_PROPERTY_TYPE(Scale ,(1.0),group,App::Prop_None,"Scale factor of the view");
    //Scale.setStatus(App::Property::ReadOnly,true);

    autoPos = true;

}

DrawView::~DrawView()
{
}

App::DocumentObjectExecReturn *DrawView::recompute(void)
{
    try {
        return App::DocumentObject::recompute();
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        App::DocumentObjectExecReturn* ret = new App::DocumentObjectExecReturn(e->GetMessageString());
        if (ret->Why.empty()) ret->Why = "Unknown OCC exception";
        return ret;
    }
}

App::DocumentObjectExecReturn *DrawView::execute(void)
{
    //right way to handle this?  can't do it at creation since don't have a parent.
    if (ScaleType.isValue("Document")) {
        TechDraw::DrawPage *page = findParentPage();
        if(page) {
            if(std::abs(page->Scale.getValue() - Scale.getValue()) > FLT_EPSILON) {
                Scale.setValue(page->Scale.getValue());
                Scale.touch();
            }
        }
    }

    return App::DocumentObject::execute();
}

/// get called by the container when a Property was changed
void DrawView::onChanged(const App::Property* prop)
{
    if (!isRestoring()) {
        if (prop == &ScaleType ||
            prop == &Scale) {
            if (ScaleType.isValue("Document")) {
                TechDraw::DrawPage *page = findParentPage();
                if(page) {
                    if(std::abs(page->Scale.getValue() - Scale.getValue()) > FLT_EPSILON) {
                        Scale.setValue(page->Scale.getValue()); // Reset scale from page
                        Scale.touch();
                    }
                }
                Scale.setStatus(App::Property::ReadOnly,true);
                App::GetApplication().signalChangePropertyEditor(Scale);
            } else if ( ScaleType.isValue("Custom") ) {
//            } else if (ScaleType.isValue("Custom") &&
//                Scale.testStatus(App::Property::ReadOnly)) {
                Scale.setStatus(App::Property::ReadOnly,false);
                App::GetApplication().signalChangePropertyEditor(Scale);
            }
            //TODO else if (ScaleType.isValue("Automatic"))...
            DrawView::execute();
        } else if (prop == &X ||
                   prop == &Y) {
            setAutoPos(false);
            DrawView::execute();
        } else if (prop == &Rotation) {
            DrawView::execute();
        }
    }

    App::DocumentObject::onChanged(prop);
}

void DrawView::onDocumentRestored()
{
    // Rebuild the view
    execute();
}

DrawPage* DrawView::findParentPage() const
{
    // Get Feature Page
    DrawPage *page = 0;
    DrawViewCollection *collection = 0;
    std::vector<App::DocumentObject*> parent = getInList();
    for (std::vector<App::DocumentObject*>::iterator it = parent.begin(); it != parent.end(); ++it) {
        if ((*it)->getTypeId().isDerivedFrom(DrawPage::getClassTypeId())) {
            page = dynamic_cast<TechDraw::DrawPage *>(*it);
        }

        if ((*it)->getTypeId().isDerivedFrom(DrawViewCollection::getClassTypeId())) {
            collection = dynamic_cast<TechDraw::DrawViewCollection *>(*it);
            page = collection->findParentPage();
        }

        if(page)
          break; // Found page so leave
    }

    return page;
}

bool DrawView::isInClip()
{
    std::vector<App::DocumentObject*> parent = getInList();
    for (std::vector<App::DocumentObject*>::iterator it = parent.begin(); it != parent.end(); ++it) {
        if ((*it)->getTypeId().isDerivedFrom(DrawViewClip::getClassTypeId())) {
            return true;
        }
    }
    return false;
}

PyObject *DrawView::getPyObject(void)
{
    if (PythonObject.is(Py::_None())) {
        // ref counter is set to 1
        PythonObject = Py::Object(new DrawViewPy(this),true);
    }
    return Py::new_reference_to(PythonObject);
}

// Python Drawing feature ---------------------------------------------------------

namespace App {
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewPython, TechDraw::DrawView)
template<> const char* TechDraw::DrawViewPython::getViewProviderName(void) const {
    return "TechDrawGui::ViewProviderDrawingView";
}
/// @endcond

// explicit template instantiation
template class TechDrawExport FeaturePythonT<TechDraw::DrawView>;
}
<commit_msg>Fix #58 ProjectionGroupItem positioning after restore<commit_after>/***************************************************************************
 *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <sstream>
# include <Standard_Failure.hxx>
#endif

#include <strstream>
#include <App/Application.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include <Base/FileInfo.h>
#include <Base/Console.h>

#include "DrawView.h"
#include "DrawPage.h"
#include "DrawViewCollection.h"
#include "DrawViewClip.h"

#include "DrawViewPy.h"  // generated from DrawViewPy.xml

using namespace TechDraw;

//===========================================================================
// DrawView
//===========================================================================

const char* DrawView::ScaleTypeEnums[]= {"Document",
                                            "Automatic",
                                            "Custom",
                                             NULL};

PROPERTY_SOURCE(TechDraw::DrawView, App::DocumentObject)

DrawView::DrawView(void)
{
    static const char *group = "Drawing view";
    ADD_PROPERTY_TYPE(X ,(0),group,App::Prop_None,"X position of the view on the page in modelling units (mm)");
    ADD_PROPERTY_TYPE(Y ,(0),group,App::Prop_None,"Y position of the view on the page in modelling units (mm)");
    ADD_PROPERTY_TYPE(Rotation ,(0),group,App::Prop_None,"Rotation of the view on the page in degrees counterclockwise");

    ScaleType.setEnums(ScaleTypeEnums);
    ADD_PROPERTY_TYPE(ScaleType,((long)0),group, App::Prop_None, "Scale Type");
    ADD_PROPERTY_TYPE(Scale ,(1.0),group,App::Prop_None,"Scale factor of the view");

    if (isRestoring()) {
        autoPos = false;
    } else {
        autoPos = true;
    }
}

DrawView::~DrawView()
{
}

App::DocumentObjectExecReturn *DrawView::recompute(void)
{
    try {
        return App::DocumentObject::recompute();
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        App::DocumentObjectExecReturn* ret = new App::DocumentObjectExecReturn(e->GetMessageString());
        if (ret->Why.empty()) ret->Why = "Unknown OCC exception";
        return ret;
    }
}

App::DocumentObjectExecReturn *DrawView::execute(void)
{
    //right way to handle this?  can't do it at creation since don't have a parent.
    if (ScaleType.isValue("Document")) {
        TechDraw::DrawPage *page = findParentPage();
        if(page) {
            if(std::abs(page->Scale.getValue() - Scale.getValue()) > FLT_EPSILON) {
                Scale.setValue(page->Scale.getValue());
                Scale.touch();
            }
        }
    }

    return App::DocumentObject::execute();
}

/// get called by the container when a Property was changed
void DrawView::onChanged(const App::Property* prop)
{
    if (!isRestoring()) {
        if (prop == &ScaleType ||
            prop == &Scale) {
            if (ScaleType.isValue("Document")) {
                TechDraw::DrawPage *page = findParentPage();
                if(page) {
                    if(std::abs(page->Scale.getValue() - Scale.getValue()) > FLT_EPSILON) {
                        Scale.setValue(page->Scale.getValue()); // Reset scale from page
                        Scale.touch();
                    }
                }
                Scale.setStatus(App::Property::ReadOnly,true);
                App::GetApplication().signalChangePropertyEditor(Scale);
            } else if ( ScaleType.isValue("Custom") ) {
                Scale.setStatus(App::Property::ReadOnly,false);
                App::GetApplication().signalChangePropertyEditor(Scale);
            }
            //TODO else if (ScaleType.isValue("Automatic"))...
            DrawView::execute();
        } else if (prop == &X ||
                   prop == &Y) {
            setAutoPos(false);
            DrawView::execute();
        } else if (prop == &Rotation) {
            DrawView::execute();
        }
    }

    App::DocumentObject::onChanged(prop);
}

void DrawView::onDocumentRestored()
{
    // Rebuild the view
    execute();
}

DrawPage* DrawView::findParentPage() const
{
    // Get Feature Page
    DrawPage *page = 0;
    DrawViewCollection *collection = 0;
    std::vector<App::DocumentObject*> parent = getInList();
    for (std::vector<App::DocumentObject*>::iterator it = parent.begin(); it != parent.end(); ++it) {
        if ((*it)->getTypeId().isDerivedFrom(DrawPage::getClassTypeId())) {
            page = dynamic_cast<TechDraw::DrawPage *>(*it);
        }

        if ((*it)->getTypeId().isDerivedFrom(DrawViewCollection::getClassTypeId())) {
            collection = dynamic_cast<TechDraw::DrawViewCollection *>(*it);
            page = collection->findParentPage();
        }

        if(page)
          break; // Found page so leave
    }

    return page;
}

bool DrawView::isInClip()
{
    std::vector<App::DocumentObject*> parent = getInList();
    for (std::vector<App::DocumentObject*>::iterator it = parent.begin(); it != parent.end(); ++it) {
        if ((*it)->getTypeId().isDerivedFrom(DrawViewClip::getClassTypeId())) {
            return true;
        }
    }
    return false;
}

PyObject *DrawView::getPyObject(void)
{
    if (PythonObject.is(Py::_None())) {
        // ref counter is set to 1
        PythonObject = Py::Object(new DrawViewPy(this),true);
    }
    return Py::new_reference_to(PythonObject);
}

// Python Drawing feature ---------------------------------------------------------

namespace App {
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewPython, TechDraw::DrawView)
template<> const char* TechDraw::DrawViewPython::getViewProviderName(void) const {
    return "TechDrawGui::ViewProviderDrawingView";
}
/// @endcond

// explicit template instantiation
template class TechDrawExport FeaturePythonT<TechDraw::DrawView>;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <map>
#include <node.h>

#include "PSATResult.h"
#include "calculator/EstimateFLA.h"
#include "calculator/MotorCurrent.h"
#include "calculator/MotorPowerFactor.h"
#include "calculator/OptimalPrePumpEff.h"
#include "calculator/OptimalSpecificSpeedCorrection.h"
#include "calculator/OptimalDeviationFactor.h"

using namespace v8;
using namespace std;

Isolate* iso;
Local<Object> inp;
Local<Object> r;

double Get(const char *nm) {
  auto rObj = inp->ToObject()->Get(String::NewFromUtf8(iso,nm));
  if (rObj->IsUndefined()) {
    cout << nm << endl;;
    assert(!"defined");
  }
  return rObj->NumberValue();
}

Motor::LineFrequency line;
Motor::EfficiencyClass effCls;
Pump::Drive drive;
double motorRatedPower;

void Setup(const FunctionCallbackInfo<Value>& args) {
  iso = args.GetIsolate();
  inp = args[0]->ToObject();
  r = Object::New(iso);
  args.GetReturnValue().Set(r);

  line = (Motor::LineFrequency)(int)(!Get("line"));
  effCls = (Motor::EfficiencyClass)(int)Get("efficiency_class");
  drive = (Pump::Drive)(int)Get("drive");
  motorRatedPower = Get("motor_rated_power");
}

void Results(const FunctionCallbackInfo<Value>& args) {
  Setup(args);

  Pump pump((Pump::Style)(int)Get("pump_style"),Get("pump_specified"),Get("pump_rated_speed"),drive,
      Get("viscosity"),Get("specific_gravity"),Get("stages"),(Pump::Speed)(int)(!Get("fixed_speed")));
  Motor motor(line,motorRatedPower,Get("motor_rated_speed"),
      effCls,Get("efficiency"),Get("motor_rated_voltage"),Get("motor_rated_flc"),Get("margin"));
  Financial fin(Get("fraction"),Get("cost"));
  FieldData fd(Get("flow"),Get("head"),(FieldData::LoadEstimationMethod)(Get("motor_field_power")>0?0:1),
      Get("motor_field_power"),Get("motor_field_current"),Get("motor_field_voltage"));
  PSATResult psat(pump,motor,fin,fd);
  psat.calculateExisting();
  psat.calculateOptimal();
  auto ex = psat.getExisting(), opt = psat.getOptimal();

  map<const char *,vector<double>> out = {
    {"Pump Efficiency",{ex.pumpEfficiency_*100,opt.pumpEfficiency_*100}},
    {"Motor Rated Power",{ex.motorRatedPower_,opt.motorRatedPower_}},
    {"Motor Shaft Power",{ex.motorShaftPower_,opt.motorShaftPower_}},
    {"Pump Shaft Power",{ex.pumpShaftPower_,opt.pumpShaftPower_}},
    {"Motor Efficiency",{ex.motorEfficiency_,opt.motorEfficiency_}},
    {"Motor Power Factor",{ex.motorPowerFactor_,opt.motorPowerFactor_}},
    {"Motor Current",{ex.motorCurrent_,opt.motorCurrent_}},
    {"Motor Power", {ex.motorPower_,opt.motorPower_}},
    {"Annual Energy", {ex.annualEnergy_,opt.annualEnergy_}},
    {"Annual Cost", {ex.annualCost_*1000,opt.annualCost_*1000}},
    {"Savings Potential", {psat.getAnnualSavingsPotential(),-1}},
    {"Optimization Rating", {psat.getOptimizationRating(),-1}}
  };
  for(auto p: out) {
    auto a = Array::New(iso);
    a->Set(0,Number::New(iso,p.second[0]));
    a->Set(1,Number::New(iso,p.second[1]));
    r->Set(String::NewFromUtf8(iso,p.first),a);
  }
}

void EstFLA(const FunctionCallbackInfo<Value>& args) {
  Setup(args);
  EstimateFLA fla(motorRatedPower,Get("motor_rated_speed"),line,effCls,
    Get("efficiency"),Get("motor_rated_voltage"));
  fla.calculate();
  args.GetReturnValue().Set(fla.getEstimatedFLA());
}

void MotorPerformance(const FunctionCallbackInfo<Value>& args) {
  Setup(args);

  MotorEfficiency mef(line,Get("motor_rated_speed"),effCls,Get("efficiency"),motorRatedPower,Get("load_factor"));
  auto mefVal = mef.calculate();
  r->Set(String::NewFromUtf8(iso,"efficiency"),Number::New(iso,mefVal*100));

  MotorCurrent mc(motorRatedPower,Get("motor_rated_speed"),line,effCls,Get("efficiency"),Get("load_factor"),Get("motor_rated_voltage"),Get("flc"));
  auto mcVal = mc.calculate();
  r->Set(String::NewFromUtf8(iso,"current"),Number::New(iso,mcVal/225.8*100));

  MotorPowerFactor pf(motorRatedPower,Get("load_factor"),mcVal,mefVal,Get("motor_rated_voltage"));
  r->Set(String::NewFromUtf8(iso,"pf"),Number::New(iso,pf.calculate()*100));
}

//TODO round vs js round; loosen up to make next test case
void Check(double exp, double act, const char* nm="") {
  //cout << "e " << exp << "; a " << act << endl;
  // if (isnan(act) || (abs(exp-act)>.01*exp)) {
  auto p = 10;
  if (isnan(act) || ( (round(exp*p)/p)!=round(act*p)/p)) {
    printf("\"%s\" TEST FAILED: %f %f\n",nm,exp,act);
    assert(!"equal");
  }
}

void Check100(double exp, double act, const char* nm="") {
  Check(exp,act*100,nm);
}

void Test(const FunctionCallbackInfo<Value>& args) {
    EstimateFLA fla(200,1780,(Motor::LineFrequency)1,(Motor::EfficiencyClass)(1),0,460);
    fla.calculate();
    Check(225.8,fla.getEstimatedFLA());

// motor perf

  {
    MotorEfficiency mef(Motor::LineFrequency::FREQ60,1780,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,.75);
    auto mefVal = mef.calculate();
    Check100(95.69,mefVal);

    MotorCurrent mc(200,1780,Motor::LineFrequency::FREQ60,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,.75,460,225.8);
    auto mcVal = mc.calculate();
    Check100(76.63,mcVal/225.8);

    MotorPowerFactor pf(200,.75,mcVal,mefVal,460);
    Check100(84.82,pf.calculate());

  }

//nema
  {
    MotorEfficiency mef(Motor::LineFrequency::FREQ60,1200, Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,1);
    //Check100(95,mef.calculate());
  }

//pump eff
  {
    OptimalPrePumpEff pef(Pump::Style::END_SUCTION_ANSI_API, 0, 2000);
    OptimalDeviationFactor df(2000);
//  Check(87.1,pef.calculate()*df.calculate());
  }

//spec speed

  {
    OptimalSpecificSpeedCorrection cor(Pump::Style::END_SUCTION_ANSI_API, 1170);
    //Check100(2.3,cor.calculate());
  }
  return;

  #define BASE \
    Pump pump(Pump::Style::END_SUCTION_ANSI_API,0,1780,Pump::Drive::DIRECT_DRIVE,\
      1,1,1,Pump::Speed::NOT_FIXED_SPEED);\
    Motor motor(Motor::LineFrequency::FREQ60,200,1780,\
        Motor::EfficiencyClass::ENERGY_EFFICIENT,0,460,225.8,0);\
    Financial fin(1,.05);\
    FieldData fd(2000,277,FieldData::LoadEstimationMethod::POWER,\
        150,0,460);

  #define CALC \
    PSATResult psat(pump,motor,fin,fd);\
    psat.calculateExisting();\
    auto ex = psat.getExisting();

  for (int i=1; i<=10000; i=i+2) {
    BASE
    CALC
    Check(ex.motorShaftPower_,ex.motorShaftPower_,"SAME");
  }

  {
    BASE
    motor.setMotorRpm(1786);
    fd.setMotorPower(80);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(79.1,ex.motorPowerFactor_);
    Check(127,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedPower(100);
    motor.setFullLoadAmps(113.8);
    CALC
    Check(101.8,ex.motorShaftPower_);
    Check100(94.9,ex.motorEfficiency_);
    Check100(86.7,ex.motorPowerFactor_);
    Check(115.8,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    fd.setVoltage(260);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(138.8,ex.motorPowerFactor_);
    Check(128,ex.motorCurrent_);
  }
  {
    BASE
    motor.setMotorRpm(1200);
    fd.setMotorPower(80);
    motor.setFullLoadAmps(235.3);
    CALC
    Check(101.4,ex.motorShaftPower_);
    Check100(94.5,ex.motorEfficiency_);
    Check100(74.3,ex.motorPowerFactor_);
    Check(135.1,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(111.855);
    CALC
    Check(143.4,ex.motorShaftPower_);
    Check100(95.6,ex.motorEfficiency_);
    Check100(84.3,ex.motorPowerFactor_);
    Check(166.5,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedVoltage(200);
    motor.setFullLoadAmps(519.3);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(35.2,ex.motorPowerFactor_);
    Check(284.9,ex.motorCurrent_);
  }
  {
    BASE
    CALC
    Check(217.5,ex.motorCurrent_);
  }
  {
    BASE
    fd.setLoadEstimationMethod(FieldData::LoadEstimationMethod::CURRENT);
    fd.setMotorAmps(218);
    fd.setMotorPower(0);
    CALC
    Check(150.4,ex.motorPower_);
    Check100(72.5,ex.pumpEfficiency_);
  }
  {
    BASE
    fd.setMotorPower(80);
    CALC
    Check(700.8,ex.annualEnergy_);
  }
  {
    BASE
    fin.setOperatingFraction(.25);
    CALC
    Check(328.5,ex.annualEnergy_);
    Check(16.4,ex.annualCost_);
  }
  {
    BASE
    motor.setFullLoadAmps(300);
    CALC
    Check(288.9,ex.motorCurrent_);
  }
  {
    BASE
    motor.setEfficiencyClass(Motor::EfficiencyClass(0));
    CALC
    Check(213.7,ex.motorCurrent_);
  }
  {
    BASE
    motor.setEfficiencyClass(Motor::EfficiencyClass(2));
    motor.setSpecifiedEfficiency(75);
    CALC
    Check(173.7,ex.motorCurrent_);
  }
  cout << "done";
}

void Wtf(const FunctionCallbackInfo<Value>& args) {
}

void Init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "results", Results);
  NODE_SET_METHOD(exports, "estFLA", EstFLA);
  NODE_SET_METHOD(exports, "motorPerformance", MotorPerformance);
  NODE_SET_METHOD(exports, "test", Test);
  NODE_SET_METHOD(exports, "wtf", Wtf);
}

NODE_MODULE(bridge, Init)

<commit_msg>no message<commit_after>#include <iostream>
#include <vector>
#include <map>
#include <node.h>

#include "PSATResult.h"
#include "calculator/EstimateFLA.h"
#include "calculator/MotorCurrent.h"
#include "calculator/MotorPowerFactor.h"
#include "calculator/OptimalPrePumpEff.h"
#include "calculator/OptimalSpecificSpeedCorrection.h"
#include "calculator/OptimalDeviationFactor.h"

using namespace v8;
using namespace std;

Isolate* iso;
Local<Object> inp;
Local<Object> r;

double Get(const char *nm) {
  auto rObj = inp->ToObject()->Get(String::NewFromUtf8(iso,nm));
  if (rObj->IsUndefined()) {
    cout << nm << endl;;
    assert(!"defined");
  }
  return rObj->NumberValue();
}

Motor::LineFrequency line() {
  return (Motor::LineFrequency)(int)(!Get("line"));
}
Motor::EfficiencyClass effCls() {
  return (Motor::EfficiencyClass)(int)Get("efficiency_class");
}
Pump::Drive drive() {
  return (Pump::Drive)(int)Get("drive");
}

void Setup(const FunctionCallbackInfo<Value>& args) {
  iso = args.GetIsolate();
  inp = args[0]->ToObject();
  r = Object::New(iso);
  args.GetReturnValue().Set(r);
}

void Results(const FunctionCallbackInfo<Value>& args) {
  Setup(args);

  Pump pump((Pump::Style)(int)Get("pump_style"),Get("pump_specified"),Get("pump_rated_speed"),drive(),
      Get("viscosity"),Get("specific_gravity"),Get("stages"),(Pump::Speed)(int)(!Get("fixed_speed")));
  Motor motor(line(),Get("motor_rated_power"),Get("motor_rated_speed"),effCls(),
      Get("efficiency"),Get("motor_rated_voltage"),Get("motor_rated_flc"),Get("margin"));
  Financial fin(Get("fraction"),Get("cost"));
  FieldData fd(Get("flow"),Get("head"),(FieldData::LoadEstimationMethod)(Get("motor_field_power")>0?0:1),
      Get("motor_field_power"),Get("motor_field_current"),Get("motor_field_voltage"));
  PSATResult psat(pump,motor,fin,fd);
  psat.calculateExisting();
  psat.calculateOptimal();
  auto ex = psat.getExisting(), opt = psat.getOptimal();

  map<const char *,vector<double>> out = {
    {"Pump Efficiency",{ex.pumpEfficiency_*100,opt.pumpEfficiency_*100}},
    {"Motor Rated Power",{ex.motorRatedPower_,opt.motorRatedPower_}},
    {"Motor Shaft Power",{ex.motorShaftPower_,opt.motorShaftPower_}},
    {"Pump Shaft Power",{ex.pumpShaftPower_,opt.pumpShaftPower_}},
    {"Motor Efficiency",{ex.motorEfficiency_,opt.motorEfficiency_}},
    {"Motor Power Factor",{ex.motorPowerFactor_,opt.motorPowerFactor_}},
    {"Motor Current",{ex.motorCurrent_,opt.motorCurrent_}},
    {"Motor Power", {ex.motorPower_,opt.motorPower_}},
    {"Annual Energy", {ex.annualEnergy_,opt.annualEnergy_}},
    {"Annual Cost", {ex.annualCost_*1000,opt.annualCost_*1000}},
    {"Savings Potential", {psat.getAnnualSavingsPotential(),-1}},
    {"Optimization Rating", {psat.getOptimizationRating(),-1}}
  };
  for(auto p: out) {
    auto a = Array::New(iso);
    a->Set(0,Number::New(iso,p.second[0]));
    a->Set(1,Number::New(iso,p.second[1]));
    r->Set(String::NewFromUtf8(iso,p.first),a);
  }
}

void EstFLA(const FunctionCallbackInfo<Value>& args) {
  Setup(args);
  EstimateFLA fla(Get("motor_rated_power"),Get("motor_rated_speed"),line(),effCls(),
    Get("efficiency"),Get("motor_rated_voltage"));
  fla.calculate();
  args.GetReturnValue().Set(fla.getEstimatedFLA());
}

void MotorPerformance(const FunctionCallbackInfo<Value>& args) {
  Setup(args);

  MotorEfficiency mef(line(),Get("motor_rated_speed"),effCls(),Get("efficiency"),Get("motor_rated_power"),Get("load_factor"));
  auto mefVal = mef.calculate();
  r->Set(String::NewFromUtf8(iso,"efficiency"),Number::New(iso,mefVal*100));

  MotorCurrent mc(Get("motor_rated_power"),Get("motor_rated_speed"),line(),effCls(),Get("efficiency"),Get("load_factor"),Get("motor_rated_voltage"),Get("flc"));
  auto mcVal = mc.calculate();
  r->Set(String::NewFromUtf8(iso,"current"),Number::New(iso,mcVal/225.8*100));

  MotorPowerFactor pf(Get("motor_rated_power"),Get("load_factor"),mcVal,mefVal,Get("motor_rated_voltage"));
  r->Set(String::NewFromUtf8(iso,"pf"),Number::New(iso,pf.calculate()*100));
}

//TODO round vs js round; loosen up to make next test case
void Check(double exp, double act, const char* nm="") {
  //cout << "e " << exp << "; a " << act << endl;
  // if (isnan(act) || (abs(exp-act)>.01*exp)) {
  auto p = 10;
  if (isnan(act) || ( (round(exp*p)/p)!=round(act*p)/p)) {
    printf("\"%s\" TEST FAILED: %f %f\n",nm,exp,act);
    assert(!"equal");
  }
}

void Check100(double exp, double act, const char* nm="") {
  Check(exp,act*100,nm);
}

void Test(const FunctionCallbackInfo<Value>& args) {
    EstimateFLA fla(200,1780,(Motor::LineFrequency)1,(Motor::EfficiencyClass)(1),0,460);
    fla.calculate();
    Check(225.8,fla.getEstimatedFLA());

// motor perf

  {
    MotorEfficiency mef(Motor::LineFrequency::FREQ60,1780,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,.75);
    auto mefVal = mef.calculate();
    Check100(95.69,mefVal);

    MotorCurrent mc(200,1780,Motor::LineFrequency::FREQ60,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,.75,460,225.8);
    auto mcVal = mc.calculate();
    Check100(76.63,mcVal/225.8);

    MotorPowerFactor pf(200,.75,mcVal,mefVal,460);
    Check100(84.82,pf.calculate());

  }

//nema
  {
    MotorEfficiency mef(Motor::LineFrequency::FREQ60,1200, Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,1);
    //Check100(95,mef.calculate());
  }

//pump eff
  {
    OptimalPrePumpEff pef(Pump::Style::END_SUCTION_ANSI_API, 0, 2000);
    OptimalDeviationFactor df(2000);
//  Check(87.1,pef.calculate()*df.calculate());
  }

//spec speed

  {
    OptimalSpecificSpeedCorrection cor(Pump::Style::END_SUCTION_ANSI_API, 1170);
    //Check100(2.3,cor.calculate());
  }
  return;

  #define BASE \
    Pump pump(Pump::Style::END_SUCTION_ANSI_API,0,1780,Pump::Drive::DIRECT_DRIVE,\
      1,1,1,Pump::Speed::NOT_FIXED_SPEED);\
    Motor motor(Motor::LineFrequency::FREQ60,200,1780,\
        Motor::EfficiencyClass::ENERGY_EFFICIENT,0,460,225.8,0);\
    Financial fin(1,.05);\
    FieldData fd(2000,277,FieldData::LoadEstimationMethod::POWER,\
        150,0,460);

  #define CALC \
    PSATResult psat(pump,motor,fin,fd);\
    psat.calculateExisting();\
    auto ex = psat.getExisting();

  for (int i=1; i<=10000; i=i+2) {
    BASE
    CALC
    Check(ex.motorShaftPower_,ex.motorShaftPower_,"SAME");
  }

  {
    BASE
    motor.setMotorRpm(1786);
    fd.setMotorPower(80);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(79.1,ex.motorPowerFactor_);
    Check(127,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedPower(100);
    motor.setFullLoadAmps(113.8);
    CALC
    Check(101.8,ex.motorShaftPower_);
    Check100(94.9,ex.motorEfficiency_);
    Check100(86.7,ex.motorPowerFactor_);
    Check(115.8,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    fd.setVoltage(260);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(138.8,ex.motorPowerFactor_);
    Check(128,ex.motorCurrent_);
  }
  {
    BASE
    motor.setMotorRpm(1200);
    fd.setMotorPower(80);
    motor.setFullLoadAmps(235.3);
    CALC
    Check(101.4,ex.motorShaftPower_);
    Check100(94.5,ex.motorEfficiency_);
    Check100(74.3,ex.motorPowerFactor_);
    Check(135.1,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(111.855);
    CALC
    Check(143.4,ex.motorShaftPower_);
    Check100(95.6,ex.motorEfficiency_);
    Check100(84.3,ex.motorPowerFactor_);
    Check(166.5,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedVoltage(200);
    motor.setFullLoadAmps(519.3);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(35.2,ex.motorPowerFactor_);
    Check(284.9,ex.motorCurrent_);
  }
  {
    BASE
    CALC
    Check(217.5,ex.motorCurrent_);
  }
  {
    BASE
    fd.setLoadEstimationMethod(FieldData::LoadEstimationMethod::CURRENT);
    fd.setMotorAmps(218);
    fd.setMotorPower(0);
    CALC
    Check(150.4,ex.motorPower_);
    Check100(72.5,ex.pumpEfficiency_);
  }
  {
    BASE
    fd.setMotorPower(80);
    CALC
    Check(700.8,ex.annualEnergy_);
  }
  {
    BASE
    fin.setOperatingFraction(.25);
    CALC
    Check(328.5,ex.annualEnergy_);
    Check(16.4,ex.annualCost_);
  }
  {
    BASE
    motor.setFullLoadAmps(300);
    CALC
    Check(288.9,ex.motorCurrent_);
  }
  {
    BASE
    motor.setEfficiencyClass(Motor::EfficiencyClass(0));
    CALC
    Check(213.7,ex.motorCurrent_);
  }
  {
    BASE
    motor.setEfficiencyClass(Motor::EfficiencyClass(2));
    motor.setSpecifiedEfficiency(75);
    CALC
    Check(173.7,ex.motorCurrent_);
  }
  cout << "done";
}

void Wtf(const FunctionCallbackInfo<Value>& args) {
}

void Init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "results", Results);
  NODE_SET_METHOD(exports, "estFLA", EstFLA);
  NODE_SET_METHOD(exports, "motorPerformance", MotorPerformance);
  NODE_SET_METHOD(exports, "test", Test);
  NODE_SET_METHOD(exports, "wtf", Wtf);
}

NODE_MODULE(bridge, Init)

<|endoftext|>


<commit_before>/*************************************
** Tsunagari Tile Engine            **
** ui-log.cpp                       **
** Copyright 2016-2017 Paul Merrill **
*************************************/

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

#include "pack/ui.h"

#include "pack/pool.h"
#include "util/unique.h"

static Unique<Pool> pool(Pool::makePool("ui", 1));

void uiShowAddingFile(const std::string& path) {
    pool->schedule([=] {
        printf("Adding %s\n", path.c_str());
    });
}

void uiShowWritingArchive(const std::string& archivePath) {
    pool->schedule([=] {
        printf("Writing to %s\n", archivePath.c_str());
    });
}

void uiShowListingEntry(const std::string& blobPath, uint64_t blobSize) {
    pool->schedule([=] {
        printf("%s: %llu bytes\n", blobPath.c_str(), blobSize);
    });
}

void uiShowExtractingFile(const std::string& blobPath, uint64_t blobSize) {
    pool->schedule([=] {
        printf("Extracting %s: %llu bytes\n", blobPath.c_str(), blobSize);
    });
}
<commit_msg>ui-log: Fix warning on GCC<commit_after>/*************************************
** Tsunagari Tile Engine            **
** ui-log.cpp                       **
** Copyright 2016-2017 Paul Merrill **
*************************************/

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

#include "pack/ui.h"

#include "pack/pool.h"
#include "util/unique.h"

static Unique<Pool> pool(Pool::makePool("ui", 1));

void uiShowAddingFile(const std::string& path) {
    pool->schedule([=] {
        printf("Adding %s\n", path.c_str());
    });
}

void uiShowWritingArchive(const std::string& archivePath) {
    pool->schedule([=] {
        printf("Writing to %s\n", archivePath.c_str());
    });
}

void uiShowListingEntry(const std::string& blobPath, uint64_t blobSize) {
    pool->schedule([=] {
        printf("%s: %lu bytes\n", blobPath.c_str(), blobSize);
    });
}

void uiShowExtractingFile(const std::string& blobPath, uint64_t blobSize) {
    pool->schedule([=] {
        printf("Extracting %s: %lu bytes\n", blobPath.c_str(), blobSize);
    });
}
<|endoftext|>


<commit_before>#ifndef slic3r_Preferences_hpp_
#define slic3r_Preferences_hpp_

#include "GUI.hpp"
#include "GUI_Utils.hpp"

#include <wx/dialog.h>
#include <map>

namespace Slic3r {
namespace GUI {

class ConfigOptionsGroup;

class PreferencesDialog : public DPIDialog
{
	std::map<std::string, std::string>	m_values;
	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_general;
	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_camera;
	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_gui;
	wxSizer*                            m_icon_size_sizer;
	wxRadioBox*							m_layout_mode_box;
    bool                                isOSX {false};
public:
	PreferencesDialog(wxWindow* parent);
	~PreferencesDialog() {}

	void	build();
	void	accept();

protected:
    void on_dpi_changed(const wxRect &suggested_rect) override;
    void layout();
    void create_icon_size_slider();
    void create_settings_mode_widget();
};

} // GUI
} // Slic3r

#endif /* slic3r_Preferences_hpp_ */
<commit_msg>Fixed OSX build<commit_after>#ifndef slic3r_Preferences_hpp_
#define slic3r_Preferences_hpp_

#include "GUI.hpp"
#include "GUI_Utils.hpp"

#include <wx/dialog.h>
#include <map>

class wxRadioBox;

namespace Slic3r {
namespace GUI {

class ConfigOptionsGroup;

class PreferencesDialog : public DPIDialog
{
	std::map<std::string, std::string>	m_values;
	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_general;
	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_camera;
	std::shared_ptr<ConfigOptionsGroup>	m_optgroup_gui;
	wxSizer*                            m_icon_size_sizer;
	wxRadioBox*							m_layout_mode_box;
    bool                                isOSX {false};
public:
	PreferencesDialog(wxWindow* parent);
	~PreferencesDialog() {}

	void	build();
	void	accept();

protected:
    void on_dpi_changed(const wxRect &suggested_rect) override;
    void layout();
    void create_icon_size_slider();
    void create_settings_mode_widget();
};

} // GUI
} // Slic3r

#endif /* slic3r_Preferences_hpp_ */
<|endoftext|>


<commit_before>#include <nan.h>
#include <node.h>
#include <string>
#include <cstring>

#include "../include/str_array_converter.h"
#include "git2/strarray.h"

using namespace v8;
using namespace node;

git_strarray *StrArrayConverter::Convert(Handle<v8::Value> val) {
  if (!val->BooleanValue()) {
    return NULL;
  }
  else if (val->IsArray()) {
    return ConvertArray(Array::Cast(*val));
  }
  else if (val->IsString() || val->IsStringObject()) {
    return ConvertString(val->ToString());
  }
  else {
    return NULL;
  }
}

static git_strarray * StrArrayConverter::AllocStrArray(const size_t count) {
  const size_t size = sizeof(git_strarray) + (sizeof(char*) * count);
  uint8_t* memory = reinterpret_cast<uint8_t*>(malloc(size));
  git_strarray *result = reinterpret_cast<git_strarray *>(memory);
  result->count = count;
  result->strings = reinterpret_cast<char**>(memory + sizeof(git_strarray));
  return result;
}

git_strarray *StrArrayConverter::ConvertArray(Array *val) {
  git_strarray *result = AllocStrArray(val->Length());

  for(size_t i = 0; i < result->count; i++) {
    NanUtf8String entry(val->Get(i));
    result->strings[i] = strdup(*entry);
  }

  return result;
}

git_strarray* StrArrayConverter::ConvertString(Handle<String> val) {
  char *strings[1];
  NanUtf8String utf8String(val);

  strings[0] = *utf8String;

  return ConstructStrArray(1, strings);
}

git_strarray *StrArrayConverter::ConstructStrArray(int argc, char** argv) {
  git_strarray *result = AllocStrArray(argc);

  for(size_t i = 0; i < result->count; i++) {
    result->strings[i] = strdup(argv[i]);
  }

  return result;
}
<commit_msg>Fix to the StrConverter<commit_after>#include <nan.h>
#include <node.h>
#include <string>
#include <cstring>

#include "../include/str_array_converter.h"
#include "git2/strarray.h"

using namespace v8;
using namespace node;

git_strarray *StrArrayConverter::Convert(Handle<v8::Value> val) {
  if (!val->BooleanValue()) {
    return NULL;
  }
  else if (val->IsArray()) {
    return ConvertArray(Array::Cast(*val));
  }
  else if (val->IsString() || val->IsStringObject()) {
    return ConvertString(val->ToString());
  }
  else {
    return NULL;
  }
}

git_strarray * StrArrayConverter::AllocStrArray(const size_t count) {
  const size_t size = sizeof(git_strarray) + (sizeof(char*) * count);
  uint8_t* memory = reinterpret_cast<uint8_t*>(malloc(size));
  git_strarray *result = reinterpret_cast<git_strarray *>(memory);
  result->count = count;
  result->strings = reinterpret_cast<char**>(memory + sizeof(git_strarray));
  return result;
}

git_strarray *StrArrayConverter::ConvertArray(Array *val) {
  git_strarray *result = AllocStrArray(val->Length());

  for(size_t i = 0; i < result->count; i++) {
    NanUtf8String entry(val->Get(i));
    result->strings[i] = strdup(*entry);
  }

  return result;
}

git_strarray* StrArrayConverter::ConvertString(Handle<String> val) {
  char *strings[1];
  NanUtf8String utf8String(val);

  strings[0] = *utf8String;

  return ConstructStrArray(1, strings);
}

git_strarray *StrArrayConverter::ConstructStrArray(int argc, char** argv) {
  git_strarray *result = AllocStrArray(argc);

  for(size_t i = 0; i < result->count; i++) {
    result->strings[i] = strdup(argv[i]);
  }

  return result;
}
<|endoftext|>


<commit_before>/**
 * pty.cc
 * This file is responsible for starting processes
 * with pseudo-terminal file descriptors.
 *
 * man pty
 * man tty_ioctl
 * man tcsetattr
 * man forkpty
 */

#include <v8.h>
#include <node.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

/* forkpty */
/* http://www.gnu.org/software/gnulib/manual/html_node/forkpty.html */
#if defined(__GLIBC__) || defined(__CYGWIN__)
  #include <pty.h>
#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
  #include <util.h>
#elif defined(__FreeBSD__)
  #include <libutil.h>
#else
  #include <pty.h>
#endif

#include <utmp.h> /* login_tty */
#include <termios.h> /* tcgetattr, tty_ioctl */

using namespace std;
using namespace node;
using namespace v8;

static Handle<Value> PtyFork(const Arguments&);
static Handle<Value> PtyResize(const Arguments&);
static int pty_execvpe(const char *file, char **argv, char **envp);
static int pty_nonblock(int fd);
extern "C" void init(Handle<Object>);

static Handle<Value> PtyFork(const Arguments& args) {
  HandleScope scope;

  if (args.Length() < 6) {
    return ThrowException(Exception::Error(
      String::New("Not enough arguments.")));
  }

  if (!args[0]->IsString()) {
    return ThrowException(Exception::Error(
      String::New("file must be a string.")));
  }

  if (!args[1]->IsArray()) {
    return ThrowException(Exception::Error(
      String::New("args must be an array.")));
  }

  if (!args[2]->IsArray()) {
    return ThrowException(Exception::Error(
      String::New("env must be an array.")));
  }

  if (!args[3]->IsString()) {
    return ThrowException(Exception::Error(
      String::New("cwd must be a string.")));
  }

  if (!args[4]->IsNumber() || !args[5]->IsNumber()) {
    return ThrowException(Exception::Error(
      String::New("cols and rows must be numbers.")));
  }

  // node/src/node_child_process.cc

  // file
  String::Utf8Value file(args[0]->ToString());

  // args
  int i = 0;
  Local<Array> argv_ = Local<Array>::Cast(args[1]);
  int argc = argv_->Length();
  int argl = argc + 1 + 1;
  char **argv = new char*[argl];
  argv[0] = strdup(*file);
  argv[argl-1] = NULL;
  for (; i < argc; i++) {
    String::Utf8Value arg(argv_->Get(Integer::New(i))->ToString());
    argv[i+1] = strdup(*arg);
  }

  // env
  i = 0;
  Local<Array> env_ = Local<Array>::Cast(args[2]);
  int envc = env_->Length();
  char **env = new char*[envc+1];
  env[envc] = NULL;
  for (; i < envc; i++) {
    String::Utf8Value pair(env_->Get(Integer::New(i))->ToString());
    env[i] = strdup(*pair);
  }

  // cwd
  String::Utf8Value cwd_(args[3]->ToString());
  char *cwd = strdup(*cwd_);

  // size
  struct winsize winp = {};
  Local<Integer> cols = args[4]->ToInteger();
  Local<Integer> rows = args[5]->ToInteger();
  winp.ws_col = cols->Value();
  winp.ws_row = rows->Value();

  // fork the pty
  int master;
  char name[40];
  pid_t pid = forkpty(&master, name, NULL, &winp);

  switch (pid) {
    case -1:
      return ThrowException(Exception::Error(
        String::New("forkpty failed.")));
    case 0:
      if (strlen(cwd)) chdir(cwd);

      pty_execvpe(argv[0], argv, env);

      perror("execvp failed");
      _exit(1);
    default:
      // cleanup
      for (i = 0; i < argl; i++) free(argv[i]);
      delete[] argv;

      for (i = 0; i < envc; i++) free(env[i]);
      delete[] env;

      free(cwd);

      // nonblocking
      if (pty_nonblock(master) == -1) {
        return ThrowException(Exception::Error(
          String::New("Could not set master fd to nonblocking.")));
      }

      Local<Object> obj = Object::New();
      obj->Set(String::New("fd"), Number::New(master));
      obj->Set(String::New("pid"), Number::New(pid));
      obj->Set(String::New("pty"), String::New(name));

      return scope.Close(obj);
  }

  return Undefined();
}

/**
 * Expose Resize Functionality
 */

static Handle<Value> PtyResize(const Arguments& args) {
  HandleScope scope;

  if (args.Length() > 0 && !args[0]->IsNumber()) {
    return ThrowException(Exception::Error(
      String::New("First argument must be a number.")));
  }

  struct winsize winp = {};
  winp.ws_col = 80;
  winp.ws_row = 30;

  int fd = args[0]->ToInteger()->Value();

  if (args.Length() == 3) {
    if (args[1]->IsNumber() && args[2]->IsNumber()) {
      Local<Integer> cols = args[1]->ToInteger();
      Local<Integer> rows = args[2]->ToInteger();

      winp.ws_col = cols->Value();
      winp.ws_row = rows->Value();
    } else {
      return ThrowException(Exception::Error(
        String::New("cols and rows need to be numbers.")));
    }
  }

  if (ioctl(fd, TIOCSWINSZ, &winp) == -1) {
    return ThrowException(Exception::Error(
      String::New("ioctl failed.")));
  }

  return Undefined();
}

/**
 * execvpe
 */

// execvpe(3) is not portable.
// http://www.gnu.org/software/gnulib/manual/html_node/execvpe.html

static int pty_execvpe(const char *file, char **argv, char **envp) {
  char **old = environ;
  environ = envp;
  int ret = execvp(file, argv);
  environ = old;
  return ret;
}

/**
 * FD to nonblocking
 */

static int pty_nonblock(int fd) {
  int flags = fcntl(fd, F_GETFL, 0);
  if (flags == -1) return -1;
  return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

/**
 * Init
 */

extern "C" void init(Handle<Object> target) {
  HandleScope scope;
  NODE_SET_METHOD(target, "fork", PtyFork);
  NODE_SET_METHOD(target, "resize", PtyResize);
}
<commit_msg>fix build on mac. closes #4.<commit_after>/**
 * pty.cc
 * This file is responsible for starting processes
 * with pseudo-terminal file descriptors.
 *
 * man pty
 * man tty_ioctl
 * man tcsetattr
 * man forkpty
 */

#include <v8.h>
#include <node.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

/* forkpty */
/* http://www.gnu.org/software/gnulib/manual/html_node/forkpty.html */
#if defined(__GLIBC__) || defined(__CYGWIN__)
  #include <pty.h>
#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
  #include <util.h>
#elif defined(__FreeBSD__)
  #include <libutil.h>
#else
  #include <pty.h>
#endif

#include <utmp.h> /* login_tty */
#include <termios.h> /* tcgetattr, tty_ioctl */

// environ for execvpe
#ifdef __APPLE__
  #include <crt_externs.h>
  #define environ (*_NSGetEnviron())
#else
extern char **environ;
#endif

using namespace std;
using namespace node;
using namespace v8;

static Handle<Value> PtyFork(const Arguments&);
static Handle<Value> PtyResize(const Arguments&);
static int pty_execvpe(const char *file, char **argv, char **envp);
static int pty_nonblock(int fd);
extern "C" void init(Handle<Object>);

static Handle<Value> PtyFork(const Arguments& args) {
  HandleScope scope;

  if (args.Length() < 6) {
    return ThrowException(Exception::Error(
      String::New("Not enough arguments.")));
  }

  if (!args[0]->IsString()) {
    return ThrowException(Exception::Error(
      String::New("file must be a string.")));
  }

  if (!args[1]->IsArray()) {
    return ThrowException(Exception::Error(
      String::New("args must be an array.")));
  }

  if (!args[2]->IsArray()) {
    return ThrowException(Exception::Error(
      String::New("env must be an array.")));
  }

  if (!args[3]->IsString()) {
    return ThrowException(Exception::Error(
      String::New("cwd must be a string.")));
  }

  if (!args[4]->IsNumber() || !args[5]->IsNumber()) {
    return ThrowException(Exception::Error(
      String::New("cols and rows must be numbers.")));
  }

  // node/src/node_child_process.cc

  // file
  String::Utf8Value file(args[0]->ToString());

  // args
  int i = 0;
  Local<Array> argv_ = Local<Array>::Cast(args[1]);
  int argc = argv_->Length();
  int argl = argc + 1 + 1;
  char **argv = new char*[argl];
  argv[0] = strdup(*file);
  argv[argl-1] = NULL;
  for (; i < argc; i++) {
    String::Utf8Value arg(argv_->Get(Integer::New(i))->ToString());
    argv[i+1] = strdup(*arg);
  }

  // env
  i = 0;
  Local<Array> env_ = Local<Array>::Cast(args[2]);
  int envc = env_->Length();
  char **env = new char*[envc+1];
  env[envc] = NULL;
  for (; i < envc; i++) {
    String::Utf8Value pair(env_->Get(Integer::New(i))->ToString());
    env[i] = strdup(*pair);
  }

  // cwd
  String::Utf8Value cwd_(args[3]->ToString());
  char *cwd = strdup(*cwd_);

  // size
  struct winsize winp = {};
  Local<Integer> cols = args[4]->ToInteger();
  Local<Integer> rows = args[5]->ToInteger();
  winp.ws_col = cols->Value();
  winp.ws_row = rows->Value();

  // fork the pty
  int master;
  char name[40];
  pid_t pid = forkpty(&master, name, NULL, &winp);

  switch (pid) {
    case -1:
      return ThrowException(Exception::Error(
        String::New("forkpty failed.")));
    case 0:
      if (strlen(cwd)) chdir(cwd);

      pty_execvpe(argv[0], argv, env);

      perror("execvp failed");
      _exit(1);
    default:
      // cleanup
      for (i = 0; i < argl; i++) free(argv[i]);
      delete[] argv;

      for (i = 0; i < envc; i++) free(env[i]);
      delete[] env;

      free(cwd);

      // nonblocking
      if (pty_nonblock(master) == -1) {
        return ThrowException(Exception::Error(
          String::New("Could not set master fd to nonblocking.")));
      }

      Local<Object> obj = Object::New();
      obj->Set(String::New("fd"), Number::New(master));
      obj->Set(String::New("pid"), Number::New(pid));
      obj->Set(String::New("pty"), String::New(name));

      return scope.Close(obj);
  }

  return Undefined();
}

/**
 * Expose Resize Functionality
 */

static Handle<Value> PtyResize(const Arguments& args) {
  HandleScope scope;

  if (args.Length() > 0 && !args[0]->IsNumber()) {
    return ThrowException(Exception::Error(
      String::New("First argument must be a number.")));
  }

  struct winsize winp = {};
  winp.ws_col = 80;
  winp.ws_row = 30;

  int fd = args[0]->ToInteger()->Value();

  if (args.Length() == 3) {
    if (args[1]->IsNumber() && args[2]->IsNumber()) {
      Local<Integer> cols = args[1]->ToInteger();
      Local<Integer> rows = args[2]->ToInteger();

      winp.ws_col = cols->Value();
      winp.ws_row = rows->Value();
    } else {
      return ThrowException(Exception::Error(
        String::New("cols and rows need to be numbers.")));
    }
  }

  if (ioctl(fd, TIOCSWINSZ, &winp) == -1) {
    return ThrowException(Exception::Error(
      String::New("ioctl failed.")));
  }

  return Undefined();
}

/**
 * execvpe
 */

// execvpe(3) is not portable.
// http://www.gnu.org/software/gnulib/manual/html_node/execvpe.html

static int pty_execvpe(const char *file, char **argv, char **envp) {
  char **old = environ;
  environ = envp;
  int ret = execvp(file, argv);
  environ = old;
  return ret;
}

/**
 * FD to nonblocking
 */

static int pty_nonblock(int fd) {
  int flags = fcntl(fd, F_GETFL, 0);
  if (flags == -1) return -1;
  return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

/**
 * Init
 */

extern "C" void init(Handle<Object> target) {
  HandleScope scope;
  NODE_SET_METHOD(target, "fork", PtyFork);
  NODE_SET_METHOD(target, "resize", PtyResize);
}
<|endoftext|>


<commit_before>/********************************************************************
 * AUTHORS: Vijay Ganesh
 *
 * BEGIN DATE: November, 2005
 *
 * LICENSE: Please view LICENSE file in the home dir of this Program
 ********************************************************************/
// -*- c++ -*-

#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <ctime>
#include <unistd.h>
#include <signal.h>
//#include <zlib.h>
#include <stdio.h>
#include "../AST/AST.h"
#include "../sat/core/Solver.h"
#include "../sat/core/SolverTypes.h"
//#include "../sat/VarOrder.h"

#include <unistd.h>

#ifdef EXT_HASH_MAP
  using namespace __gnu_cxx;
#endif

/* GLOBAL FUNCTION: parser
 */
extern int smtparse();
extern int cvcparse();

namespace BEEV
{
extern BEEV::ASTNode SingleBitOne;
extern BEEV::ASTNode SingleBitZero;
}

/* GLOBAL VARS: Some global vars for the Main function.
 *
 */
const char * prog = "stp";
int linenum  = 1;
const char * usage = "Usage: %s [-option] [infile]\n";
std::string helpstring = "\n\n";

// Amount of memory to ask for at beginning of main.
static const intptr_t INITIAL_MEMORY_PREALLOCATION_SIZE = 4000000;

/******************************************************************************
 * MAIN FUNCTION:
 *
 * step 0. Parse the input into an ASTVec.
 * step 1. Do BV Rewrites
 * step 2. Bitblasts the ASTNode.
 * step 3. Convert to CNF
 * step 4. Convert to SAT
 * step 5. Call SAT to determine if input is SAT or UNSAT
 ******************************************************************************/
int main(int argc, char ** argv) {
  char * infile;
  extern FILE *cvcin;
  extern FILE *smtin;

  // Grab some memory from the OS upfront to reduce system time when individual
  // hash tables are being allocated

  if (sbrk(INITIAL_MEMORY_PREALLOCATION_SIZE) == ((void *) -1)) {
    // FIXME: figure out how to get and print the real error message.
    BEEV::FatalError("Initial allocation of memory failed.");
  }

  //populate the help string
  helpstring +=  "-r  : switch refinement off (optimizations are ON by default)\n";
  helpstring +=  "-w  : switch wordlevel solver off (optimizations are ON by default)\n";
  helpstring +=  "-a  : switch optimizations off (optimizations are ON by default)\n";
  helpstring +=  "-s  : print function statistics\n";
  helpstring +=  "-v  : print nodes \n";
  helpstring +=  "-c  : construct counterexample\n";
  helpstring +=  "-d  : check counterexample\n";
  helpstring +=  "-p  : print counterexample\n";
  helpstring +=  "-y  : print counterexample in binary\n";
  helpstring +=  "-b  : STP input read back\n";
  helpstring +=  "-x  : flatten nested XORs\n";
  helpstring +=  "-h  : help\n";
  helpstring +=  "-m  : use the SMTLIB parser\n";

  for(int i=1; i < argc;i++) {
    if(argv[i][0] == '-') {
      switch(argv[i][1]) {
      case 'a' :
	BEEV::optimize_flag = false;
	break;
      case 'b':
	BEEV::print_STPinput_back_flag = true;
	break;
      case 'c':
	BEEV::construct_counterexample_flag = true;
	break;
      case 'd':
	BEEV::construct_counterexample_flag = true;
	BEEV::check_counterexample_flag = true;
	break;
      case 'h':
	fprintf(stderr,usage,prog);
	cout << helpstring;
	//BEEV::FatalError("");
	return -1;
	break;
      case 'n':
	BEEV::print_output_flag = true;
	break;
      case 'm':
	BEEV::smtlib_parser_flag=true;
	BEEV::division_by_zero_returns_one = true;
	break;
      case 'p':
	BEEV::print_counterexample_flag = true;
	break;
      case 'y':
	BEEV::print_binary_flag = true;
	break;
      case 'q':
	BEEV::print_arrayval_declaredorder_flag = true;
	break;
      case 'r':
	BEEV::arrayread_refinement_flag = false;
	break;
      case 's' :
	BEEV::stats_flag = true;
	break;
      case 'u':
	BEEV::arraywrite_refinement_flag = false;
	break;
      case 'v' :
	BEEV::print_nodes_flag = true;
	break;
      case 'w':
	BEEV::wordlevel_solve_flag = false;
	break;
      case 'x':
	BEEV::xor_flatten_flag = true;
	break;
      case 'z':
	BEEV::print_sat_varorder_flag = true;
	break;
      default:
	fprintf(stderr,usage,prog);
	cout << helpstring;
	//BEEV::FatalError("");
	return -1;
	break;
      }
      if(argv[i][2]) {
	fprintf(stderr, "Multiple character options are not allowed.\n");
	fprintf(stderr, "(for example: -ab is not an abbreviation for -a -b)\n");
	fprintf(stderr,usage,prog);
	cout << helpstring;
	return -1;
      }
    } else {
      infile = argv[i];

      if (BEEV::smtlib_parser_flag)
	{
	  smtin = fopen(infile,"r");
	  if(smtin == NULL)
	    {
	      fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
	      BEEV::FatalError("");
	    }
	}
      else
	{
	  cvcin = fopen(infile,"r");
	  if(cvcin == NULL)
	    {
	      fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
	      BEEV::FatalError("");
	    }
	}
    }
  }

  CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot();
  if(0 != c) {
    cout << CONSTANTBV::BitVector_Error(c) << endl;
    return 0;
  }

  //want to print the output always from the commandline.
  BEEV::print_output_flag = true;
  BEEV::globalBeevMgr_for_parser = new BEEV::BeevMgr();

  BEEV::SingleBitOne = BEEV::globalBeevMgr_for_parser->CreateOneConst(1);
  BEEV::SingleBitZero = BEEV::globalBeevMgr_for_parser->CreateZeroConst(1);

  if (BEEV::smtlib_parser_flag)
    smtparse();
  else
    cvcparse();
}//end of Main
<commit_msg>Trying to get version number in the executable<commit_after>/********************************************************************
 * AUTHORS: Vijay Ganesh
 *
 * BEGIN DATE: November, 2005
 *
 * LICENSE: Please view LICENSE file in the home dir of this Program
 ********************************************************************/
// -*- c++ -*-

#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <ctime>
#include <unistd.h>
#include <signal.h>
//#include <zlib.h>
#include <stdio.h>
#include "../AST/AST.h"
#include "../sat/core/Solver.h"
#include "../sat/core/SolverTypes.h"
//#include "../sat/VarOrder.h"

#include <unistd.h>

#ifdef EXT_HASH_MAP
  using namespace __gnu_cxx;
#endif

/* GLOBAL FUNCTION: parser
 */
extern int smtparse();
extern int cvcparse();

namespace BEEV
{
extern BEEV::ASTNode SingleBitOne;
extern BEEV::ASTNode SingleBitZero;
}

const string version = "$Id$";

/* GLOBAL VARS: Some global vars for the Main function.
 *
 */
const char * prog = "stp";
int linenum  = 1;
const char * usage = "Usage: %s [-option] [infile]\n";
std::string helpstring = "\n\n";

// Amount of memory to ask for at beginning of main.
static const intptr_t INITIAL_MEMORY_PREALLOCATION_SIZE = 4000000;

/******************************************************************************
 * MAIN FUNCTION:
 *
 * step 0. Parse the input into an ASTVec.
 * step 1. Do BV Rewrites
 * step 2. Bitblasts the ASTNode.
 * step 3. Convert to CNF
 * step 4. Convert to SAT
 * step 5. Call SAT to determine if input is SAT or UNSAT
 ******************************************************************************/
int main(int argc, char ** argv) {
  char * infile;
  extern FILE *cvcin;
  extern FILE *smtin;

  // Grab some memory from the OS upfront to reduce system time when individual
  // hash tables are being allocated

  if (sbrk(INITIAL_MEMORY_PREALLOCATION_SIZE) == ((void *) -1)) {
    // FIXME: figure out how to get and print the real error message.
    BEEV::FatalError("Initial allocation of memory failed.");
  }

  //populate the help string
  helpstring +=  "-r  : switch refinement off (optimizations are ON by default)\n";
  helpstring +=  "-w  : switch wordlevel solver off (optimizations are ON by default)\n";
  helpstring +=  "-a  : switch optimizations off (optimizations are ON by default)\n";
  helpstring +=  "-s  : print function statistics\n";
  helpstring +=  "-v  : print nodes \n";
  helpstring +=  "-c  : construct counterexample\n";
  helpstring +=  "-d  : check counterexample\n";
  helpstring +=  "-p  : print counterexample\n";
  helpstring +=  "-y  : print counterexample in binary\n";
  helpstring +=  "-b  : STP input read back\n";
  helpstring +=  "-x  : flatten nested XORs\n";
  helpstring +=  "-h  : help\n";
  helpstring +=  "-m  : use the SMTLIB parser\n";

  for(int i=1; i < argc;i++) {
    if(argv[i][0] == '-') {
      switch(argv[i][1]) {
      case 'a' :
	BEEV::optimize_flag = false;
	break;
      case 'b':
	BEEV::print_STPinput_back_flag = true;
	break;
      case 'c':
	BEEV::construct_counterexample_flag = true;
	break;
      case 'd':
	BEEV::construct_counterexample_flag = true;
	BEEV::check_counterexample_flag = true;
	break;
      case 'h':
	fprintf(stderr,usage,prog);
	cout << helpstring;
	//BEEV::FatalError("");
	return -1;
	break;
      case 'n':
	BEEV::print_output_flag = true;
	break;
      case 'm':
	BEEV::smtlib_parser_flag=true;
	BEEV::division_by_zero_returns_one = true;
	break;
      case 'p':
	BEEV::print_counterexample_flag = true;
	break;
      case 'y':
	BEEV::print_binary_flag = true;
	break;
      case 'q':
	BEEV::print_arrayval_declaredorder_flag = true;
	break;
      case 'r':
	BEEV::arrayread_refinement_flag = false;
	break;
      case 's' :
	BEEV::stats_flag = true;
	break;
      case 'u':
	BEEV::arraywrite_refinement_flag = false;
	break;
      case 'v' :
	BEEV::print_nodes_flag = true;
	break;
      case 'w':
	BEEV::wordlevel_solve_flag = false;
	break;
      case 'x':
	BEEV::xor_flatten_flag = true;
	break;
      case 'z':
	BEEV::print_sat_varorder_flag = true;
	break;
      default:
	fprintf(stderr,usage,prog);
	cout << helpstring;
	//BEEV::FatalError("");
	return -1;
	break;
      }
      if(argv[i][2]) {
	fprintf(stderr, "Multiple character options are not allowed.\n");
	fprintf(stderr, "(for example: -ab is not an abbreviation for -a -b)\n");
	fprintf(stderr,usage,prog);
	cout << helpstring;
	return -1;
      }
    } else {
      infile = argv[i];

      if (BEEV::smtlib_parser_flag)
	{
	  smtin = fopen(infile,"r");
	  if(smtin == NULL)
	    {
	      fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
	      BEEV::FatalError("");
	    }
	}
      else
	{
	  cvcin = fopen(infile,"r");
	  if(cvcin == NULL)
	    {
	      fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
	      BEEV::FatalError("");
	    }
	}
    }
  }

  CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot();
  if(0 != c) {
    cout << CONSTANTBV::BitVector_Error(c) << endl;
    return 0;
  }

  //want to print the output always from the commandline.
  BEEV::print_output_flag = true;
  BEEV::globalBeevMgr_for_parser = new BEEV::BeevMgr();

  BEEV::SingleBitOne = BEEV::globalBeevMgr_for_parser->CreateOneConst(1);
  BEEV::SingleBitZero = BEEV::globalBeevMgr_for_parser->CreateZeroConst(1);

  if (BEEV::smtlib_parser_flag)
    smtparse();
  else
    cvcparse();
}//end of Main
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Victor Gaydov
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <CppUTest/TestHarness.h>

#include "roc_config/config.h"
#include "roc_core/scoped_ptr.h"
#include "roc_rtp/composer.h"
#include "roc_rtp/parser.h"
#include "roc_datagram/datagram_queue.h"
#include "roc_pipeline/client.h"
#include "roc_pipeline/server.h"

#include "test_sample_stream.h"
#include "test_sample_queue.h"
#include "test_datagram.h"

namespace roc {
namespace test {

using namespace pipeline;

TEST_GROUP(client_server) {
    enum {
        // Sending port.
        ClientPort = 501,

        // Receiving port.
        ServerPort = 502,

        // Number of samples in every channel per packet.
        PktSamples = ROC_CONFIG_DEFAULT_PACKET_SAMPLES,

        // Number of samples in input/output buffers.
        BufSamples = SampleStream::ReadBufsz,

        // Number of packets to read per tick.
        PacketsPerTick = 20,

        // Maximum number of sample buffers.
        MaxBuffers = PktSamples * 100 / BufSamples,

        // Percentage of packets to be lost.
        RandomLoss = 1
    };

    SampleQueue<MaxBuffers> input;
    SampleQueue<MaxBuffers> output;

    datagram::DatagramQueue network;
    TestDatagramComposer datagram_composer;

    rtp::Composer packet_composer;
    rtp::Parser packet_parser;

    core::ScopedPtr<Client> client;
    core::ScopedPtr<Server> server;

    void setup() {
    }

    void teardown() {
        LONGS_EQUAL(0, input.size());
        LONGS_EQUAL(0, output.size());
        LONGS_EQUAL(0, network.size());
    }

    void init_client(int options, size_t random_loss = 0) {
        ClientConfig config;

        config.options = options;
        config.channels = ChannelMask;
        config.samples_per_packet = PktSamples;
        config.random_loss_rate = random_loss;

        client.reset(
            new Client(input, network, datagram_composer, packet_composer, config));

        client->set_sender(new_address(ClientPort));
        client->set_receiver(new_address(ServerPort));
    }

    void init_server(int options) {
        ServerConfig config;

        config.options = options;
        config.channels = ChannelMask;
        config.latency = BufSamples;
        config.timeout = MaxBuffers;

        server.reset(new Server(network, output, config));

        server->add_port(new_address(ServerPort), packet_parser);
    }

    void flow_client_server() {
        SampleStream si;

        for (size_t n = 0; n < MaxBuffers; n++) {
            si.write(input, BufSamples);
        }

        LONGS_EQUAL(MaxBuffers, input.size());

        while (input.size() != 0) {
            CHECK(client->tick());
        }

        client->flush();

        CHECK(network.size() >= MaxBuffers * BufSamples / PktSamples);

        SampleStream so;

        for (size_t n = 0; n < MaxBuffers; n++) {
            CHECK(server->tick(PacketsPerTick, 1, BufSamples));

            LONGS_EQUAL(1, output.size());

            so.read(output, BufSamples);

            LONGS_EQUAL(0, output.size());
        }

        LONGS_EQUAL(0, network.size());
    }
};

TEST(client_server, bare) {
    init_client(0);
    init_server(0);
    flow_client_server();
}

TEST(client_server, interleaving) {
    init_client(EnableInterleaving);
    init_server(0);
    flow_client_server();
}

TEST(client_server, ldpc_only_client) {
    init_client(EnableLDPC);
    init_server(0);
    flow_client_server();
}

TEST(client_server, ldpc_only_server) {
    init_client(0);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc) {
    init_client(EnableLDPC);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc_interleaving) {
    init_client(EnableLDPC | EnableInterleaving);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc_random_loss) {
    init_client(EnableLDPC, RandomLoss);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc_interleaving_random_loss) {
    init_client(EnableLDPC | EnableInterleaving, RandomLoss);
    init_server(EnableLDPC);
    flow_client_server();
}

} // namespace test
} // namespace roc
<commit_msg>Disable ldpc tests when built w/o openfec<commit_after>/*
 * Copyright (c) 2015 Victor Gaydov
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <CppUTest/TestHarness.h>

#include "roc_config/config.h"
#include "roc_core/scoped_ptr.h"
#include "roc_rtp/composer.h"
#include "roc_rtp/parser.h"
#include "roc_datagram/datagram_queue.h"
#include "roc_pipeline/client.h"
#include "roc_pipeline/server.h"

#include "test_sample_stream.h"
#include "test_sample_queue.h"
#include "test_datagram.h"

namespace roc {
namespace test {

using namespace pipeline;

TEST_GROUP(client_server) {
    enum {
        // Sending port.
        ClientPort = 501,

        // Receiving port.
        ServerPort = 502,

        // Number of samples in every channel per packet.
        PktSamples = ROC_CONFIG_DEFAULT_PACKET_SAMPLES,

        // Number of samples in input/output buffers.
        BufSamples = SampleStream::ReadBufsz,

        // Number of packets to read per tick.
        PacketsPerTick = 20,

        // Maximum number of sample buffers.
        MaxBuffers = PktSamples * 100 / BufSamples,

        // Percentage of packets to be lost.
        RandomLoss = 1
    };

    SampleQueue<MaxBuffers> input;
    SampleQueue<MaxBuffers> output;

    datagram::DatagramQueue network;
    TestDatagramComposer datagram_composer;

    rtp::Composer packet_composer;
    rtp::Parser packet_parser;

    core::ScopedPtr<Client> client;
    core::ScopedPtr<Server> server;

    void setup() {
    }

    void teardown() {
        LONGS_EQUAL(0, input.size());
        LONGS_EQUAL(0, output.size());
        LONGS_EQUAL(0, network.size());
    }

    void init_client(int options, size_t random_loss = 0) {
        ClientConfig config;

        config.options = options;
        config.channels = ChannelMask;
        config.samples_per_packet = PktSamples;
        config.random_loss_rate = random_loss;

        client.reset(
            new Client(input, network, datagram_composer, packet_composer, config));

        client->set_sender(new_address(ClientPort));
        client->set_receiver(new_address(ServerPort));
    }

    void init_server(int options) {
        ServerConfig config;

        config.options = options;
        config.channels = ChannelMask;
        config.latency = BufSamples;
        config.timeout = MaxBuffers;

        server.reset(new Server(network, output, config));

        server->add_port(new_address(ServerPort), packet_parser);
    }

    void flow_client_server() {
        SampleStream si;

        for (size_t n = 0; n < MaxBuffers; n++) {
            si.write(input, BufSamples);
        }

        LONGS_EQUAL(MaxBuffers, input.size());

        while (input.size() != 0) {
            CHECK(client->tick());
        }

        client->flush();

        CHECK(network.size() >= MaxBuffers * BufSamples / PktSamples);

        SampleStream so;

        for (size_t n = 0; n < MaxBuffers; n++) {
            CHECK(server->tick(PacketsPerTick, 1, BufSamples));

            LONGS_EQUAL(1, output.size());

            so.read(output, BufSamples);

            LONGS_EQUAL(0, output.size());
        }

        LONGS_EQUAL(0, network.size());
    }
};

TEST(client_server, bare) {
    init_client(0);
    init_server(0);
    flow_client_server();
}

TEST(client_server, interleaving) {
    init_client(EnableInterleaving);
    init_server(0);
    flow_client_server();
}

#ifdef ROC_TARGET_OPENFEC
TEST(client_server, ldpc_only_client) {
    init_client(EnableLDPC);
    init_server(0);
    flow_client_server();
}

TEST(client_server, ldpc_only_server) {
    init_client(0);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc) {
    init_client(EnableLDPC);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc_interleaving) {
    init_client(EnableLDPC | EnableInterleaving);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc_random_loss) {
    init_client(EnableLDPC, RandomLoss);
    init_server(EnableLDPC);
    flow_client_server();
}

TEST(client_server, ldpc_interleaving_random_loss) {
    init_client(EnableLDPC | EnableInterleaving, RandomLoss);
    init_server(EnableLDPC);
    flow_client_server();
}
#endif // ROC_TARGET_OPENFEC

} // namespace test
} // namespace roc
<|endoftext|>