<commit_before>/*
Copyright (C) 2002 by John Harger

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; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "csgeom/vector3.h"
#include "csplugincommon/opengl/glextmanager.h"
#include "csplugincommon/opengl/glstates.h"
#include "csutil/objreg.h"
#include "csutil/ref.h"
#include "csutil/scf.h"
#include "iutil/comp.h"
#include "iutil/plugin.h"
#include "ivideo/graph2d.h"
#include "ivideo/graph3d.h"
#include "ivideo/shader/shader.h"
#include "glshader_ps1.h"
#include "ps1_emu_ati.h"
#include "ps1_emu_nv.h"

CS_PLUGIN_NAMESPACE_BEGIN(GLShaderPS1)
{

SCF_IMPLEMENT_FACTORY (csGLShader_PS1)

csGLShader_PS1::csGLShader_PS1(iBase* parent) :
  scfImplementationType (this, parent)
{
  enable = false;
  isOpen = false;
}

csGLShader_PS1::~csGLShader_PS1()
{
}

void csGLShader_PS1::Report (int severity, const char* msg, ...)
{
  va_list args;
  va_start (args, msg);
  csReportV (object_reg, severity,
    "crystalspace.graphics3d.shader.glps1", msg, args);
  va_end (args);
}

////////////////////////////////////////////////////////////////////
//                      iShaderProgramPlugin
////////////////////////////////////////////////////////////////////
bool csGLShader_PS1::SupportType(const char* type)
{
  if (!enable)
    return false;
  else if (strcasecmp (type, "fp") == 0)
    return true;
  return false;
}

csPtr<iShaderProgram> csGLShader_PS1::CreateProgram (const char* type)
{
  if (strcasecmp (type, "fp") == 0)
  {
    Open();

    if(ext->CS_GL_ATI_fragment_shader)
      return csPtr<iShaderProgram> (new csShaderGLPS1_ATI (this));
    else if(ext->CS_GL_NV_register_combiners)
      return csPtr<iShaderProgram> (new csShaderGLPS1_NV (this));
  }
  return 0;
}

void csGLShader_PS1::Open()
{
  if (isOpen) return;
  if(!object_reg)
    return;

  if (!ext) return;

  csRef<iConfigManager> config (csQueryRegistry<iConfigManager> (object_reg));
  ext->InitGL_NV_register_combiners ();
  ext->InitGL_NV_register_combiners2 ();
  ext->InitGL_NV_texture_shader ();
  ext->InitGL_NV_texture_shader2 ();
  ext->InitGL_NV_texture_shader3 ();
  if(ext->CS_GL_NV_register_combiners)
  {
    if (doVerbose)
    {
      GLint num_combiners;
      glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &num_combiners);
      Report(CS_REPORTER_SEVERITY_NOTIFY,
    	  "Max General Combiners: %d", num_combiners);
    }
  }

  ext->InitGL_ATI_fragment_shader ();

  useLists = config->GetBool ("Video.OpenGL.Shader.PS1.UseDisplayLists", true);
  if (doVerbose)
    Report(CS_REPORTER_SEVERITY_NOTIFY,
      "Display list usage %s", useLists ? "enabled" : "disabled");
  dumpTo14ConverterOutput = config->GetBool (
    "Video.OpenGL.Shader.PS1.Dump14ConverterOutput", false);

  if(ext->CS_GL_ATI_fragment_shader)
    supportedPSVersion = CS_PS_1_4;
  else if (ext->CS_GL_NV_register_combiners2
    && ext->CS_GL_NV_texture_shader)
  {
    if (ext->CS_GL_NV_texture_shader3)
      supportedPSVersion = CS_PS_1_3;
    else
      supportedPSVersion = CS_PS_1_1;
  }
  if (doVerbose)
  {
    Report(CS_REPORTER_SEVERITY_NOTIFY,
      "Highest supported PS version: %s", PSVersionStr (supportedPSVersion));
  }

  isOpen = true;
}

const char* csGLShader_PS1::PSVersionStr (csPixelShaderVersion ver) const
{
  switch (ver)
  {
  case CS_PS_1_1: return "1.1"; break;
  case CS_PS_1_2: return "1.2"; break;
  case CS_PS_1_3: return "1.3"; break;
  case CS_PS_1_4: return "1.4"; break;
  }
  return 0;
}

////////////////////////////////////////////////////////////////////
//                          iComponent
////////////////////////////////////////////////////////////////////
bool csGLShader_PS1::Initialize(iObjectRegistry* reg)
{
  object_reg = reg;
  csRef<iGraphics3D> r = csQueryRegistry<iGraphics3D> (object_reg);

  csRef<iFactory> f = scfQueryInterface<iFactory> (r);
  if (f != 0 && strcmp ("crystalspace.graphics3d.opengl",
    f->QueryClassID ()) == 0)
    enable = true;
  else
    return false;

  r->GetDriver2D()->PerformExtension ("getextmanager", &ext);
  if(!ext) return false;
  r->GetDriver2D()->PerformExtension ("getstatecache", &stateCache);
  if(!stateCache) return false;

  csRef<iVerbosityManager> verbosemgr (
    csQueryRegistry<iVerbosityManager> (object_reg));
  if (verbosemgr)
    doVerbose = verbosemgr->Enabled ("renderer.shader");
  else
    doVerbose = false;

  return true;
}

}
CS_PLUGIN_NAMESPACE_END(GLShaderPS1)
<commit_msg>Warning fix<commit_after>/*
Copyright (C) 2002 by John Harger

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; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "csgeom/vector3.h"
#include "csplugincommon/opengl/glextmanager.h"
#include "csplugincommon/opengl/glstates.h"
#include "csutil/objreg.h"
#include "csutil/ref.h"
#include "csutil/scf.h"
#include "iutil/comp.h"
#include "iutil/plugin.h"
#include "ivideo/graph2d.h"
#include "ivideo/graph3d.h"
#include "ivideo/shader/shader.h"
#include "glshader_ps1.h"
#include "ps1_emu_ati.h"
#include "ps1_emu_nv.h"

CS_PLUGIN_NAMESPACE_BEGIN(GLShaderPS1)
{

SCF_IMPLEMENT_FACTORY (csGLShader_PS1)

csGLShader_PS1::csGLShader_PS1(iBase* parent) :
  scfImplementationType (this, parent)
{
  enable = false;
  isOpen = false;
}

csGLShader_PS1::~csGLShader_PS1()
{
}

void csGLShader_PS1::Report (int severity, const char* msg, ...)
{
  va_list args;
  va_start (args, msg);
  csReportV (object_reg, severity,
    "crystalspace.graphics3d.shader.glps1", msg, args);
  va_end (args);
}

////////////////////////////////////////////////////////////////////
//                      iShaderProgramPlugin
////////////////////////////////////////////////////////////////////
bool csGLShader_PS1::SupportType(const char* type)
{
  if (!enable)
    return false;
  else if (strcasecmp (type, "fp") == 0)
    return true;
  return false;
}

csPtr<iShaderProgram> csGLShader_PS1::CreateProgram (const char* type)
{
  if (strcasecmp (type, "fp") == 0)
  {
    Open();

    if(ext->CS_GL_ATI_fragment_shader)
      return csPtr<iShaderProgram> (new csShaderGLPS1_ATI (this));
    else if(ext->CS_GL_NV_register_combiners)
      return csPtr<iShaderProgram> (new csShaderGLPS1_NV (this));
  }
  return 0;
}

void csGLShader_PS1::Open()
{
  if (isOpen) return;
  if(!object_reg)
    return;

  if (!ext) return;

  csRef<iConfigManager> config (csQueryRegistry<iConfigManager> (object_reg));
  ext->InitGL_NV_register_combiners ();
  ext->InitGL_NV_register_combiners2 ();
  ext->InitGL_NV_texture_shader ();
  ext->InitGL_NV_texture_shader2 ();
  ext->InitGL_NV_texture_shader3 ();
  if(ext->CS_GL_NV_register_combiners)
  {
    if (doVerbose)
    {
      GLint num_combiners;
      glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &num_combiners);
      Report(CS_REPORTER_SEVERITY_NOTIFY,
    	  "Max General Combiners: %d", num_combiners);
    }
  }

  ext->InitGL_ATI_fragment_shader ();

  useLists = config->GetBool ("Video.OpenGL.Shader.PS1.UseDisplayLists", true);
  if (doVerbose)
    Report(CS_REPORTER_SEVERITY_NOTIFY,
      "Display list usage %s", useLists ? "enabled" : "disabled");
  dumpTo14ConverterOutput = config->GetBool (
    "Video.OpenGL.Shader.PS1.Dump14ConverterOutput", false);

  if(ext->CS_GL_ATI_fragment_shader)
    supportedPSVersion = CS_PS_1_4;
  else if (ext->CS_GL_NV_register_combiners2
    && ext->CS_GL_NV_texture_shader)
  {
    if (ext->CS_GL_NV_texture_shader3)
      supportedPSVersion = CS_PS_1_3;
    else
      supportedPSVersion = CS_PS_1_1;
  }
  if (doVerbose)
  {
    Report(CS_REPORTER_SEVERITY_NOTIFY,
      "Highest supported PS version: %s", PSVersionStr (supportedPSVersion));
  }

  isOpen = true;
}

const char* csGLShader_PS1::PSVersionStr (csPixelShaderVersion ver) const
{
  switch (ver)
  {
  case CS_PS_1_1: return "1.1"; break;
  case CS_PS_1_2: return "1.2"; break;
  case CS_PS_1_3: return "1.3"; break;
  case CS_PS_1_4: return "1.4"; break;
  case CS_PS_INVALID: break;
  }
  return 0;
}

////////////////////////////////////////////////////////////////////
//                          iComponent
////////////////////////////////////////////////////////////////////
bool csGLShader_PS1::Initialize(iObjectRegistry* reg)
{
  object_reg = reg;
  csRef<iGraphics3D> r = csQueryRegistry<iGraphics3D> (object_reg);

  csRef<iFactory> f = scfQueryInterface<iFactory> (r);
  if (f != 0 && strcmp ("crystalspace.graphics3d.opengl",
    f->QueryClassID ()) == 0)
    enable = true;
  else
    return false;

  r->GetDriver2D()->PerformExtension ("getextmanager", &ext);
  if(!ext) return false;
  r->GetDriver2D()->PerformExtension ("getstatecache", &stateCache);
  if(!stateCache) return false;

  csRef<iVerbosityManager> verbosemgr (
    csQueryRegistry<iVerbosityManager> (object_reg));
  if (verbosemgr)
    doVerbose = verbosemgr->Enabled ("renderer.shader");
  else
    doVerbose = false;

  return true;
}

}
CS_PLUGIN_NAMESPACE_END(GLShaderPS1)
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2014, Howard Butler (howard@hobu.co)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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 <pdal/kernel/Diff.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>

#include <boost/scoped_ptr.hpp>

using boost::property_tree::ptree;

namespace pdal { namespace kernel {

Diff::Diff(int argc, const char* argv[])
    : Application(argc, argv, "dif")
    , m_sourceFile("")
    , m_candidateFile("")
    , m_useXML(false)
    , m_useJSON(false)

{
    return;
}

void Diff::validateSwitches()
{

    if (!m_sourceFile.size())
        throw app_runtime_error("No source file given!");
    if (!m_candidateFile.size())
        throw app_runtime_error("No candidate file given!");

    return;
}

void Diff::addSwitches()
{
    namespace po = boost::program_options;

    po::options_description* file_options = new po::options_description("file options");

    file_options->add_options()
        ("source", po::value<std::string>(&m_sourceFile), "source file name")
        ("candidate", po::value<std::string>(&m_candidateFile), "candidate file name")
        ("xml", po::value<bool>(&m_useXML)->zero_tokens()->implicit_value(true), "dump XML")
        ("json", po::value<bool>(&m_useJSON)->zero_tokens()->implicit_value(true), "dump JSON")

        ;

    addSwitchSet(file_options);

    po::options_description* processing_options = new po::options_description("processing options");

    processing_options->add_options()

        ;

    addSwitchSet(processing_options);

    addPositionalSwitch("source", 1);
    addPositionalSwitch("candidate", 2);

    return;
}

void Diff::checkPoints(const PointBuffer& source_data,
    const PointBuffer& candidate_data, ptree& errors)
{
    uint32_t i(0);
    uint32_t MAX_BADBYTES(20);
    uint32_t badbytes(0);

    // Both schemas have already been determined to be equal, so are the
    // same size and in the same order.
    Dimension::IdList const& sourceDims = source_data.context().dims();
    Dimension::IdList const& candidateDims = candidate_data.context().dims();

    char sbuf[8];
    char cbuf[8];
    for (PointId idx = 0; idx < source_data.size(); ++idx)
    {
        for (size_t d = 0; d < sourceDims.size(); ++d)
        {
            Dimension::Id::Enum sd = sourceDims[d];
            Dimension::Id::Enum cd = candidateDims[d];

            source_data.getRawField(sd, idx, (void *)sbuf);
            candidate_data.getRawField(cd, idx, (void *)cbuf);
            Dimension::Type::Enum t = Dimension::defaultType(cd);
            size_t size = Dimension::size(t);
            if (memcmp(sbuf, cbuf, size))
            {
                std::ostringstream oss;

                oss << "Point " << idx << " differs for dimension \"" <<
                            Dimension::name(sd) << "\" for source and candidate";
                errors.put<std::string>("data.error", oss.str());
                badbytes++;
            }
        }
        if (badbytes > MAX_BADBYTES )
            break;
    }
}

int Diff::execute()
{
    PointContext sourceCtx;

    Options sourceOptions;
    {
        sourceOptions.add<std::string>("filename", m_sourceFile);
        sourceOptions.add<bool>("debug", isDebug());
        sourceOptions.add<boost::uint32_t>("verbose", getVerboseLevel());
    }
    std::unique_ptr<Stage> source(AppSupport::makeReader(sourceOptions));
    source->prepare(sourceCtx);
    PointBufferSet sourceSet = source->execute(sourceCtx);

    ptree errors;

    PointContext candidateCtx;
    Options candidateOptions;
    {
        candidateOptions.add<std::string>("filename", m_candidateFile);
        candidateOptions.add<bool>("debug", isDebug());
        candidateOptions.add<boost::uint32_t>("verbose", getVerboseLevel());
    }

    std::unique_ptr<Stage> candidate(AppSupport::makeReader(candidateOptions));
    candidate->prepare(candidateCtx);
    PointBufferSet candidateSet = candidate->execute(candidateCtx);

    assert(sourceSet.size() == 1);
    assert(candidateSet.size() == 1);
    PointBufferPtr sourceBuf = *sourceSet.begin();
    PointBufferPtr candidateBuf = *candidateSet.begin();
    if (candidateBuf->size() != sourceBuf->size())
    {
        std::ostringstream oss;

        oss << "Source and candidate files do not have the same point count";
        errors.put<std::string>("count.error", oss.str());
        errors.put<uint32_t>("count.candidate", candidateBuf->size());
        errors.put<uint32_t>("count.source", sourceBuf->size());
    }

    MetadataNode source_metadata = sourceCtx.metadata();
    MetadataNode candidate_metadata = candidateCtx.metadata();
    if (source_metadata != candidate_metadata)
    {
        std::ostringstream oss;

        oss << "Source and candidate files do not have the same metadata count";
        //ABELL
        /**
        errors.put<std::string>("metadata.error", oss.str());
        errors.put_child("metadata.source", source_metadata.toPTree());
        errors.put_child("metadata.candidate", candidate_metadata.toPTree());
        **/
    }

    if (candidateCtx.dims().size() != sourceCtx.dims().size())
    {
        std::ostringstream oss;

        oss << "Source and candidate files do not have the same number of dimensions";
        errors.put<std::string>("schema.error", oss.str());
        // FIXME: Need to "ptree" the PointContext dimension list in some way
        // errors.put_child("schema.source", sourceCtx.schema()->toPTree());
        // errors.put_child("schema.candidate", candidateCtx.schema()->toPTree());
    }

    if (errors.size())
    {
        write_json(std::cout, errors);
        return 1;
    }
    else
    {
        // If we made it this far with no errors, now we'll
        // check the points.
        checkPoints(*sourceBuf, *candidateBuf, errors);
        if (errors.size())
        {
            write_json(std::cout, errors);
            return 1;
        }
    }

    return 0;

}

}} // pdal::kernel
<commit_msg>Diff cleanup.<commit_after>/******************************************************************************
* Copyright (c) 2014, Howard Butler (howard@hobu.co)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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 <pdal/kernel/Diff.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>

#include <boost/scoped_ptr.hpp>

using boost::property_tree::ptree;

namespace pdal {
namespace kernel {

Diff::Diff(int argc, const char* argv[])
    : Application(argc, argv, "dif")
    , m_sourceFile("")
    , m_candidateFile("")
    , m_useXML(false)
    , m_useJSON(false)

{}

void Diff::validateSwitches()
{
    if (!m_sourceFile.size())
        throw app_runtime_error("No source file given!");
    if (!m_candidateFile.size())
        throw app_runtime_error("No candidate file given!");
}

void Diff::addSwitches()
{
    namespace po = boost::program_options;

    po::options_description* file_options =
        new po::options_description("file options");

    file_options->add_options()
        ("source", po::value<std::string>(&m_sourceFile), "source file name")
        ("candidate",
            po::value<std::string>(&m_candidateFile), "candidate file name")
        ("xml",
            po::value<bool>(&m_useXML)->zero_tokens()->implicit_value(true),
            "dump XML")
        ("json",
            po::value<bool>(&m_useJSON)->zero_tokens()->implicit_value(true),
            "dump JSON")
    ;

    addSwitchSet(file_options);
    po::options_description* processing_options =
        new po::options_description("processing options");

    processing_options->add_options();

    addSwitchSet(processing_options);

    addPositionalSwitch("source", 1);
    addPositionalSwitch("candidate", 2);
}

void Diff::checkPoints(const PointBuffer& source_data,
    const PointBuffer& candidate_data, ptree& errors)
{
    uint32_t i(0);
    uint32_t MAX_BADBYTES(20);
    uint32_t badbytes(0);

    // Both schemas have already been determined to be equal, so are the
    // same size and in the same order.
    Dimension::IdList const& sourceDims = source_data.context().dims();
    Dimension::IdList const& candidateDims = candidate_data.context().dims();

    char sbuf[8];
    char cbuf[8];
    for (PointId idx = 0; idx < source_data.size(); ++idx)
    {
        for (size_t d = 0; d < sourceDims.size(); ++d)
        {
            Dimension::Id::Enum sd = sourceDims[d];
            Dimension::Id::Enum cd = candidateDims[d];

            source_data.getRawField(sd, idx, (void *)sbuf);
            candidate_data.getRawField(cd, idx, (void *)cbuf);
            Dimension::Type::Enum t = Dimension::defaultType(cd);
            size_t size = Dimension::size(t);
            if (memcmp(sbuf, cbuf, size))
            {
                std::ostringstream oss;

                oss << "Point " << idx << " differs for dimension \"" <<
                    Dimension::name(sd) << "\" for source and candidate";
                errors.put<std::string>("data.error", oss.str());
                badbytes++;
            }
        }
        if (badbytes > MAX_BADBYTES )
            break;
    }
}

int Diff::execute()
{
    PointContext sourceCtx;

    Options sourceOptions;
    {
        sourceOptions.add<std::string>("filename", m_sourceFile);
        sourceOptions.add<bool>("debug", isDebug());
        sourceOptions.add<boost::uint32_t>("verbose", getVerboseLevel());
    }
    std::unique_ptr<Stage> source(AppSupport::makeReader(sourceOptions));
    source->prepare(sourceCtx);
    PointBufferSet sourceSet = source->execute(sourceCtx);

    ptree errors;

    PointContext candidateCtx;
    Options candidateOptions;
    {
        candidateOptions.add<std::string>("filename", m_candidateFile);
        candidateOptions.add<bool>("debug", isDebug());
        candidateOptions.add<boost::uint32_t>("verbose", getVerboseLevel());
    }

    std::unique_ptr<Stage> candidate(AppSupport::makeReader(candidateOptions));
    candidate->prepare(candidateCtx);
    PointBufferSet candidateSet = candidate->execute(candidateCtx);

    assert(sourceSet.size() == 1);
    assert(candidateSet.size() == 1);
    PointBufferPtr sourceBuf = *sourceSet.begin();
    PointBufferPtr candidateBuf = *candidateSet.begin();
    if (candidateBuf->size() != sourceBuf->size())
    {
        std::ostringstream oss;

        oss << "Source and candidate files do not have the same point count";
        errors.put("count.error", oss.str());
        errors.put("count.candidate", candidateBuf->size());
        errors.put("count.source", sourceBuf->size());
    }

    MetadataNode source_metadata = sourceCtx.metadata();
    MetadataNode candidate_metadata = candidateCtx.metadata();
    if (source_metadata != candidate_metadata)
    {
        std::ostringstream oss;

        oss << "Source and candidate files do not have the same metadata count";
        errors.put("metadata.error", oss.str());
        errors.put_child("metadata.source", source_metadata.toPTree());
        errors.put_child("metadata.candidate", candidate_metadata.toPTree());
    }

    if (candidateCtx.dims().size() != sourceCtx.dims().size())
    {
        std::ostringstream oss;

        oss << "Source and candidate files do not have the same "
            "number of dimensions";
        errors.put<std::string>("schema.error", oss.str());
        // FIXME: Need to "ptree" the PointContext dimension list in some way
        // errors.put_child("schema.source", sourceCtx.schema()->toPTree());
        // errors.put_child("schema.candidate",
        //     candidateCtx.schema()->toPTree());
    }

    if (errors.size())
    {
        write_json(std::cout, errors);
        return 1;
    }
    else
    {
        // If we made it this far with no errors, now we'll
        // check the points.
        checkPoints(*sourceBuf, *candidateBuf, errors);
        if (errors.size())
        {
            write_json(std::cout, errors);
            return 1;
        }
    }
    return 0;
}

} // namespace kernel
} // namespace pdal
<|endoftext|>


<commit_before>#include <ignition/math/Pose3.hh>
#include "gazebo/physics/physics.hh"
#include "gazebo/common/common.hh"
#include "gazebo/gazebo.hh"

#include <ros/ros.h>
#include <boost/bind/bind.hpp>
#include <tf2_msgs/TFMessage.h>

#include <tf/transform_listener.h>

#include <boost/thread.hpp>

namespace gazebo
{

struct tokens: std::ctype<char>
{
    tokens(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        typedef std::ctype<char> cctype;
        static const cctype::mask *const_rc= cctype::classic_table();

        static cctype::mask rc[cctype::table_size];
        std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));

        rc[','] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
    }
};

typedef struct
{
    physics::WorldPtr parentWorld;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
}tPhantomContext;

tPhantomContext PhantomContext;

class LabPhantoms;
void onTFData2(const tf2_msgs::TFMessage::ConstPtr& msg);
void onTFData(const tf2_msgs::TFMessage::ConstPtr& msg);//, LabPhantoms *plugin);

math::Pose Msg2Pose(geometry_msgs::Transform const& msg)
{
    math::Pose pose;
    math::Vector3 v;
    math::Quaternion q;

    v.x = msg.translation.x;
    v.y = msg.translation.y;
    v.z = msg.translation.z;
    q.w = msg.rotation.w;
    q.x = msg.rotation.x;
    q.y = msg.rotation.y;
    q.z = msg.rotation.z;

    pose.Set(v, q);
    return pose;
}

math::Pose StampedTransform2Pose(tf::StampedTransform const& transform)
{
    tf::Vector3 vt = transform.getOrigin();
    tf::Quaternion qt = transform.getRotation();
    math::Vector3 v;
    math::Quaternion q;

    v.x = vt.x();
    v.y = vt.y();
    v.z = vt.z();
    /*SUPER DIRTY HAXX*/
    if(0.755 > v.z)
        v.z = 0.755;
    q.w = qt.w();
    q.x = qt.x();
    q.y = qt.y();
    q.z = qt.z();

    math::Pose pose;
    pose.Set(v, q);
    return pose;
}

class LabPhantoms : public WorldPlugin
{
  protected:
  bool havePhantom(std::string const& name)
  {
      bool retq = false;
      int maxK = phantoms.size();
      for(int k = 0; (!retq) && (k < maxK); k++)
          retq = (phantoms[k] == name);
      return retq;
  }

  public:
  LabPhantoms()
  {
      n = 0;
      parentWorld.reset();
  }
  ~LabPhantoms()
  {
      running = false;
      if(n)
          delete n;
  }

  void monitorTFThread(void)
  {
      ros::Rate rate(0.5);
      while(running)
      {
          physics::WorldPtr world = parentWorld;
          std::vector<std::string> phantomsL = phantoms;
          tf::TransformListener listenerL;

          int maxK = phantomsL.size();

          listenerL.waitForTransform("bottle_250ml_0_frame", "/map", ros::Time::now(), ros::Duration(3.0));
          for(int k = 0; k < maxK; k++)
          {
              std::string childFrame = "/";
              childFrame += phantomsL[k] + "_frame";

              tf::StampedTransform transform;
              try
              {
                  ros::Time now = ros::Time::now();
                  listenerL.lookupTransform("/map", childFrame, ros::Time(), transform);

                  if(phantomsL[k] == "pipette_accumax")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "PIPETTE TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "bottle_250ml")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "BOTTLE_250ML TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "mixer_ikamag")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "MIXER_IKAMAG TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "flask_400ml_0")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "FLASK_400ml_0 TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  physics::ModelPtr childModel = world->GetModel(phantomsL[k]);
                  if(childModel.get())
                  {
                      math::Pose world2Child = StampedTransform2Pose(transform);
                      childModel->SetWorldPose(world2Child);
                      childModel->SetGravityMode(true);
                      childModel->SetStatic(true);
                  }
              }
              catch (tf::TransformException ex)
              {
                  ROS_ERROR("%s", ex.what());
              }
          }
          rate.sleep();
      }
  }

  void onTFData(const tf2_msgs::TFMessageConstPtr& msg)
  {
      if(!(parentWorld.get()))
          return;
      physics::WorldPtr world = parentWorld;

      int maxK = msg->transforms.size();

      for(int k = 0; k < maxK; k++)
      {
          geometry_msgs::TransformStamped transform = msg->transforms[k];
          std::string parentFrame = transform.header.frame_id;
          std::string childFrame = transform.child_frame_id;

          /*DIRTY HAXXXXX TO BE REMOVED.*/
          if("in_r_gripper_tool_frame" == parentFrame)
              parentFrame = "r_gripper_tool_frame";
          if("in_l_gripper_tool_frame" == parentFrame)
              parentFrame = "l_gripper_tool_frame";

          if(havePhantom(childFrame))
          {
              physics::ModelPtr childModel = world->GetModel(childFrame);
              physics::ModelPtr parentModel = world->GetModel(parentFrame);

              if((childModel.get()) && (parentModel.get()))
              {
                  math::Pose parent2Child = Msg2Pose(transform.transform);
                  math::Pose world2Parent = parentModel->GetWorldPose();
                  childModel->SetWorldPose(parent2Child*world2Parent);
              }
          }
      }
  }

  void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
  {
    parentWorld = _parent;
    pluginParameters = _sdf;
    char nodeName[] = "labphantoms";
    char* argv[] = {nodeName};
    int argc = 1;
    ros::init(argc, argv, "labphantoms");
    n = new ros::NodeHandle();

    //ros::Subscriber sub = n->subscribe("/tf", 1, &LabPhantoms::onTFData, this);

    if(pluginParameters->HasElement("trackedModels"))
    {
        std::string trackedModels = pluginParameters->Get<std::string>("trackedModels");
        std::string dbgStr = "Tracked Models as given by launch file: ";
        dbgStr = dbgStr + trackedModels;
        std::cerr << dbgStr << "\n";

        std::stringstream ss(trackedModels);
        ss.imbue(std::locale(std::locale(), new tokens()));
        std::istream_iterator<std::string> begin(ss);
        std::istream_iterator<std::string> end;
        std::vector<std::string> vstrings(begin, end);
        std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cerr, "\n"));
        phantoms = vstrings;
    }

    running = true;
    boost::thread(&LabPhantoms::monitorTFThread, this);
  }

  protected:
    bool running;
    ros::NodeHandle *n;
    physics::WorldPtr parentWorld;
    sdf::ElementPtr pluginParameters;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
};

// Register this plugin with the simulator
GZ_REGISTER_WORLD_PLUGIN(LabPhantoms)
}
<commit_msg>Undid a dirty hack.<commit_after>#include <ignition/math/Pose3.hh>
#include "gazebo/physics/physics.hh"
#include "gazebo/common/common.hh"
#include "gazebo/gazebo.hh"

#include <ros/ros.h>
#include <boost/bind/bind.hpp>
#include <tf2_msgs/TFMessage.h>

#include <tf/transform_listener.h>

#include <boost/thread.hpp>

namespace gazebo
{

struct tokens: std::ctype<char>
{
    tokens(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        typedef std::ctype<char> cctype;
        static const cctype::mask *const_rc= cctype::classic_table();

        static cctype::mask rc[cctype::table_size];
        std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));

        rc[','] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
    }
};

typedef struct
{
    physics::WorldPtr parentWorld;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
}tPhantomContext;

tPhantomContext PhantomContext;

class LabPhantoms;
void onTFData2(const tf2_msgs::TFMessage::ConstPtr& msg);
void onTFData(const tf2_msgs::TFMessage::ConstPtr& msg);//, LabPhantoms *plugin);

math::Pose Msg2Pose(geometry_msgs::Transform const& msg)
{
    math::Pose pose;
    math::Vector3 v;
    math::Quaternion q;

    v.x = msg.translation.x;
    v.y = msg.translation.y;
    v.z = msg.translation.z;
    q.w = msg.rotation.w;
    q.x = msg.rotation.x;
    q.y = msg.rotation.y;
    q.z = msg.rotation.z;

    pose.Set(v, q);
    return pose;
}

math::Pose StampedTransform2Pose(tf::StampedTransform const& transform)
{
    tf::Vector3 vt = transform.getOrigin();
    tf::Quaternion qt = transform.getRotation();
    math::Vector3 v;
    math::Quaternion q;

    v.x = vt.x();
    v.y = vt.y();
    v.z = vt.z();
    /*SUPER DIRTY HAXX*/
    if(0.755 > v.z)
        v.z = 0.755;
    q.w = qt.w();
    q.x = qt.x();
    q.y = qt.y();
    q.z = qt.z();

    math::Pose pose;
    pose.Set(v, q);
    return pose;
}

class LabPhantoms : public WorldPlugin
{
  protected:
  bool havePhantom(std::string const& name)
  {
      bool retq = false;
      int maxK = phantoms.size();
      for(int k = 0; (!retq) && (k < maxK); k++)
          retq = (phantoms[k] == name);
      return retq;
  }

  public:
  LabPhantoms()
  {
      n = 0;
      parentWorld.reset();
  }
  ~LabPhantoms()
  {
      running = false;
      if(n)
          delete n;
  }

  void monitorTFThread(void)
  {
      ros::Rate rate(0.5);
      while(running)
      {
          physics::WorldPtr world = parentWorld;
          std::vector<std::string> phantomsL = phantoms;
          tf::TransformListener listenerL;

          int maxK = phantomsL.size();

          listenerL.waitForTransform("bottle_250ml_0_frame", "/map", ros::Time::now(), ros::Duration(3.0));
          for(int k = 0; k < maxK; k++)
          {
              std::string childFrame = "/";
              childFrame += phantomsL[k] + "_frame";

              tf::StampedTransform transform;
              try
              {
                  ros::Time now = ros::Time::now();
                  listenerL.lookupTransform("/map", childFrame, ros::Time(), transform);

                  if(phantomsL[k] == "pipette_accumax")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "PIPETTE TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "bottle_250ml")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "BOTTLE_250ML TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "mixer_ikamag")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "MIXER_IKAMAG TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  if(phantomsL[k] == "flask_400ml_0")
                  {
                      math::Pose p = StampedTransform2Pose(transform);
                      std::cerr << "FLASK_400ml_0 TRANSFORM to /map V(" << p.pos.x << " " << p.pos.y << " " << p.pos.z << ") Q(" << p.rot.w << " " << p.rot.x << " " << p.rot.y << " " << p.rot.z << ")" << std::endl;
                  }

                  physics::ModelPtr childModel = world->GetModel(phantomsL[k]);
                  if(childModel.get())
                  {
                      math::Pose world2Child = StampedTransform2Pose(transform);
                      childModel->SetWorldPose(world2Child);
                      childModel->SetStatic(true);
                      childModel->SetGravityMode(false);
                  }
              }
              catch (tf::TransformException ex)
              {
                  ROS_ERROR("%s", ex.what());
              }
          }
          rate.sleep();
      }
  }

  void onTFData(const tf2_msgs::TFMessageConstPtr& msg)
  {
      if(!(parentWorld.get()))
          return;
      physics::WorldPtr world = parentWorld;

      int maxK = msg->transforms.size();

      for(int k = 0; k < maxK; k++)
      {
          geometry_msgs::TransformStamped transform = msg->transforms[k];
          std::string parentFrame = transform.header.frame_id;
          std::string childFrame = transform.child_frame_id;

          /*DIRTY HAXXXXX TO BE REMOVED.*/
          if("in_r_gripper_tool_frame" == parentFrame)
              parentFrame = "r_gripper_tool_frame";
          if("in_l_gripper_tool_frame" == parentFrame)
              parentFrame = "l_gripper_tool_frame";

          if(havePhantom(childFrame))
          {
              physics::ModelPtr childModel = world->GetModel(childFrame);
              physics::ModelPtr parentModel = world->GetModel(parentFrame);

              if((childModel.get()) && (parentModel.get()))
              {
                  math::Pose parent2Child = Msg2Pose(transform.transform);
                  math::Pose world2Parent = parentModel->GetWorldPose();
                  childModel->SetWorldPose(parent2Child*world2Parent);
              }
          }
      }
  }

  void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
  {
    parentWorld = _parent;
    pluginParameters = _sdf;
    char nodeName[] = "labphantoms";
    char* argv[] = {nodeName};
    int argc = 1;
    ros::init(argc, argv, "labphantoms");
    n = new ros::NodeHandle();

    //ros::Subscriber sub = n->subscribe("/tf", 1, &LabPhantoms::onTFData, this);

    if(pluginParameters->HasElement("trackedModels"))
    {
        std::string trackedModels = pluginParameters->Get<std::string>("trackedModels");
        std::string dbgStr = "Tracked Models as given by launch file: ";
        dbgStr = dbgStr + trackedModels;
        std::cerr << dbgStr << "\n";

        std::stringstream ss(trackedModels);
        ss.imbue(std::locale(std::locale(), new tokens()));
        std::istream_iterator<std::string> begin(ss);
        std::istream_iterator<std::string> end;
        std::vector<std::string> vstrings(begin, end);
        std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cerr, "\n"));
        phantoms = vstrings;
    }

    running = true;
    boost::thread(&LabPhantoms::monitorTFThread, this);
  }

  protected:
    bool running;
    ros::NodeHandle *n;
    physics::WorldPtr parentWorld;
    sdf::ElementPtr pluginParameters;
    std::vector<std::string> phantoms;
    tf::TransformListener listener;
};

// Register this plugin with the simulator
GZ_REGISTER_WORLD_PLUGIN(LabPhantoms)
}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2011
  \file      main.cpp
  \authors     (rdo@rk9.bmstu.ru)
  \authors     (lord.tiran@gmail.com)
  \date      13.07.2009
  \brief       RDOValue
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#include <iostream>
#include <boost/regex.hpp>
#define BOOST_TEST_MODULE RDOValue_Test
#include <boost/test/included/unit_test.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/rdo_res_type.h"
// --------------------------------------------------------------------------------

BOOST_AUTO_TEST_SUITE(RDOValue_Test)

BOOST_AUTO_TEST_CASE(RDOValue_String)
{
	const tstring str1 = _T("qqq");
	rdoRuntime::RDOValue value1(str1);
	BOOST_CHECK(value1.getString  () == str1);
	BOOST_CHECK(value1.getAsString() == str1);

	rdoRuntime::RDOValue value2 = value1;
	BOOST_CHECK(value2.getString  () == str1);
	BOOST_CHECK(value2.getAsString() == str1);
	BOOST_CHECK(value2 == value1);

	const tstring str2 = _T("aaa");
	value2 += str2;
	BOOST_CHECK(value2.getString  () == str1 + str2);
	BOOST_CHECK(value2.getAsString() == str1 + str2);
}

BOOST_AUTO_TEST_CASE(RDOValue_Resource)
{
	using namespace rdoRuntime;

	LPRDORuntime pRuntime = rdo::Factory<RDORuntime>::create();
	BOOST_CHECK(pRuntime);

	LPRDOResourceType pResourceType = rdo::Factory<RDOResourceType>::create(0);
	BOOST_CHECK(pResourceType);
	LPIResourceType pResourceFactory = pResourceType.interface_cast<IResourceType>();
	BOOST_CHECK(pResourceFactory);

	std::vector<RDOValue> paramList;
	paramList.push_back(RDOValue(1      ));
	paramList.push_back(RDOValue(2.2    ));
	paramList.push_back(RDOValue(_T("3")));

	LPRDOResource pResource = pResourceFactory->createRes(pRuntime, pRuntime->getResourceId(), paramList, true, true);
	BOOST_CHECK(pResource);

	RDOValue value1(pResourceType, pResource);

	LPRDOResourceType pType = value1.type().object_dynamic_cast<RDOResourceType>();
	BOOST_CHECK(pType);

	LPRDOResource pResource1 = value1.getPointer<RDOResource>();

	pRuntime   = NULL;
	value1     = RDOValue();
	pResource1 = NULL;

	BOOST_CHECK(pResource.owner());

	pResource = NULL;
}

BOOST_AUTO_TEST_SUITE_END() //RDOValue_Resource
<commit_msg> - добавлены тесты для типов int, uint, double, char, bool<commit_after>/*!
  \copyright (c) RDO-Team, 2011
  \file      main.cpp
  \authors     (rdo@rk9.bmstu.ru)
  \authors     (lord.tiran@gmail.com)
  \date      13.07.2009
  \brief       RDOValue
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#include <iostream>
#include <boost/regex.hpp>
#define BOOST_TEST_MODULE RDOValue_Test
#include <boost/test/included/unit_test.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/rdo_res_type.h"
// --------------------------------------------------------------------------------

BOOST_AUTO_TEST_SUITE(RDOValue_Test)

BOOST_AUTO_TEST_CASE(RDOValue_String)
{
	const tstring str1 = _T("qqq");
	rdoRuntime::RDOValue value1(str1);
	BOOST_CHECK(value1.getString  () == str1);
	BOOST_CHECK(value1.getAsString() == str1);

	rdoRuntime::RDOValue value2 = value1;
	BOOST_CHECK(value2.getString  () == str1);
	BOOST_CHECK(value2.getAsString() == str1);
	BOOST_CHECK(value2 == value1);

	const tstring str2 = _T("aaa");
	value2 += str2;
	BOOST_CHECK(value2.getString  () == str1 + str2);
	BOOST_CHECK(value2.getAsString() == str1 + str2);
}

BOOST_AUTO_TEST_CASE(RDOValue_Rsint)
{
	const rsint int1 = 30;
	rdoRuntime::RDOValue value1(int1);
	BOOST_CHECK(value1.getInt() == int1);

	rdoRuntime::RDOValue value2 = value1;
	BOOST_CHECK(value2 == int1);
	BOOST_CHECK(value2 == value1);

	const rsint int2 = 20;
	value1 += int2;
	BOOST_CHECK(value1 == int1 + int2);

	const rsint int3 = 10;
	value1 -= int3;
	BOOST_CHECK(value1 == int1 + int2 - int3);

	const rsint int4 = 2;
	value2 = value1;
	value2 *= int4;
	BOOST_CHECK(value2 == value1 * int4);

	const rsint int5 = 5;
	value2 = value1;
	value2 /= int5;
	BOOST_CHECK(value2 == value1 / int5);

	value2 = value1;
	value2 --;
	BOOST_CHECK(value2 == value1 - 1);
	value2 ++;
	BOOST_CHECK(value2 == value1);

	value1 = int1;
	value2 = int2;
	BOOST_CHECK(value1 != value2);
	BOOST_CHECK(value1 > value2);
	BOOST_CHECK(value2 < value1);
	BOOST_CHECK(value1 >= value2);
	BOOST_CHECK(value2 <= value1);
	value2 = int1;
	BOOST_CHECK(value1 >= value2);
	BOOST_CHECK(value2 <= value1);

}

BOOST_AUTO_TEST_CASE(RDOValue_Ruint)
{
	const ruint int1 = 30;
	rdoRuntime::RDOValue value1(int1);
	BOOST_CHECK(value1 == int1);

	rdoRuntime::RDOValue value2 = value1;
	BOOST_CHECK(value2 == int1);
	BOOST_CHECK(value2 == value1);

	const ruint int2 = 20;
	value1 += int2;
	BOOST_CHECK(value1 == int1 + int2);

	const ruint int3 = 10;
	value1 -= int3;
	BOOST_CHECK(value1 == int1 + int2 - int3);

	const ruint int4 = 2;
	value2 = value1;
	value2 *= int4;
	BOOST_CHECK(value2 == value1 * int4);

	const ruint int5 = 5;
	value2 = value1;
	value2 /= int5;
	BOOST_CHECK(value2 == value1 / int5);

	value2 = value1;
	value2 --;
	BOOST_CHECK(value2 == value1 - 1);
	value2 ++;
	BOOST_CHECK(value2 == value1);

	value1 = int1;
	value2 = int2;
	BOOST_CHECK(value1 != value2);
	BOOST_CHECK(value1 > value2);
	BOOST_CHECK(value2 < value1);
	BOOST_CHECK(value1 >= value2);
	BOOST_CHECK(value2 <= value1);
	value2 = int1;
	BOOST_CHECK(value1 >= value2);
	BOOST_CHECK(value2 <= value1);
}

BOOST_AUTO_TEST_CASE(RDOValue_Double)
{
	const double doub1 = 30.2;
	rdoRuntime::RDOValue value1(doub1);
	BOOST_CHECK(value1 == doub1);

	rdoRuntime::RDOValue value2 = value1;
	BOOST_CHECK(value2 == doub1);
	BOOST_CHECK(value2 == value1);

	const double doub2 = 20.5;
	value1 += doub2;
	BOOST_CHECK(value1 == doub1 + doub2);

	const double doub3 = 10.3;
	value1 -= doub3;
	BOOST_CHECK(value1 == doub1 + doub2 - doub3);

	const double doub4 = 2.5;
	value2 = value1;
	value2 *= doub4;
	BOOST_CHECK(value2 == value1 * doub4);

	const double doub5 = 5;
	value2 = value1;
	value2 /= doub5;
	BOOST_CHECK(value2 == value1 / doub5);

	value2 = value1;
	value2 --;
	BOOST_CHECK(value2 == value1 - 1);
	value2 ++;
	BOOST_CHECK(value2 == value1);

	value1 = doub1;
	value2 = doub2;
	BOOST_CHECK(value1 != value2);
	BOOST_CHECK(value1 > value2);
	BOOST_CHECK(value2 < value1);
	BOOST_CHECK(value1 >= value2);
	BOOST_CHECK(value2 <= value1);
	value2 = doub1;
	BOOST_CHECK(value1 >= value2);
	BOOST_CHECK(value2 <= value1);
}

BOOST_AUTO_TEST_CASE(RDOValue_Bool)
{
	rbool bool1 = true;
	rbool bool2 = false;
	rbool bool3 = true;
	rbool bool4 = false;

	rdoRuntime::RDOValue value1(bool1);
	rdoRuntime::RDOValue value2(bool2);
	rdoRuntime::RDOValue value3(bool3);
	rdoRuntime::RDOValue value4(bool4);

	BOOST_CHECK(value1.getBool());
	BOOST_CHECK(!value2);
	BOOST_CHECK(value2 == value4);
	BOOST_CHECK(value1 != value2);
	BOOST_CHECK(!(value1 == value2));
	BOOST_CHECK(value1 && value3);
	BOOST_CHECK(!(value2 && value3));
	BOOST_CHECK(value1 || value2);
	BOOST_CHECK(!(value2 || value4));
}

BOOST_AUTO_TEST_CASE(RDOValue_Char)
{
	tchar ch1 = 'a';
	tchar ch2 = 'b';
	rdoRuntime::RDOValue value1 = ch1;
	rdoRuntime::RDOValue value2 = ch2;
	BOOST_CHECK(value1 == ch1);
	BOOST_CHECK(value1 < value2);
	BOOST_CHECK(value2 > value1);
	BOOST_CHECK(value1 != value2);
	value1 = value2;
	BOOST_CHECK(value1 == value2);
}

BOOST_AUTO_TEST_CASE(RDOValue_Enum)
{
	using namespace rdoRuntime;

	LPRDOEnumType pEnum = rdo::Factory<RDOEnumType>::create();
	BOOST_CHECK(pEnum);
	pEnum->empty();
}
/*
BOOST_AUTO_TEST_CASE(RDOValue_Identificator)
{

}
*/

BOOST_AUTO_TEST_CASE(RDOValue_Resource)
{
	using namespace rdoRuntime;

	LPRDORuntime pRuntime = rdo::Factory<RDORuntime>::create();
	BOOST_CHECK(pRuntime);

	LPRDOResourceType pResourceType = rdo::Factory<RDOResourceType>::create(0);
	BOOST_CHECK(pResourceType);
	LPIResourceType pResourceFactory = pResourceType.interface_cast<IResourceType>();
	BOOST_CHECK(pResourceFactory);

	std::vector<RDOValue> paramList;
	paramList.push_back(RDOValue(1      ));
	paramList.push_back(RDOValue(2.2    ));
	paramList.push_back(RDOValue(_T("3")));

	LPRDOResource pResource = pResourceFactory->createRes(pRuntime, pRuntime->getResourceId(), paramList, true, true);
	BOOST_CHECK(pResource);

	RDOValue value1(pResourceType, pResource);

	LPRDOResourceType pType = value1.type().object_dynamic_cast<RDOResourceType>();
	BOOST_CHECK(pType);

	LPRDOResource pResource1 = value1.getPointer<RDOResource>();

	pRuntime   = NULL;
	value1     = RDOValue();
	pResource1 = NULL;

	BOOST_CHECK(pResource.owner());

	pResource = NULL;
}

BOOST_AUTO_TEST_SUITE_END() //RDOValue_Resource
<|endoftext|>


<commit_before>/*
 * copyright: (c) RDO-Team, 2011
 * filename : statements.cpp
 * author   :  ,
 * date     : 16.04.11
 * bref     :
 * indent   : 4T
 */

// ====================================================================== PCH
#include "rdo_lib/rdo_runtime/pch.h"
// ====================================================================== INCLUDES
// ====================================================================== SYNOPSIS
#include "rdo_lib/rdo_runtime/calc/statements.h"
// ===============================================================================

OPEN_RDO_RUNTIME_NAMESPACE

// ----------------------------------------------------------------------------
// ---------- RDOCalcNoChange
// ----------------------------------------------------------------------------
RDOCalcNoChange::RDOCalcNoChange()
{}

REF(RDOValue) RDOCalcNoChange::doCalc(PTR(RDORuntime) pRuntime)
{
	m_value = RDOValue(0);
	return m_value;
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcIf
// ----------------------------------------------------------------------------
RDOCalcIf::RDOCalcIf(CREF(LPRDOCalc) pCondition, CREF(LPRDOCalc) pStatement)
: m_pCondition(pCondition)
, m_pStatement(pStatement)
{
	ASSERT(m_pCondition);
	ASSERT(m_pStatement);
}

REF(RDOValue) RDOCalcIf::doCalc(PTR(RDORuntime) pRuntime)
{
	m_value = RDOValue(false);
	return (m_pCondition->calcValue(pRuntime).getAsBool()) ? m_pStatement->calcValue(pRuntime) : (m_value);
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcIfElse
// ----------------------------------------------------------------------------
RDOCalcIfElse::RDOCalcIfElse(CREF(LPRDOCalc) pCondition, CREF(LPRDOCalc) pIfStatement, CREF(LPRDOCalc) pElseStatement)
: m_pCondition    (pCondition    )
, m_pIfStatement  (pIfStatement  )
, m_pElseStatement(pElseStatement)
{
	ASSERT(m_pCondition    );
	ASSERT(m_pIfStatement  );
	ASSERT(m_pElseStatement);
}

REF(RDOValue) RDOCalcIfElse::doCalc(PTR(RDORuntime) pRuntime)
{
	return (m_pCondition->calcValue(pRuntime).getAsBool()) ? m_pIfStatement->calcValue(pRuntime) : m_pElseStatement->calcValue(pRuntime);
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcFor
// ----------------------------------------------------------------------------
RDOCalcFor::RDOCalcFor(CREF(LPRDOCalc) pDeclaration, CREF(LPRDOCalc) pCondition, CREF(LPRDOCalc) pExpression, CREF(LPRDOCalc) pStatement)
: m_pDeclaration(pDeclaration)
, m_pCondition  (pCondition  )
, m_pExpression (pExpression )
, m_pStatement  (pStatement  )
{
	ASSERT(m_pDeclaration);
	ASSERT(m_pCondition  );
	ASSERT(m_pExpression );
	ASSERT(m_pStatement  );
}

REF(RDOValue) RDOCalcFor::doCalc(PTR(RDORuntime) pRuntime)
{
	if(pRuntime->getFunBreakFlag() == RDORuntime::FBF_CONTINUE)
	{
		m_value = m_pDeclaration->calcValue(pRuntime);
		while (m_pCondition->calcValue(pRuntime).getAsBool())
		{
			m_value = m_pStatement->calcValue(pRuntime);
			m_value = m_pExpression->calcValue(pRuntime);
			if(pRuntime->getFunBreakFlag() == RDORuntime::FBF_BREAK)
			{
				pRuntime->setFunBreakFlag(RDORuntime::FBF_CONTINUE);
				return m_value;
			}
			if(pRuntime->getFunBreakFlag() == RDORuntime::FBF_RETURN)
			{
				return m_value;
			}
		}
	}
	return m_value;
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcFunReturn
// ----------------------------------------------------------------------------
RDOCalcFunReturn::RDOCalcFunReturn(CREF(LPRDOCalc) pReturn)
: m_pReturn(pReturn)
{}

REF(RDOValue) RDOCalcFunReturn::doCalc(PTR(RDORuntime) pRuntime)
{
	m_value = m_pReturn->calcValue(pRuntime);
	pRuntime->setFunBreakFlag(RDORuntime::FBF_RETURN);
	return m_value;
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcFunBreak
// ----------------------------------------------------------------------------
RDOCalcFunBreak::RDOCalcFunBreak()
{}

REF(RDOValue) RDOCalcFunBreak::doCalc(PTR(RDORuntime) pRuntime)
{
	pRuntime->setFunBreakFlag(RDORuntime::FBF_BREAK);
	return m_value;
}

CLOSE_RDO_RUNTIME_NAMESPACE
<commit_msg> - исправлена ошибка RDOCalcFor::doCalc<commit_after>/*
 * copyright: (c) RDO-Team, 2011
 * filename : statements.cpp
 * author   :  ,
 * date     : 16.04.11
 * bref     :
 * indent   : 4T
 */

// ====================================================================== PCH
#include "rdo_lib/rdo_runtime/pch.h"
// ====================================================================== INCLUDES
// ====================================================================== SYNOPSIS
#include "rdo_lib/rdo_runtime/calc/statements.h"
// ===============================================================================

OPEN_RDO_RUNTIME_NAMESPACE

// ----------------------------------------------------------------------------
// ---------- RDOCalcNoChange
// ----------------------------------------------------------------------------
RDOCalcNoChange::RDOCalcNoChange()
{}

REF(RDOValue) RDOCalcNoChange::doCalc(PTR(RDORuntime) pRuntime)
{
	m_value = RDOValue(0);
	return m_value;
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcIf
// ----------------------------------------------------------------------------
RDOCalcIf::RDOCalcIf(CREF(LPRDOCalc) pCondition, CREF(LPRDOCalc) pStatement)
: m_pCondition(pCondition)
, m_pStatement(pStatement)
{
	ASSERT(m_pCondition);
	ASSERT(m_pStatement);
}

REF(RDOValue) RDOCalcIf::doCalc(PTR(RDORuntime) pRuntime)
{
	m_value = RDOValue(false);
	return (m_pCondition->calcValue(pRuntime).getAsBool()) ? m_pStatement->calcValue(pRuntime) : (m_value);
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcIfElse
// ----------------------------------------------------------------------------
RDOCalcIfElse::RDOCalcIfElse(CREF(LPRDOCalc) pCondition, CREF(LPRDOCalc) pIfStatement, CREF(LPRDOCalc) pElseStatement)
: m_pCondition    (pCondition    )
, m_pIfStatement  (pIfStatement  )
, m_pElseStatement(pElseStatement)
{
	ASSERT(m_pCondition    );
	ASSERT(m_pIfStatement  );
	ASSERT(m_pElseStatement);
}

REF(RDOValue) RDOCalcIfElse::doCalc(PTR(RDORuntime) pRuntime)
{
	return (m_pCondition->calcValue(pRuntime).getAsBool()) ? m_pIfStatement->calcValue(pRuntime) : m_pElseStatement->calcValue(pRuntime);
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcFor
// ----------------------------------------------------------------------------
RDOCalcFor::RDOCalcFor(CREF(LPRDOCalc) pDeclaration, CREF(LPRDOCalc) pCondition, CREF(LPRDOCalc) pExpression, CREF(LPRDOCalc) pStatement)
: m_pDeclaration(pDeclaration)
, m_pCondition  (pCondition  )
, m_pExpression (pExpression )
, m_pStatement  (pStatement  )
{
	ASSERT(m_pDeclaration);
	ASSERT(m_pCondition  );
	ASSERT(m_pExpression );
	ASSERT(m_pStatement  );
}

REF(RDOValue) RDOCalcFor::doCalc(PTR(RDORuntime) pRuntime)
{
	if(pRuntime->getFunBreakFlag() == RDORuntime::FBF_CONTINUE)
	{
		m_value = m_pDeclaration->calcValue(pRuntime);
		while (m_pCondition->calcValue(pRuntime).getAsBool())
		{
			m_value = m_pStatement->calcValue(pRuntime);
			m_pExpression->calcValue(pRuntime);
			if(pRuntime->getFunBreakFlag() == RDORuntime::FBF_BREAK)
			{
				pRuntime->setFunBreakFlag(RDORuntime::FBF_CONTINUE);
				return m_value;
			}
			if(pRuntime->getFunBreakFlag() == RDORuntime::FBF_RETURN)
			{
				return m_value;
			}
		}
	}
	return m_value;
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcFunReturn
// ----------------------------------------------------------------------------
RDOCalcFunReturn::RDOCalcFunReturn(CREF(LPRDOCalc) pReturn)
: m_pReturn(pReturn)
{}

REF(RDOValue) RDOCalcFunReturn::doCalc(PTR(RDORuntime) pRuntime)
{
	m_value = m_pReturn->calcValue(pRuntime);
	pRuntime->setFunBreakFlag(RDORuntime::FBF_RETURN);
	return m_value;
}

// ----------------------------------------------------------------------------
// ---------- RDOCalcFunBreak
// ----------------------------------------------------------------------------
RDOCalcFunBreak::RDOCalcFunBreak()
{}

REF(RDOValue) RDOCalcFunBreak::doCalc(PTR(RDORuntime) pRuntime)
{
	pRuntime->setFunBreakFlag(RDORuntime::FBF_BREAK);
	return m_value;
}

CLOSE_RDO_RUNTIME_NAMESPACE
<|endoftext|>


<commit_before>
#include <cassert>
#ifdef _WIN32
#include <windows.h>
#include <malloc.h>
#endif

#include "Process.h"
#ifdef _WIN32
#include "Array.h"
#include "Map.h"
#include "File.h"
#endif

#ifdef _WIN32
static Array<HANDLE> runningProcessHandles;
#endif

Process::Process()
{
#ifdef _WIN32
  assert(sizeof(hProcess) >= sizeof(HANDLE));
  hProcess = INVALID_HANDLE_VALUE;
#endif
}

Process::~Process()
{
#ifdef _WIN32
  if(hProcess != INVALID_HANDLE_VALUE)
  {
    CloseHandle((HANDLE)hProcess);

    int index = runningProcessHandles.find(hProcess);
    assert(index >= 0);
    runningProcessHandles.remove(index);
  }
#endif
}

unsigned int Process::start(const List<String>& command)
{
#ifdef _WIN32

  struct Executable
  {
    static bool Executable::fileComplete(const String& searchName, bool testExtensions, String& result)
    {
      if(File::exists(searchName))
      {
        result = searchName;
        return true;
      }
      if(testExtensions)
      {
        String testPath = searchName;
        testPath.append(".exe");
        if(File::exists(testPath))
        {
          result = testPath;
          return true;
        }
        testPath.setLength(searchName.getLength());
        testPath.append(".com");
        if(File::exists(testPath))
        {
          result = testPath;
          return true;
        }
      }
      return false;
    }

    static const List<String>& getPathEnv()
    {
      static List<String> searchPaths;
      static bool loaded = false;
      if(!loaded)
      {
        char* pathVar = (char*)alloca(32767);
        GetEnvironmentVariable("PATH", pathVar, 32767);
        for(const char* str = pathVar; *str;)
        {
          const char* end = strchr(str, ';');
          if(end)
          {
            if(end > str)
              searchPaths.append(String(str, end - str));
            ++end;
            str = end;
          }
          else
          {
            searchPaths.append(String(str, -1));
            break;
          }
        }
        loaded = true;
      }
      return searchPaths;
    }

    static bool resolveSymlink(const String& fileName, String& result)
    {
      String cygwinRoot = File::getDirname(File::getDirname(fileName));
      result = fileName;
      bool success = false;
      for(;;)
      {
        File file;
        if(!file.open(result))
          return success;
        const int len = 12 + MAX_PATH * 2 + 2;
        char buffer[len];
        int i = file.read(buffer, len);
        if(i < 12 || strncmp(buffer, "!<symlink>", 12) != 0)
          return success;
        i &= ~1;
        wchar_t* wdest = (wchar_t*)(buffer + 12);
        wdest[(i - 12) >> 1] = 0;
        String dest;
        dest.format(i - 12, "%S", wdest);
        if(strncmp(dest.getData(), "/usr/bin/", 9) == 0)
        {
          result = cygwinRoot;
          result.append(dest.substr(4));
        }
        else if(dest.getData()[0] == '/')
        {
          result = cygwinRoot;
          result.append(dest);
        }
        else
        {
          result = File::getDirname(result);
          result.append('/');
          result.append(dest);
        }
        success = true;
      }
      return false;
    }

    static String find(const String& program)
    {
      String result = program;
      bool testExtensions = File::getExtension(program).isEmpty();
      // check whether the given path is absolute
      if(program.getData()[0] == '/' || (program.getLength() > 2 && program.getData()[1] == ':'))
      { // absolute
        fileComplete(program, testExtensions, result);
      }
      else
      { // try each search path
        const List<String>& searchPaths = Executable::getPathEnv();
        for(const List<String>::Node* i = searchPaths.getFirst(); i; i = i->getNext())
        {
          String testPath = i->data;
          testPath.append('\\');
          testPath.append(program);
          if(fileComplete(testPath, testExtensions, result))
            break;
        }
      }
      return result;
    }
  };

  String program, programPath;
  static Map<String, String> cachedProgramPaths;
  bool cachedProgramPath = false;
  if(command.isEmpty())
    cachedProgramPath = true;
  else
  {
    program = command.getFirst()->data;
    const Map<String, String>::Node* i = cachedProgramPaths.find(program);
    if(i)
    {
      programPath = i->data;
      cachedProgramPath = true;
    }
    else
      programPath = Executable::find(program);
  }

  const List<String>::Node* i = command.getFirst();
  String commandLine;
  if(i)
  {
    commandLine.append(i->data);
    for(i = i->getNext(); i; i = i->getNext())
    {
      commandLine.append(' ');
      commandLine.append(i->data);
    }
  }
  commandLine.setCapacity(commandLine.getLength()); // enforce detach

  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  ZeroMemory(&pi, sizeof(pi));

  if(!CreateProcess(programPath.getData(), (char*)commandLine.getData(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  {
    if(!programPath.isEmpty())
    {
      String resolvedSymlink;
      if(Executable::resolveSymlink(programPath, resolvedSymlink))
      {
        programPath = resolvedSymlink;
        if(CreateProcess(programPath.getData(), (char*)commandLine.getData(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
          goto success;
      }
    }

    if(!cachedProgramPath)
      cachedProgramPaths.append(program, programPath);

    error = GetLastError();
    return 0;
  }
success:

  if(!cachedProgramPath)
    cachedProgramPaths.append(program, programPath);

  CloseHandle(pi.hThread);

  assert(pi.hProcess);
  hProcess = pi.hProcess;
  runningProcessHandles.append(pi.hProcess);

  return pi.dwProcessId;
#endif
}

unsigned int Process::wait()
{
#ifdef _WIN32
  if(hProcess == INVALID_HANDLE_VALUE)
    return 0;
  DWORD exitCode = 0;
  GetExitCodeProcess(hProcess, &exitCode);

  CloseHandle((HANDLE)hProcess);

  int index = runningProcessHandles.find(hProcess);
  assert(index >= 0);
  runningProcessHandles.remove(index);

  hProcess = INVALID_HANDLE_VALUE;

  return exitCode;
#endif
}

unsigned int Process::waitOne()
{
#ifdef _WIN32
  if(runningProcessHandles.isEmpty())
    return 0;
  DWORD index = WaitForMultipleObjects(runningProcessHandles.getSize(), runningProcessHandles.getFirst(), FALSE, INFINITE);
  if(index == WAIT_FAILED)
    return 0;
  index -= WAIT_OBJECT_0;
  assert(index >= 0 && index < runningProcessHandles.getSize());

  HANDLE handle = runningProcessHandles.getFirst()[index];

  return GetProcessId(handle);
#endif
}

unsigned  int Process::getProcessorCount()
{
#ifdef _WIN32
  SYSTEM_INFO si;
  GetSystemInfo(&si);
  return si.dwNumberOfProcessors;
#elif defined(__linux__)
  return sysconf(_SC_NPROCESSORS_CONF);
#else
  return 1;
#endif
}
<commit_msg>Make Process::getProcessorCount compatible with cygwin<commit_after>
#include <cassert>
#ifdef _WIN32
#include <windows.h>
#include <malloc.h>
#else
#include <unistd.h>
#endif

#include "Process.h"
#ifdef _WIN32
#include "Array.h"
#include "Map.h"
#include "File.h"
#endif

#ifdef _WIN32
static Array<HANDLE> runningProcessHandles;
#endif

Process::Process()
{
#ifdef _WIN32
  assert(sizeof(hProcess) >= sizeof(HANDLE));
  hProcess = INVALID_HANDLE_VALUE;
#endif
}

Process::~Process()
{
#ifdef _WIN32
  if(hProcess != INVALID_HANDLE_VALUE)
  {
    CloseHandle((HANDLE)hProcess);

    int index = runningProcessHandles.find(hProcess);
    assert(index >= 0);
    runningProcessHandles.remove(index);
  }
#endif
}

unsigned int Process::start(const List<String>& command)
{
#ifdef _WIN32

  struct Executable
  {
    static bool Executable::fileComplete(const String& searchName, bool testExtensions, String& result)
    {
      if(File::exists(searchName))
      {
        result = searchName;
        return true;
      }
      if(testExtensions)
      {
        String testPath = searchName;
        testPath.append(".exe");
        if(File::exists(testPath))
        {
          result = testPath;
          return true;
        }
        testPath.setLength(searchName.getLength());
        testPath.append(".com");
        if(File::exists(testPath))
        {
          result = testPath;
          return true;
        }
      }
      return false;
    }

    static const List<String>& getPathEnv()
    {
      static List<String> searchPaths;
      static bool loaded = false;
      if(!loaded)
      {
        char* pathVar = (char*)alloca(32767);
        GetEnvironmentVariable("PATH", pathVar, 32767);
        for(const char* str = pathVar; *str;)
        {
          const char* end = strchr(str, ';');
          if(end)
          {
            if(end > str)
              searchPaths.append(String(str, end - str));
            ++end;
            str = end;
          }
          else
          {
            searchPaths.append(String(str, -1));
            break;
          }
        }
        loaded = true;
      }
      return searchPaths;
    }

    static bool resolveSymlink(const String& fileName, String& result)
    {
      String cygwinRoot = File::getDirname(File::getDirname(fileName));
      result = fileName;
      bool success = false;
      for(;;)
      {
        File file;
        if(!file.open(result))
          return success;
        const int len = 12 + MAX_PATH * 2 + 2;
        char buffer[len];
        int i = file.read(buffer, len);
        if(i < 12 || strncmp(buffer, "!<symlink>", 12) != 0)
          return success;
        i &= ~1;
        wchar_t* wdest = (wchar_t*)(buffer + 12);
        wdest[(i - 12) >> 1] = 0;
        String dest;
        dest.format(i - 12, "%S", wdest);
        if(strncmp(dest.getData(), "/usr/bin/", 9) == 0)
        {
          result = cygwinRoot;
          result.append(dest.substr(4));
        }
        else if(dest.getData()[0] == '/')
        {
          result = cygwinRoot;
          result.append(dest);
        }
        else
        {
          result = File::getDirname(result);
          result.append('/');
          result.append(dest);
        }
        success = true;
      }
      return false;
    }

    static String find(const String& program)
    {
      String result = program;
      bool testExtensions = File::getExtension(program).isEmpty();
      // check whether the given path is absolute
      if(program.getData()[0] == '/' || (program.getLength() > 2 && program.getData()[1] == ':'))
      { // absolute
        fileComplete(program, testExtensions, result);
      }
      else
      { // try each search path
        const List<String>& searchPaths = Executable::getPathEnv();
        for(const List<String>::Node* i = searchPaths.getFirst(); i; i = i->getNext())
        {
          String testPath = i->data;
          testPath.append('\\');
          testPath.append(program);
          if(fileComplete(testPath, testExtensions, result))
            break;
        }
      }
      return result;
    }
  };

  String program, programPath;
  static Map<String, String> cachedProgramPaths;
  bool cachedProgramPath = false;
  if(command.isEmpty())
    cachedProgramPath = true;
  else
  {
    program = command.getFirst()->data;
    const Map<String, String>::Node* i = cachedProgramPaths.find(program);
    if(i)
    {
      programPath = i->data;
      cachedProgramPath = true;
    }
    else
      programPath = Executable::find(program);
  }

  const List<String>::Node* i = command.getFirst();
  String commandLine;
  if(i)
  {
    commandLine.append(i->data);
    for(i = i->getNext(); i; i = i->getNext())
    {
      commandLine.append(' ');
      commandLine.append(i->data);
    }
  }
  commandLine.setCapacity(commandLine.getLength()); // enforce detach

  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  ZeroMemory(&pi, sizeof(pi));

  if(!CreateProcess(programPath.getData(), (char*)commandLine.getData(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  {
    if(!programPath.isEmpty())
    {
      String resolvedSymlink;
      if(Executable::resolveSymlink(programPath, resolvedSymlink))
      {
        programPath = resolvedSymlink;
        if(CreateProcess(programPath.getData(), (char*)commandLine.getData(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
          goto success;
      }
    }

    if(!cachedProgramPath)
      cachedProgramPaths.append(program, programPath);

    error = GetLastError();
    return 0;
  }
success:

  if(!cachedProgramPath)
    cachedProgramPaths.append(program, programPath);

  CloseHandle(pi.hThread);

  assert(pi.hProcess);
  hProcess = pi.hProcess;
  runningProcessHandles.append(pi.hProcess);

  return pi.dwProcessId;
#endif
}

unsigned int Process::wait()
{
#ifdef _WIN32
  if(hProcess == INVALID_HANDLE_VALUE)
    return 0;
  DWORD exitCode = 0;
  GetExitCodeProcess(hProcess, &exitCode);

  CloseHandle((HANDLE)hProcess);

  int index = runningProcessHandles.find(hProcess);
  assert(index >= 0);
  runningProcessHandles.remove(index);

  hProcess = INVALID_HANDLE_VALUE;

  return exitCode;
#endif
}

unsigned int Process::waitOne()
{
#ifdef _WIN32
  if(runningProcessHandles.isEmpty())
    return 0;
  DWORD index = WaitForMultipleObjects(runningProcessHandles.getSize(), runningProcessHandles.getFirst(), FALSE, INFINITE);
  if(index == WAIT_FAILED)
    return 0;
  index -= WAIT_OBJECT_0;
  assert(index >= 0 && index < runningProcessHandles.getSize());

  HANDLE handle = runningProcessHandles.getFirst()[index];

  return GetProcessId(handle);
#endif
}

unsigned  int Process::getProcessorCount()
{
#if defined(_WIN32)
  SYSTEM_INFO si;
  GetSystemInfo(&si);
  return si.dwNumberOfProcessors;
//#elif defined(__linux)
#else
  return sysconf(_SC_NPROCESSORS_CONF);
//#else
  //return 1;
#endif
}
<|endoftext|>


<commit_before>#include <sstream>

#include "sprite_sheet.h"
#include "game_window.h"

SpriteSheet::SpriteSheet( std::string pPath, int pixelRefX, int pixelRefY, int altoSprite, int anchoSprite, int cantSprites, double fps, double delay, GameWindow & owner) : owner(owner){
	std::stringstream message;
	message << "Creating SpriteSheet " << this
		<< " with path " << pPath
		<< " owned by " << &owner;
	Logger::getInstance()->writeInformation(message.str());
	this->path = pPath;

	texture = nullptr;
	initialized = false;

	this->pixel_ref_x = pixelRefX;
	this->pixel_ref_y = pixelRefY;
	this->alto_sprite = altoSprite;
	this->ancho_sprite = anchoSprite;
	this->total_sprites = cantSprites;
	this->fps = fps;	// segundos
	this->delay = delay;	// segundos
	this->currentFrame = 0;
	this->counter = 0;
	this->tick = 0;
}

SpriteSheet::~SpriteSheet(){
	std::stringstream message;
	message << "Killing SpriteSheet " << this
		<< " with path " << path
		<< " owned by " << &owner;
	Logger::getInstance()->writeInformation(message.str());
	clear();
}

void SpriteSheet::clear(){
	if(texture){
		SDL_DestroyTexture( texture );
		texture = nullptr;
	}
}

SDL_Texture*  SpriteSheet::getLoadedTexture( SDL_Renderer* renderer ){
	if( !initialized )
		initialized = loadTexture( renderer );
	return texture;
}

bool SpriteSheet::loadTexture( SDL_Renderer* renderer ) {
	//	Libera la carga anterior, para poder recargar
	clear();
	//	Carga la imagen desde el path
	SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
	//	Si no se cargo la imagen, cargo default
	if(!loadedSurface) {
		texture = nullptr;
		Logger::getInstance()->writeError( "No se puede cargar la imagen " + path + "! - " + IMG_GetError() );
		loadedSurface = IMG_Load( ENTIDAD_DEFAULT_IMAGEN );
		this->pixel_ref_x = ENTIDAD_DEFAULT_PIXEL_REF_X;
		this->pixel_ref_y = ENTIDAD_DEFAULT_PIXEL_REF_Y;
		this->alto_sprite = ENTIDAD_DEFAULT_ALTO_SPRITE;
		this->ancho_sprite = ENTIDAD_DEFAULT_ANCHO_SPRITE;
		this->total_sprites = ENTIDAD_DEFAULT_CANTIDAD_SPRITES;
		this->fps = ENTIDAD_DEFAULT_FPS;	// segundos
		this->delay = ENTIDAD_DEFAULT_DELAY;	// segundos
		this->currentFrame = 0;
		this->counter = 0;
		this->tick = 0;
	}
	//	La default siempre deberia poder cargarla
	if(!loadedSurface) {
		texture = nullptr;
		Logger::getInstance()->writeError( "No se puede cargar la imagen Default ! " );
	} else {
		//	Textura de la superficie
		texture = SDL_CreateTextureFromSurface( renderer, loadedSurface );
		//	Libera la superficie
		SDL_FreeSurface( loadedSurface );
	}
	return texture;
}

void SpriteSheet::render(Entity & entity, int frame, SDL_Renderer* renderer){
	auto direction = entity.getDirection();

	currentFrame = counter % total_sprites;	//Aca se debe usar el frame actual desde el estado de la entidad

	//	Conversion isometrica
	auto pos = entity.getPosition() - owner.getFocus();
	auto x = pos.x;
	auto y = pos.y;
	int screenX = ((x - y) * TILE_WIDTH_DEFAULT / 2) + (owner.ancho_pantalla) / 2;
	int screenY = ((x + y) * TILE_HEIGHT_DEFAULT / 2) + (owner.alto_pantalla - TILE_HEIGHT_DEFAULT) / 2;

	//	Ubicacion donde dibujar
	SDL_Rect renderQuad = { screenX - pixel_ref_x , screenY - pixel_ref_y, ancho_sprite, alto_sprite };

	//	Parte de la imagen a levantar
	SDL_Rect clip = { direction * ancho_sprite, currentFrame * alto_sprite, ancho_sprite, alto_sprite };

	//	Dibujado
	//	TODO: Verificar si renderQuad realmente se pisa con la pantalla
	SDL_RenderCopy( renderer, getLoadedTexture( renderer ), &clip, &renderQuad );
}

void SpriteSheet::update(){
	// Todas las entidades del mismo tipo tienen el mismo fps y delay.
	auto currentTick = GameTimer::getCurrent();
	auto diffTime = currentTick - this->tick;
	if ( ( (currentFrame != 0) || (diffTime >= (this->delay * 1000)) ) ) {
		if ( (this->fps == 0) || (diffTime >= (1000 / this->fps ) ) ) {
			//	Actualizo el tick del sprite sheet
			this->tick = currentTick;
			counter++;
		}
	}
}
<commit_msg>validacion canidad de sprites mayor a cero<commit_after>#include <sstream>

#include "sprite_sheet.h"
#include "game_window.h"

SpriteSheet::SpriteSheet( std::string pPath, int pixelRefX, int pixelRefY, int altoSprite, int anchoSprite, int cantSprites, double fps, double delay, GameWindow & owner) : owner(owner){
	std::stringstream message;
	message << "Creating SpriteSheet " << this
		<< " with path " << pPath
		<< " owned by " << &owner;
	Logger::getInstance()->writeInformation(message.str());
	this->path = pPath;

	texture = nullptr;
	initialized = false;

	this->pixel_ref_x = pixelRefX;
	this->pixel_ref_y = pixelRefY;
	this->alto_sprite = altoSprite;
	this->ancho_sprite = anchoSprite;
	this->total_sprites = cantSprites;
	this->fps = fps;	// segundos
	this->delay = delay;	// segundos
	this->currentFrame = 0;
	this->counter = 0;
	this->tick = 0;
}

SpriteSheet::~SpriteSheet(){
	std::stringstream message;
	message << "Killing SpriteSheet " << this
		<< " with path " << path
		<< " owned by " << &owner;
	Logger::getInstance()->writeInformation(message.str());
	clear();
}

void SpriteSheet::clear(){
	if(texture){
		SDL_DestroyTexture( texture );
		texture = nullptr;
	}
}

SDL_Texture*  SpriteSheet::getLoadedTexture( SDL_Renderer* renderer ){
	if( !initialized )
		initialized = loadTexture( renderer );
	return texture;
}

bool SpriteSheet::loadTexture( SDL_Renderer* renderer ) {
	//	Libera la carga anterior, para poder recargar
	clear();
	//	Carga la imagen desde el path
	SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
	//	Si no se cargo la imagen, cargo default
	if(!loadedSurface) {
		texture = nullptr;
		Logger::getInstance()->writeError( "No se puede cargar la imagen " + path + "! - " + IMG_GetError() );
		loadedSurface = IMG_Load( ENTIDAD_DEFAULT_IMAGEN );
		this->pixel_ref_x = ENTIDAD_DEFAULT_PIXEL_REF_X;
		this->pixel_ref_y = ENTIDAD_DEFAULT_PIXEL_REF_Y;
		this->alto_sprite = ENTIDAD_DEFAULT_ALTO_SPRITE;
		this->ancho_sprite = ENTIDAD_DEFAULT_ANCHO_SPRITE;
		this->total_sprites = ENTIDAD_DEFAULT_CANTIDAD_SPRITES;
		this->fps = ENTIDAD_DEFAULT_FPS;	// segundos
		this->delay = ENTIDAD_DEFAULT_DELAY;	// segundos
		this->currentFrame = 0;
		this->counter = 0;
		this->tick = 0;
	}
	//	La default siempre deberia poder cargarla
	if(!loadedSurface) {
		texture = nullptr;
		Logger::getInstance()->writeError( "No se puede cargar la imagen Default ! " );
	} else {
		//	Textura de la superficie
		texture = SDL_CreateTextureFromSurface( renderer, loadedSurface );
		//	Libera la superficie
		SDL_FreeSurface( loadedSurface );
	}
	return texture;
}

void SpriteSheet::render(Entity & entity, int frame, SDL_Renderer* renderer){
	auto direction = entity.getDirection();

	if (total_sprites == 0){
		currentFrame = 0;
		Logger::getInstance()->writeWarning(" La cantidad de sprites debe ser mayor a cero " + path);
	}else
		currentFrame = counter % total_sprites;

	//	Conversion isometrica
	auto pos = entity.getPosition() - owner.getFocus();
	auto x = pos.x;
	auto y = pos.y;
	int screenX = ((x - y) * TILE_WIDTH_DEFAULT / 2) + (owner.ancho_pantalla) / 2;
	int screenY = ((x + y) * TILE_HEIGHT_DEFAULT / 2) + (owner.alto_pantalla - TILE_HEIGHT_DEFAULT) / 2;

	//	Ubicacion donde dibujar
	SDL_Rect renderQuad = { screenX - pixel_ref_x , screenY - pixel_ref_y, ancho_sprite, alto_sprite };

	//	Parte de la imagen a levantar
	SDL_Rect clip = { direction * ancho_sprite, currentFrame * alto_sprite, ancho_sprite, alto_sprite };

	//	Dibujado
	//	TODO: Verificar si renderQuad realmente se pisa con la pantalla
	SDL_RenderCopy( renderer, getLoadedTexture( renderer ), &clip, &renderQuad );
}

void SpriteSheet::update(){
	// Todas las entidades del mismo tipo tienen el mismo fps y delay.
	auto currentTick = GameTimer::getCurrent();
	auto diffTime = currentTick - this->tick;
	if ( ( (currentFrame != 0) || (diffTime >= (this->delay * 1000)) ) ) {
		if ( (this->fps == 0) || (diffTime >= (1000 / this->fps ) ) ) {
			//	Actualizo el tick del sprite sheet
			this->tick = currentTick;
			counter++;
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>Formatting doc<commit_after><|endoftext|>