<commit_before>//===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"

namespace {

using namespace llvm;
using namespace llvm::orc;

class JITDylibSearchOrderResolver : public JITSymbolResolver {
public:
  JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}

  void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) {
    auto &ES = MR.getTargetJITDylib().getExecutionSession();
    SymbolNameSet InternedSymbols;

    // Intern the requested symbols: lookup takes interned strings.
    for (auto &S : Symbols)
      InternedSymbols.insert(ES.intern(S));

    // Build an OnResolve callback to unwrap the interned strings and pass them
    // to the OnResolved callback.
    // FIXME: Switch to move capture of OnResolved once we have c++14.
    auto OnResolvedWithUnwrap =
        [OnResolved](Expected<SymbolMap> InternedResult) {
          if (!InternedResult) {
            OnResolved(InternedResult.takeError());
            return;
          }

          LookupResult Result;
          for (auto &KV : *InternedResult)
            Result[*KV.first] = std::move(KV.second);
          OnResolved(Result);
        };

    // We're not waiting for symbols to be ready. Just log any errors.
    auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };

    // Register dependencies for all symbols contained in this set.
    auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
      MR.addDependenciesForAll(Deps);
    };

    MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
      ES.lookup(JDs, InternedSymbols, OnResolvedWithUnwrap, OnReady,
                RegisterDependencies, &MR.getTargetJITDylib());
    });
  }

  Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {
    LookupSet Result;

    for (auto &KV : MR.getSymbols()) {
      if (Symbols.count(*KV.first))
        Result.insert(*KV.first);
    }

    return Result;
  }

private:
  MaterializationResponsibility &MR;
};

} // end anonymous namespace

namespace llvm {
namespace orc {

RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
    ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
    NotifyLoadedFunction NotifyLoaded, NotifyEmittedFunction NotifyEmitted)
    : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
      NotifyLoaded(std::move(NotifyLoaded)),
      NotifyEmitted(std::move(NotifyEmitted)) {}

void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
                                    std::unique_ptr<MemoryBuffer> O) {
  assert(O && "Object must not be null");

  // This method launches an asynchronous link step that will fulfill our
  // materialization responsibility. We need to switch R to be heap
  // allocated before that happens so it can live as long as the asynchronous
  // link needs it to (i.e. it must be able to outlive this method).
  auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R));

  auto &ES = getExecutionSession();

  auto Obj = object::ObjectFile::createObjectFile(*O);

  if (!Obj) {
    getExecutionSession().reportError(Obj.takeError());
    SharedR->failMaterialization();
    return;
  }

  // Collect the internal symbols from the object file: We will need to
  // filter these later.
  auto InternalSymbols = std::make_shared<std::set<StringRef>>();
  {
    for (auto &Sym : (*Obj)->symbols()) {
      if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
        if (auto SymName = Sym.getName())
          InternalSymbols->insert(*SymName);
        else {
          ES.reportError(SymName.takeError());
          R.failMaterialization();
          return;
        }
      }
    }
  }

  auto K = R.getVModuleKey();
  MemMgrs.push_back(GetMemoryManager());
  auto &MemMgr = *MemMgrs.back();

  JITDylibSearchOrderResolver Resolver(*SharedR);

  /* Thoughts on proper cross-dylib weak symbol handling:
   *
   * Change selection of canonical defs to be a manually triggered process, and
   * add a 'canonical' bit to symbol definitions. When canonical def selection
   * is triggered, sweep the JITDylibs to mark defs as canonical, discard
   * duplicate defs.
   */
  jitLinkForORC(
      **Obj, std::move(O), MemMgr, Resolver, ProcessAllSections,
      [this, K, SharedR, &Obj, InternalSymbols](
          std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
          std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
        return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo),
                         ResolvedSymbols, *InternalSymbols);
      },
      [this, K, SharedR](Error Err) {
        onObjEmit(K, *SharedR, std::move(Err));
      });
}

Error RTDyldObjectLinkingLayer::onObjLoad(
    VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj,
    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
    std::map<StringRef, JITEvaluatedSymbol> Resolved,
    std::set<StringRef> &InternalSymbols) {
  SymbolFlagsMap ExtraSymbolsToClaim;
  SymbolMap Symbols;
  for (auto &KV : Resolved) {
    // Scan the symbols and add them to the Symbols map for resolution.

    // We never claim internal symbols.
    if (InternalSymbols.count(KV.first))
      continue;

    auto InternedName = getExecutionSession().intern(KV.first);
    auto Flags = KV.second.getFlags();

    // Override object flags and claim responsibility for symbols if
    // requested.
    if (OverrideObjectFlags || AutoClaimObjectSymbols) {
      auto I = R.getSymbols().find(InternedName);

      if (OverrideObjectFlags && I != R.getSymbols().end())
        Flags = JITSymbolFlags::stripTransientFlags(I->second);
      else if (AutoClaimObjectSymbols && I == R.getSymbols().end())
        ExtraSymbolsToClaim[InternedName] = Flags;
    }

    Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags);
  }

  if (!ExtraSymbolsToClaim.empty())
    if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim))
      return Err;

  R.resolve(Symbols);

  if (NotifyLoaded)
    NotifyLoaded(K, Obj, *LoadedObjInfo);

  return Error::success();
}

void RTDyldObjectLinkingLayer::onObjEmit(VModuleKey K,
                                          MaterializationResponsibility &R,
                                          Error Err) {
  if (Err) {
    getExecutionSession().reportError(std::move(Err));
    R.failMaterialization();
    return;
  }

  R.emit();

  if (NotifyEmitted)
    NotifyEmitted(K);
}

} // End namespace orc.
} // End namespace llvm.
<commit_msg>[ORC] Guard access to the MemMgrs vector in RTDyldObjectLinkingLayer.<commit_after>//===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"

namespace {

using namespace llvm;
using namespace llvm::orc;

class JITDylibSearchOrderResolver : public JITSymbolResolver {
public:
  JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}

  void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) {
    auto &ES = MR.getTargetJITDylib().getExecutionSession();
    SymbolNameSet InternedSymbols;

    // Intern the requested symbols: lookup takes interned strings.
    for (auto &S : Symbols)
      InternedSymbols.insert(ES.intern(S));

    // Build an OnResolve callback to unwrap the interned strings and pass them
    // to the OnResolved callback.
    // FIXME: Switch to move capture of OnResolved once we have c++14.
    auto OnResolvedWithUnwrap =
        [OnResolved](Expected<SymbolMap> InternedResult) {
          if (!InternedResult) {
            OnResolved(InternedResult.takeError());
            return;
          }

          LookupResult Result;
          for (auto &KV : *InternedResult)
            Result[*KV.first] = std::move(KV.second);
          OnResolved(Result);
        };

    // We're not waiting for symbols to be ready. Just log any errors.
    auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };

    // Register dependencies for all symbols contained in this set.
    auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
      MR.addDependenciesForAll(Deps);
    };

    MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
      ES.lookup(JDs, InternedSymbols, OnResolvedWithUnwrap, OnReady,
                RegisterDependencies, &MR.getTargetJITDylib());
    });
  }

  Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {
    LookupSet Result;

    for (auto &KV : MR.getSymbols()) {
      if (Symbols.count(*KV.first))
        Result.insert(*KV.first);
    }

    return Result;
  }

private:
  MaterializationResponsibility &MR;
};

} // end anonymous namespace

namespace llvm {
namespace orc {

RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
    ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
    NotifyLoadedFunction NotifyLoaded, NotifyEmittedFunction NotifyEmitted)
    : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
      NotifyLoaded(std::move(NotifyLoaded)),
      NotifyEmitted(std::move(NotifyEmitted)) {}

void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
                                    std::unique_ptr<MemoryBuffer> O) {
  assert(O && "Object must not be null");

  // This method launches an asynchronous link step that will fulfill our
  // materialization responsibility. We need to switch R to be heap
  // allocated before that happens so it can live as long as the asynchronous
  // link needs it to (i.e. it must be able to outlive this method).
  auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R));

  auto &ES = getExecutionSession();

  auto Obj = object::ObjectFile::createObjectFile(*O);

  if (!Obj) {
    getExecutionSession().reportError(Obj.takeError());
    SharedR->failMaterialization();
    return;
  }

  // Collect the internal symbols from the object file: We will need to
  // filter these later.
  auto InternalSymbols = std::make_shared<std::set<StringRef>>();
  {
    for (auto &Sym : (*Obj)->symbols()) {
      if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
        if (auto SymName = Sym.getName())
          InternalSymbols->insert(*SymName);
        else {
          ES.reportError(SymName.takeError());
          R.failMaterialization();
          return;
        }
      }
    }
  }

  auto K = R.getVModuleKey();
  RuntimeDyld::MemoryManager *MemMgr = nullptr;

  // Create a record a memory manager for this object.
  {
    auto Tmp = GetMemoryManager();
    std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
    MemMgrs.push_back(std::move(Tmp));
    MemMgr = MemMgrs.back().get();
  }

  JITDylibSearchOrderResolver Resolver(*SharedR);

  /* Thoughts on proper cross-dylib weak symbol handling:
   *
   * Change selection of canonical defs to be a manually triggered process, and
   * add a 'canonical' bit to symbol definitions. When canonical def selection
   * is triggered, sweep the JITDylibs to mark defs as canonical, discard
   * duplicate defs.
   */
  jitLinkForORC(
      **Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections,
      [this, K, SharedR, &Obj, InternalSymbols](
          std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
          std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
        return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo),
                         ResolvedSymbols, *InternalSymbols);
      },
      [this, K, SharedR](Error Err) {
        onObjEmit(K, *SharedR, std::move(Err));
      });
}

Error RTDyldObjectLinkingLayer::onObjLoad(
    VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj,
    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
    std::map<StringRef, JITEvaluatedSymbol> Resolved,
    std::set<StringRef> &InternalSymbols) {
  SymbolFlagsMap ExtraSymbolsToClaim;
  SymbolMap Symbols;
  for (auto &KV : Resolved) {
    // Scan the symbols and add them to the Symbols map for resolution.

    // We never claim internal symbols.
    if (InternalSymbols.count(KV.first))
      continue;

    auto InternedName = getExecutionSession().intern(KV.first);
    auto Flags = KV.second.getFlags();

    // Override object flags and claim responsibility for symbols if
    // requested.
    if (OverrideObjectFlags || AutoClaimObjectSymbols) {
      auto I = R.getSymbols().find(InternedName);

      if (OverrideObjectFlags && I != R.getSymbols().end())
        Flags = JITSymbolFlags::stripTransientFlags(I->second);
      else if (AutoClaimObjectSymbols && I == R.getSymbols().end())
        ExtraSymbolsToClaim[InternedName] = Flags;
    }

    Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags);
  }

  if (!ExtraSymbolsToClaim.empty())
    if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim))
      return Err;

  R.resolve(Symbols);

  if (NotifyLoaded)
    NotifyLoaded(K, Obj, *LoadedObjInfo);

  return Error::success();
}

void RTDyldObjectLinkingLayer::onObjEmit(VModuleKey K,
                                          MaterializationResponsibility &R,
                                          Error Err) {
  if (Err) {
    getExecutionSession().reportError(std::move(Err));
    R.failMaterialization();
    return;
  }

  R.emit();

  if (NotifyEmitted)
    NotifyEmitted(K);
}

} // End namespace orc.
} // End namespace llvm.
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkVersorTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
/**
 *
 *  This program illustrates the use of Versors
 *
 *  Versors are Unit Quaternions used to represent
 *  rotations.
 *
 */

#include "itkVersor.h"
#include <iostream>

//-------------------------
//
//   Main code
//
//-------------------------
int main()
{

  typedef   double          ValueType;

  const ValueType epsilon = 1e-12;

  //  Versor type
  typedef    itk::Versor< ValueType >    VersorType;

  //  Vector type
  typedef    VersorType::VectorType      VectorType;

  //  Point type
  typedef    VersorType::PointType      PointType;

  //  Covariant Vector type
  typedef    VersorType::CovariantVectorType      CovariantVectorType;

  //  VnlVector type
  typedef    VersorType::VnlVectorType      VnlVectorType;

  {
    std::cout << "Test default constructor... ";
    VersorType qa;
    if( fabs(qa.GetX()) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetY()) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetZ()) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetW()-1.0) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for setting Axis and Angle...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 1.5;
    xa[2] = 0.5;
    ValueType angle = atan(1.0)/3.0; // 15 degrees in radians

    qa.Set( xa, angle );

    xa.Normalize();

    ValueType cosangle = cos( angle / 2.0 );
    ValueType sinangle = sin( angle / 2.0 );

    VectorType xb;

    xb =  xa * sinangle;

    if( fabs(qa.GetX()-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetY()-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetZ()-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetW()-cosangle) > epsilon )
      {
      std::cout << "Error in W ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetAngle()-angle) > epsilon )
      {
      std::cout << "Error in Angle ! " << std::endl;
      return EXIT_FAILURE;
      }

    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for setting Right part...";
    VersorType qa;
    VectorType xa;

    ValueType angle = atan(1.0)*30.0/45.0;
    ValueType sin2a = sin( angle/2.0 );

    xa[0] = 0.7;
    xa[1] = 0.3;
    xa[2] = 0.1;

    xa.Normalize();

    xa *= sin2a;

    qa.Set( xa, angle );

    ValueType cos2a = cos( angle/2.0 );

    if( fabs(qa.GetW()-cos2a) > epsilon )
      {
      std::cout << "Error in W ! " << std::endl;
      std::cout << "W= " << qa.GetW();
      std::cout << " it should be " << cos2a << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetAngle()-angle) > epsilon )
      {
      std::cout << "Error in Angle ! " << std::endl;
      return EXIT_FAILURE;
      }

    std::cout << " PASSED !" << std::endl;
  }

 {
    std::cout << "Test for Square Root...";
    VersorType qa;
    VectorType xa;

    ValueType angle = atan(1.0)*30.0/45.0;
    ValueType sin2a = sin( angle/2.0 );

    xa[0] = 0.7;
    xa[1] = 0.3;
    xa[2] = 0.1;

    xa.Normalize();

    xa *= sin2a;

    qa.Set( xa, angle );

    VersorType qb;

    qb = qa.SquareRoot();

    if( fabs( qa.GetAngle() - 2.0 * qb.GetAngle() ) > epsilon )
      {
      std::cout << "Error in Square Root ! " << std::endl;
      std::cout << "Angle = " << qb.GetAngle();
      std::cout << " it should be " << qa.GetAngle() / 2.0 << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a vector...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    VectorType xb;
    xb = 3.0, 7.0, 9.0;

    VectorType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a point...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    PointType xb;
    xb = 3.0, 7.0, 9.0;

    PointType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a covariantvector...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    CovariantVectorType xb;
    xb = 3.0, 7.0, 9.0;

    CovariantVectorType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a vnl_vector...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    VnlVectorType xb;
    xb[0] = 3.0;
    xb[1] = 7.0;
    xb[2] = 9.0;

    VnlVectorType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  return EXIT_SUCCESS;

}

<commit_msg>ENH: Tests for GetReciprocal() and operator/()   added.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkVersorTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
/**
 *
 *  This program illustrates the use of Versors
 *
 *  Versors are Unit Quaternions used to represent
 *  rotations.
 *
 */

#include "itkVersor.h"
#include <iostream>

//-------------------------
//
//   Main code
//
//-------------------------
int main()
{

  typedef   double          ValueType;

  const ValueType epsilon = 1e-12;

  //  Versor type
  typedef    itk::Versor< ValueType >    VersorType;

  //  Vector type
  typedef    VersorType::VectorType      VectorType;

  //  Point type
  typedef    VersorType::PointType      PointType;

  //  Covariant Vector type
  typedef    VersorType::CovariantVectorType      CovariantVectorType;

  //  VnlVector type
  typedef    VersorType::VnlVectorType      VnlVectorType;

  {
    std::cout << "Test default constructor... ";
    VersorType qa;
    if( fabs(qa.GetX()) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetY()) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetZ()) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetW()-1.0) > epsilon )
      {
      std::cout << "Error ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for setting Axis and Angle...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 1.5;
    xa[2] = 0.5;
    ValueType angle = atan(1.0)/3.0; // 15 degrees in radians

    qa.Set( xa, angle );

    xa.Normalize();

    ValueType cosangle = cos( angle / 2.0 );
    ValueType sinangle = sin( angle / 2.0 );

    VectorType xb;

    xb =  xa * sinangle;

    if( fabs(qa.GetX()-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetY()-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetZ()-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetW()-cosangle) > epsilon )
      {
      std::cout << "Error in W ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetAngle()-angle) > epsilon )
      {
      std::cout << "Error in Angle ! " << std::endl;
      return EXIT_FAILURE;
      }

    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for setting Right part...";
    VersorType qa;
    VectorType xa;

    ValueType angle = atan(1.0)*30.0/45.0;
    ValueType sin2a = sin( angle/2.0 );

    xa[0] = 0.7;
    xa[1] = 0.3;
    xa[2] = 0.1;

    xa.Normalize();

    xa *= sin2a;

    qa.Set( xa, angle );

    ValueType cos2a = cos( angle/2.0 );

    if( fabs(qa.GetW()-cos2a) > epsilon )
      {
      std::cout << "Error in W ! " << std::endl;
      std::cout << "W= " << qa.GetW();
      std::cout << " it should be " << cos2a << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(qa.GetAngle()-angle) > epsilon )
      {
      std::cout << "Error in Angle ! " << std::endl;
      return EXIT_FAILURE;
      }

    std::cout << " PASSED !" << std::endl;
  }

 {
    std::cout << "Test for Square Root...";
    VersorType qa;
    VectorType xa;

    ValueType angle = atan(1.0)*30.0/45.0;
    ValueType sin2a = sin( angle/2.0 );

    xa[0] = 0.7;
    xa[1] = 0.3;
    xa[2] = 0.1;

    xa.Normalize();

    xa *= sin2a;

    qa.Set( xa, angle );

    VersorType qb;

    qb = qa.SquareRoot();

    if( fabs( qa.GetAngle() - 2.0 * qb.GetAngle() ) > epsilon )
      {
      std::cout << "Error in Square Root ! " << std::endl;
      std::cout << "Angle = " << qb.GetAngle();
      std::cout << " it should be " << qa.GetAngle() / 2.0 << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a vector...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    VectorType xb;
    xb = 3.0, 7.0, 9.0;

    VectorType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a point...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    PointType xb;
    xb = 3.0, 7.0, 9.0;

    PointType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a covariantvector...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    CovariantVectorType xb;
    xb = 3.0, 7.0, 9.0;

    CovariantVectorType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {
    std::cout << "Test for Transforming a vnl_vector...";
    VersorType qa;
    VectorType xa;
    xa[0] = 2.5;
    xa[1] = 2.5;
    xa[2] = 2.5;
    ValueType angle = 8.0*atan(1.0)/3.0; // 120 degrees in radians

    qa.Set( xa, angle );

    VnlVectorType xb;
    xb[0] = 3.0;
    xb[1] = 7.0;
    xb[2] = 9.0;

    VnlVectorType xc;

    xc = qa.Transform( xb );

    // This rotation will just permute the axis

    if( fabs(xc[1]-xb[0]) > epsilon )
      {
      std::cout << "Error in X ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[2]-xb[1]) > epsilon )
      {
      std::cout << "Error in Y ! " << std::endl;
      return EXIT_FAILURE;
      }
    if( fabs(xc[0]-xb[2]) > epsilon )
      {
      std::cout << "Error in Z ! " << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;
  }

  {

    std::cout << "Test for Reciprocal and Conjugate Operations...";

    VersorType  v1;
    VersorType  v2;

    VectorType x1;
    x1 = 2.5f, 1.5f, 0.5f;

    ValueType angle1 = atan(1.0)/3.0; // 15 degrees in radians

    VectorType x2;
    x2 = 1.5f, 0.5f, 0.5f;

    ValueType angle2 = atan(1.0)/1.0; // 45 degrees in radians

    v1.Set( x1, angle1 );
    v2.Set( x2, angle2 );

    VersorType unit;
    VersorType v2r;

    v2r  = v2.GetReciprocal();
    unit = v2 * v2r;

    if( fabs( unit.GetX() ) > epsilon ||
        fabs( unit.GetY() ) > epsilon ||
        fabs( unit.GetZ() ) > epsilon ||
        fabs( unit.GetW() - 1.0 ) > epsilon )
      {
      std::cout << "Error in Reciprocal ! " << std::endl;
      std::cout << "Versor     = " << v2    << std::endl;
      std::cout << "Reciprocal = " << v2r   << std::endl;
      std::cout << "Product    = " << unit  << std::endl;

      return EXIT_FAILURE;
      }

    unit = v2 / v2;

    if( fabs( unit.GetX() ) > epsilon ||
        fabs( unit.GetY() ) > epsilon ||
        fabs( unit.GetZ() ) > epsilon ||
        fabs( unit.GetW() - 1.0 ) > epsilon )
      {
      std::cout << "Error in Division ! " << std::endl;
      std::cout << "Versor          = " << v2    << std::endl;
      std::cout << "Self Division   = " << unit  << std::endl;

      return EXIT_FAILURE;
      }

    x1.Normalize();
    x2.Normalize();

    VersorType  v3;

    v3 = v1 * v2;

    VersorType v4;

    v4 = v3 * v2r;

    if( fabs(v1.GetX() - v4.GetX() ) > epsilon ||
        fabs(v1.GetY() - v4.GetY() ) > epsilon ||
        fabs(v1.GetZ() - v4.GetZ() ) > epsilon ||
        fabs(v1.GetW() - v4.GetW() ) > epsilon )
      {
      std::cout << "Error in Versor division ! " << std::endl;
      std::cout << "v1  = " << v1 << std::endl;
      std::cout << "v1' = " << v4 << std::endl;
      return EXIT_FAILURE;
      }
    std::cout << " PASSED !" << std::endl;

  }

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <chrono>
#include <vector>
#include <map>

#include "simdjson.h"

#define NB_ITERATION 5
#define MIN_BATCH_SIZE 200000
#define MAX_BATCH_SIZE 10000000

bool test_baseline = false;
bool test_per_batch = true;
bool test_best_batch = true;

bool compare(std::pair<size_t, double> i, std::pair<size_t, double> j){
    return i.second > j.second;
}

int main (int argc, char *argv[]){

    if (argc <= 1) {
        std::cerr << "Usage: " << argv[0] << " <jsonfile>" << std::endl;
        exit(1);
    }
    const char *filename = argv[1];
    auto [p, error] = simdjson::padded_string::load(filename);
    if (error) {
        std::cerr << "Could not load the file " << filename << std::endl;
        return EXIT_FAILURE;
    }
    if (test_baseline) {
        std::wclog << "Baseline: Getline + normal parse... " << std::endl;
        std::cout << "Gigabytes/second\t" << "Nb of documents parsed" << std::endl;
        for (auto i = 0; i < 3; i++) {
            //Actual test
            simdjson::document::parser parser;
            simdjson::error_code alloc_error = parser.set_capacity(p.size());
            if (alloc_error) {
                std::cerr << alloc_error << std::endl;
                return EXIT_FAILURE;
            }
            std::istringstream ss(std::string(p.data(), p.size()));

            auto start = std::chrono::steady_clock::now();
            int count = 0;
            std::string line;
            int parse_res = simdjson::SUCCESS;
            while (getline(ss, line)) {
                // TODO we're likely triggering simdjson's padding reallocation here. Is that intentional?
                parser.parse(line);
                count++;
            }

            auto end = std::chrono::steady_clock::now();

            std::chrono::duration<double> secs = end - start;
            double speedinGBs = (p.size()) / (secs.count() * 1000000000.0);
            std::cout << speedinGBs << "\t\t\t\t" << count << std::endl;

            if (parse_res != simdjson::SUCCESS) {
                std::cerr << "Parsing failed" << std::endl;
                exit(1);
            }
        }
    }

    std::map<size_t, double> batch_size_res;
    if(test_per_batch) {
        std::wclog << "parse_many: Speed per batch_size... from " << MIN_BATCH_SIZE
                << " bytes to " << MAX_BATCH_SIZE << " bytes..." << std::endl;
        std::cout << "Batch Size\t" << "Gigabytes/second\t" << "Nb of documents parsed" << std::endl;
        for (size_t i = MIN_BATCH_SIZE; i <= MAX_BATCH_SIZE; i += (MAX_BATCH_SIZE - MIN_BATCH_SIZE) / 50) {
            batch_size_res.insert(std::pair<size_t, double>(i, 0));
            int count;
            for (size_t j = 0; j < 5; j++) {
                //Actual test
                simdjson::document::parser parser;
                simdjson::error_code error;

                auto start = std::chrono::steady_clock::now();
                count = 0;
                for (auto result : parser.parse_many(p, 4000000)) {
                    error = result.error;
                    count++;
                }
                auto end = std::chrono::steady_clock::now();

                std::chrono::duration<double> secs = end - start;
                double speedinGBs = (p.size()) / (secs.count() * 1000000000.0);
                if (speedinGBs > batch_size_res.at(i))
                    batch_size_res[i] = speedinGBs;

                if (error != simdjson::SUCCESS) {
                    std::wcerr << "Parsing failed with: " << error << std::endl;
                    exit(1);
                }
            }
            std::cout << i << "\t\t" << std::fixed << std::setprecision(3) << batch_size_res.at(i) << "\t\t\t\t" << count << std::endl;

        }
    }

    if (test_best_batch) {
        size_t optimal_batch_size;
        if (test_per_batch) {
            optimal_batch_size = (*min_element(batch_size_res.begin(), batch_size_res.end(), compare)).first;
        } else {
            optimal_batch_size = MIN_BATCH_SIZE;
        }
        std::wclog << "Starting speed test... Best of " << NB_ITERATION << " iterations..." << std::endl;
        std::wclog << "Seemingly optimal batch_size: " << optimal_batch_size << "..." << std::endl;
        std::vector<double> res;
        for (int i = 0; i < NB_ITERATION; i++) {

            // Actual test
            simdjson::document::parser parser;
            simdjson::error_code error;

            auto start = std::chrono::steady_clock::now();
            // TODO this includes allocation of the parser; is that intentional?
            for (auto result : parser.parse_many(p, 4000000)) {
                error = result.error;
            }
            auto end = std::chrono::steady_clock::now();

            std::chrono::duration<double> secs = end - start;
            res.push_back(secs.count());

            if (error != simdjson::SUCCESS) {
                std::wcerr << "Parsing failed with: " << error << std::endl;
                exit(1);
            }

        }

        std::min(res.begin(), res.end());

        double min_result = *min_element(res.begin(), res.end());
        double speedinGBs = (p.size()) / (min_result * 1000000000.0);

        std::cout << "Min:  " << min_result << " bytes read: " << p.size()
                << " Gigabytes/second: " << speedinGBs << std::endl;
    }

    return 0;
}<commit_msg>Simple fix for name erasure.<commit_after>#include <iostream>
#include <algorithm>
#include <chrono>
#include <vector>
#include <map>

#include "simdjson.h"

#define NB_ITERATION 5
#define MIN_BATCH_SIZE 200000
#define MAX_BATCH_SIZE 10000000

bool test_baseline = false;
bool test_per_batch = true;
bool test_best_batch = true;

bool compare(std::pair<size_t, double> i, std::pair<size_t, double> j){
    return i.second > j.second;
}

int main (int argc, char *argv[]){

    if (argc <= 1) {
        std::cerr << "Usage: " << argv[0] << " <jsonfile>" << std::endl;
        exit(1);
    }
    const char *filename = argv[1];
    auto [p, err] = simdjson::padded_string::load(filename);
    if (err) {
        std::cerr << "Could not load the file " << filename << std::endl;
        return EXIT_FAILURE;
    }
    if (test_baseline) {
        std::wclog << "Baseline: Getline + normal parse... " << std::endl;
        std::cout << "Gigabytes/second\t" << "Nb of documents parsed" << std::endl;
        for (auto i = 0; i < 3; i++) {
            //Actual test
            simdjson::document::parser parser;
            simdjson::error_code alloc_error = parser.set_capacity(p.size());
            if (alloc_error) {
                std::cerr << alloc_error << std::endl;
                return EXIT_FAILURE;
            }
            std::istringstream ss(std::string(p.data(), p.size()));

            auto start = std::chrono::steady_clock::now();
            int count = 0;
            std::string line;
            int parse_res = simdjson::SUCCESS;
            while (getline(ss, line)) {
                // TODO we're likely triggering simdjson's padding reallocation here. Is that intentional?
                parser.parse(line);
                count++;
            }

            auto end = std::chrono::steady_clock::now();

            std::chrono::duration<double> secs = end - start;
            double speedinGBs = (p.size()) / (secs.count() * 1000000000.0);
            std::cout << speedinGBs << "\t\t\t\t" << count << std::endl;

            if (parse_res != simdjson::SUCCESS) {
                std::cerr << "Parsing failed" << std::endl;
                exit(1);
            }
        }
    }

    std::map<size_t, double> batch_size_res;
    if(test_per_batch) {
        std::wclog << "parse_many: Speed per batch_size... from " << MIN_BATCH_SIZE
                << " bytes to " << MAX_BATCH_SIZE << " bytes..." << std::endl;
        std::cout << "Batch Size\t" << "Gigabytes/second\t" << "Nb of documents parsed" << std::endl;
        for (size_t i = MIN_BATCH_SIZE; i <= MAX_BATCH_SIZE; i += (MAX_BATCH_SIZE - MIN_BATCH_SIZE) / 50) {
            batch_size_res.insert(std::pair<size_t, double>(i, 0));
            int count;
            for (size_t j = 0; j < 5; j++) {
                //Actual test
                simdjson::document::parser parser;
                simdjson::error_code error;

                auto start = std::chrono::steady_clock::now();
                count = 0;
                for (auto result : parser.parse_many(p, 4000000)) {
                    error = result.error;
                    count++;
                }
                auto end = std::chrono::steady_clock::now();

                std::chrono::duration<double> secs = end - start;
                double speedinGBs = (p.size()) / (secs.count() * 1000000000.0);
                if (speedinGBs > batch_size_res.at(i))
                    batch_size_res[i] = speedinGBs;

                if (error != simdjson::SUCCESS) {
                    std::wcerr << "Parsing failed with: " << error << std::endl;
                    exit(1);
                }
            }
            std::cout << i << "\t\t" << std::fixed << std::setprecision(3) << batch_size_res.at(i) << "\t\t\t\t" << count << std::endl;

        }
    }

    if (test_best_batch) {
        size_t optimal_batch_size;
        if (test_per_batch) {
            optimal_batch_size = (*min_element(batch_size_res.begin(), batch_size_res.end(), compare)).first;
        } else {
            optimal_batch_size = MIN_BATCH_SIZE;
        }
        std::wclog << "Starting speed test... Best of " << NB_ITERATION << " iterations..." << std::endl;
        std::wclog << "Seemingly optimal batch_size: " << optimal_batch_size << "..." << std::endl;
        std::vector<double> res;
        for (int i = 0; i < NB_ITERATION; i++) {

            // Actual test
            simdjson::document::parser parser;
            simdjson::error_code error;

            auto start = std::chrono::steady_clock::now();
            // TODO this includes allocation of the parser; is that intentional?
            for (auto result : parser.parse_many(p, 4000000)) {
                error = result.error;
            }
            auto end = std::chrono::steady_clock::now();

            std::chrono::duration<double> secs = end - start;
            res.push_back(secs.count());

            if (error != simdjson::SUCCESS) {
                std::wcerr << "Parsing failed with: " << error << std::endl;
                exit(1);
            }

        }

        std::min(res.begin(), res.end());

        double min_result = *min_element(res.begin(), res.end());
        double speedinGBs = (p.size()) / (min_result * 1000000000.0);

        std::cout << "Min:  " << min_result << " bytes read: " << p.size()
                << " Gigabytes/second: " << speedinGBs << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "game_window.h"

bool GameWindow::sdlInitialized = false;

bool GameWindow::initialize() {
	Logger::getInstance()->writeInformation("Initializing graphics");
	if (GameWindow::sdlInitialized) {
		Logger::getInstance()->writeWarning("SDL already initialized");
	} else {
		atexit(SDL_Quit);
		if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
			Logger::getInstance()->writeError("SDL could not initialize!");
			Logger::getInstance()->writeError(SDL_GetError());
			GameWindow::sdlInitialized = false;
		} else {
			GameWindow::sdlInitialized = true;
		}
	}
	return GameWindow::sdlInitialized;
}

GameWindow::GameWindow(Game* game) {
	this->exitGame = false;
	this->model = game;
	Logger::getInstance()->writeInformation("Creating window");

	GameWindow::initialize();
	window = SDL_CreateWindow("Trabajo Práctico 7542",
			SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
			ANCHO_DEFAULT, ALTO_DEFAULT,
			SDL_WINDOW_SHOWN);

	Logger::getInstance()->writeInformation("Creating renderer");
	renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED );

	// TODO: IMG_INIT

	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Color: negro opaco
	SDL_RenderClear(renderer); // Limpio pantalla inicialmente
	SDL_RenderPresent( renderer );
}

GameWindow::~GameWindow() {

	Logger::getInstance()->writeInformation("Destroying renderer");
	if (renderer != NULL) {
		SDL_DestroyRenderer(renderer);
		renderer = NULL;
	}
	Logger::getInstance()->writeInformation("Destroying window");
	if (window != NULL) {
		Logger::getInstance()->writeWarning("Window never initialized");
		SDL_DestroyWindow(window);
		window = NULL;
	}

	for(auto itr : spritesSheets){
		delete itr.second;
	}
}

bool GameWindow::endOfGame(){
	return this->exitGame;
}

void GameWindow::render(){
	//	Dibujar
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	SDL_RenderClear(renderer);
	for (auto entity : this->model->getBoard()->getEntities()){
		auto it = this->spritesSheets.find(entity->name);
		if(it != this->spritesSheets.end()){
			it->second
				->render(entity->getX() * TILE_WIDTH_DEFAULT, entity->getY() * TILE_HEIGHT_DEFAULT, renderer);
		} else {
			Logger::getInstance()->writeWarning("No existe SpriteSheet para este tipo de entidad" + entity->name);
		}
	}

	SDL_RenderPresent( renderer );
	return;
}

void GameWindow::init(){
	this->spritesSheets["agua"] = new SpriteSheet("resources//agua.png");
	this->spritesSheets["pasto"] = new SpriteSheet("resources//pasto.png");
	this->spritesSheets["piedra"] = new SpriteSheet("resources//piedra.png");

}

void GameWindow::update(){
	model->update();
	return;
}

void GameWindow::processInput(){
	//	Procesar input del usuario
	if(SDL_PollEvent(EventHandler::getInstance()->getEvent())) {
		if(EventHandler::getInstance()->getEvent()->type == SDL_QUIT )
			this->exitGame = true;
		if(EventHandler::getInstance()->getEvent()->type == SDL_KEYDOWN )
			Logger::getInstance()->writeInformation("Teclado");
		if( EventHandler::getInstance()->getEvent()->type == SDL_MOUSEBUTTONUP ){
			if( EventHandler::getInstance()->getEvent()->button.button == SDL_BUTTON_LEFT )
				Logger::getInstance()->writeInformation("Boton Izquierdo");
			if( EventHandler::getInstance()->getEvent()->button.button == SDL_BUTTON_RIGHT)
				Logger::getInstance()->writeInformation("Boton derecho");
		}
	}
}

int GameWindow::start(){

	while (!endOfGame())
	{
		processInput();
		update();
		render();

		SDL_Delay(20); // TODO: Optimizar, sacar hardcodeo
	}
	return 0;
}

<commit_msg>Destruyo SpriteSheets antes que Renderer y Window, ya que los usa<commit_after>#include "game_window.h"

bool GameWindow::sdlInitialized = false;

bool GameWindow::initialize() {
	Logger::getInstance()->writeInformation("Initializing graphics");
	if (GameWindow::sdlInitialized) {
		Logger::getInstance()->writeWarning("SDL already initialized");
	} else {
		atexit(SDL_Quit);
		if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
			Logger::getInstance()->writeError("SDL could not initialize!");
			Logger::getInstance()->writeError(SDL_GetError());
			GameWindow::sdlInitialized = false;
		} else {
			GameWindow::sdlInitialized = true;
		}
	}
	return GameWindow::sdlInitialized;
}

GameWindow::GameWindow(Game* game) {
	this->exitGame = false;
	this->model = game;
	Logger::getInstance()->writeInformation("Creating window");

	GameWindow::initialize();
	window = SDL_CreateWindow("Trabajo Práctico 7542",
			SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
			ANCHO_DEFAULT, ALTO_DEFAULT,
			SDL_WINDOW_SHOWN);

	Logger::getInstance()->writeInformation("Creating renderer");
	renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED );

	// TODO: IMG_INIT

	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Color: negro opaco
	SDL_RenderClear(renderer); // Limpio pantalla inicialmente
	SDL_RenderPresent( renderer );
}

GameWindow::~GameWindow() {
	for(auto itr : spritesSheets){
		delete itr.second;
	}

	Logger::getInstance()->writeInformation("Destroying renderer");
	if (renderer != NULL) {
		SDL_DestroyRenderer(renderer);
		renderer = NULL;
	}

	Logger::getInstance()->writeInformation("Destroying window");
	if (window != NULL) {
		Logger::getInstance()->writeWarning("Window never initialized");
		SDL_DestroyWindow(window);
		window = NULL;
	}
}

bool GameWindow::endOfGame(){
	return this->exitGame;
}

void GameWindow::render(){
	//	Dibujar
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	SDL_RenderClear(renderer);
	for (auto entity : this->model->getBoard()->getEntities()){
		auto it = this->spritesSheets.find(entity->name);
		if(it != this->spritesSheets.end()){
			it->second
				->render(entity->getX() * TILE_WIDTH_DEFAULT, entity->getY() * TILE_HEIGHT_DEFAULT, renderer);
		} else {
			Logger::getInstance()->writeWarning("No existe SpriteSheet para este tipo de entidad" + entity->name);
		}
	}

	SDL_RenderPresent( renderer );
	return;
}

void GameWindow::init(){
	this->spritesSheets["agua"] = new SpriteSheet("resources//agua.png");
	this->spritesSheets["pasto"] = new SpriteSheet("resources//pasto.png");
	this->spritesSheets["piedra"] = new SpriteSheet("resources//piedra.png");

}

void GameWindow::update(){
	model->update();
	return;
}

void GameWindow::processInput(){
	//	Procesar input del usuario
	if(SDL_PollEvent(EventHandler::getInstance()->getEvent())) {
		if(EventHandler::getInstance()->getEvent()->type == SDL_QUIT )
			this->exitGame = true;
		if(EventHandler::getInstance()->getEvent()->type == SDL_KEYDOWN )
			Logger::getInstance()->writeInformation("Teclado");
		if( EventHandler::getInstance()->getEvent()->type == SDL_MOUSEBUTTONUP ){
			if( EventHandler::getInstance()->getEvent()->button.button == SDL_BUTTON_LEFT )
				Logger::getInstance()->writeInformation("Boton Izquierdo");
			if( EventHandler::getInstance()->getEvent()->button.button == SDL_BUTTON_RIGHT)
				Logger::getInstance()->writeInformation("Boton derecho");
		}
	}
}

int GameWindow::start(){

	while (!endOfGame())
	{
		processInput();
		update();
		render();

		SDL_Delay(20); // TODO: Optimizar, sacar hardcodeo
	}
	return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#
#include "iceoryx_posh/runtime/posh_runtime_single_process.hpp"
#include "iceoryx_posh/internal/roudi_environment/roudi_environment.hpp"

#include "test.hpp"

using namespace ::testing;
using namespace iox::runtime;
using namespace iox::roudi;

namespace iox
{
namespace test
{
/// @brief Test goal: This test suit verifies class posh_runtime_single_process

class PoshRuntimeSingleProcess_test : public Test
{
  public:
    PoshRuntimeSingleProcess_test()
    {
    }

    virtual ~PoshRuntimeSingleProcess_test()
    {
    }

    virtual void SetUp()
    {
    };

    virtual void TearDown()
    {
    };
};

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessIsSuccess)
{
  iox::RouDiConfig_t defaultRouDiConfig = iox::RouDiConfig_t().setDefaults();
  IceOryxRouDiComponents roudiComponents(defaultRouDiConfig);

  RouDi roudi(roudiComponents.m_rouDiMemoryManager,
                            roudiComponents.m_portManager,
                            RouDi::RoudiStartupParameters{iox::roudi::MonitoringMode::OFF, false});

  const ProcessName_t& m_runtimeName{"App"};
  PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);
}

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessMultipleProcessIsFound)
{
  RouDiEnvironment m_roudiEnv{iox::RouDiConfig_t().setDefaults()};

  const ProcessName_t& m_runtimeName{"App"};

  EXPECT_DEATH({PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);}, ".*");
}

} // namespace test
} // namespace iox
<commit_msg>iox-#496 improve unit test of class runtime single process<commit_after>// Copyright (c) 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#
#include "iceoryx_posh/runtime/posh_runtime_single_process.hpp"
#include "iceoryx_posh/internal/roudi_environment/roudi_environment.hpp"

#include "test.hpp"

using namespace ::testing;
using namespace iox::runtime;
using namespace iox::roudi;

namespace iox
{
namespace test
{
/// @brief Test goal: This test suit verifies class posh_runtime_single_process

class PoshRuntimeSingleProcess_test : public Test
{
  public:
    PoshRuntimeSingleProcess_test()
    {
    }

    virtual ~PoshRuntimeSingleProcess_test()
    {
    }

    virtual void SetUp()
    {
    };

    virtual void TearDown()
    {
    };
};

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessIsSuccess)
{
  iox::RouDiConfig_t defaultRouDiConfig = iox::RouDiConfig_t().setDefaults();
  IceOryxRouDiComponents roudiComponents(defaultRouDiConfig);

  RouDi roudi(roudiComponents.m_rouDiMemoryManager,
                            roudiComponents.m_portManager,
                            RouDi::RoudiStartupParameters{iox::roudi::MonitoringMode::OFF, false});

  const ProcessName_t& m_runtimeName{"App"};
  PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);
}

TEST_F(PoshRuntimeSingleProcess_test, ConstructorPoshRuntimeSingleProcessMultipleProcessIsFound)
{
  RouDiEnvironment m_roudiEnv{iox::RouDiConfig_t().setDefaults()};

  const ProcessName_t& m_runtimeName{"App"};

  iox::cxx::optional<iox::Error> detectedError;
  auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler(
    [&detectedError](const iox::Error error, const std::function<void()>, const iox::ErrorLevel errorLevel) {
        detectedError.emplace(error);
        EXPECT_THAT(errorLevel, Eq(iox::ErrorLevel::FATAL));
    });

  PoshRuntimeSingleProcess m_runtimeSingleProcess(m_runtimeName);

  ASSERT_THAT(detectedError.has_value(), Eq(true));
  EXPECT_THAT(detectedError.value(), Eq(iox::Error::kPOSH__RUNTIME_IS_CREATED_MULTIPLE_TIMES));
}

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


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "test.hpp"
#include "testutils/timing_test.hpp"

using namespace ::testing;
using ::testing::Return;

#define private public
#define protected public
#include "iceoryx_posh/internal/roudi/introspection/process_introspection.hpp"
#undef private
#undef protected

#include "iceoryx_posh/internal/popo/ports/publisher_port_data.hpp"
#include "mocks/chunk_mock.hpp"
#include "mocks/publisher_mock.hpp"

class MockPublisherPortUserIntrospection : public MockPublisherPortUser
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    MockPublisherPortUserIntrospection() = default;
    MockPublisherPortUserIntrospection(iox::popo::PublisherPortData*){};

    ChunkMock<Topic> m_chunk;

    iox::cxx::expected<iox::mepoo::ChunkHeader*, iox::popo::AllocationError> tryAllocateChunk(const uint32_t)
    {
        return iox::cxx::success<iox::mepoo::ChunkHeader*>(m_chunk.chunkHeader());
    }

    ChunkMock<Topic>* getChunk()
    {
        return &m_chunk;
    }
};

class ProcessIntrospectionAccess : public iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>
{
  public:
    void send()
    {
        iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>::send();
    }
    iox::cxx::optional<MockPublisherPortUserIntrospection>& getPublisherPort()
    {
        return this->m_publisherPort;
    }
};
class ProcessIntrospection_test : public Test
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    ProcessIntrospection_test()
    {
    }

    ~ProcessIntrospection_test()
    {
    }

    virtual void SetUp()
    {
        internal::CaptureStdout();
        // m_publisherPortData.PublisherPortData(m_serviceDescription, "Foo", &m_memoryManager);
    }

    virtual void TearDown()
    {
        std::string output = internal::GetCapturedStdout();
        if (Test::HasFailure())
        {
            std::cout << output << std::endl;
        }
        m_publisherPortData.~PublisherPortData();
    }

    ChunkMock<Topic>* createMemoryChunkAndSend(ProcessIntrospectionAccess& introspectionAccess)
    {
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(1);

        introspectionAccess.send();

        return introspectionAccess.getPublisherPort().value().getChunk();
    }

    MockPublisherPortUserIntrospection m_publisherPortImpl_mock;
    iox::mepoo::MemoryManager m_memoryManager;
    iox::capro::ServiceDescription m_serviceDescription;
    iox::popo::PublisherPortData m_publisherPortData{m_serviceDescription, "Foo", &m_memoryManager};
};

TEST_F(ProcessIntrospection_test, CTOR)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        EXPECT_THAT(introspectionAccess.getPublisherPort().has_value(), Eq(false));
    }
}

TEST_F(ProcessIntrospection_test, registerPublisherPort)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }

    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, send)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        auto chunk = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk->sample()->m_processList.size(), Eq(0U));
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveProcess)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        // invalid removal doesn't cause problems
        introspectionAccess.removeProcess(PID);
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process should be sent
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_pid, Eq(PID));
        EXPECT_THAT(iox::ProcessName_t(PROCESS_NAME) == chunk2->sample()->m_processList[0].m_name, Eq(true));

        // list should be empty after removal
        introspectionAccess.removeProcess(PID);
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(0U));

        // if there isn't any change, no data are deliverd
        EXPECT_CALL(m_publisherPortImpl_mock, sendChunk(_)).Times(0);
        introspectionAccess.send();
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, thread)
{
    {
        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), offer()).Times(1);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(AtLeast(1));

        // we use the deliverChunk call to check how often the thread calls the send method
        std::chrono::milliseconds& sendIntervalSleep =
            const_cast<std::chrono::milliseconds&>(introspectionAccess.m_sendIntervalSleep);
        sendIntervalSleep = std::chrono::milliseconds(10);

        introspectionAccess.setSendInterval(10);
        introspectionAccess.run();

        for (size_t i = 0; i < 3; ++i)
        {
            introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
            introspectionAccess.removeProcess(PID);
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
        }

        // within this time, the thread should have sent the 6 updates
        introspectionAccess.stop();
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveRunnable)
{
    {
        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";
        const char RUNNABLE_1[] = "the_wrecking_crew";
        const char RUNNABLE_2[] = "the_octagon";
        const char RUNNABLE_3[] = "the_hitman";

        // invalid removal of unknown runnable of unknown process
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));

        // invalid removal of unknown runnable of known process
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_runnables.size(), Eq(0U));

        // add a runnable
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk3->sample()->m_processList[0].m_runnables.size(), Eq(1U));

        // add it again, must be ignored
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk4 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk4->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk4->sample()->m_processList[0].m_runnables.size(), Eq(1U));

        // add some more
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_2));
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_3));
        auto chunk5 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk5->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk5->sample()->m_processList[0].m_runnables.size(), Eq(3U));

        // remove some runnables
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_3));
        auto chunk6 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk6->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk6->sample()->m_processList[0].m_runnables.size(), Eq(1U));
        EXPECT_THAT(strcmp(RUNNABLE_2, chunk6->sample()->m_processList[0].m_runnables[0].c_str()), Eq(0));

        // remove last runnable list empty again
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_2));
        auto chunk7 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk7->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk7->sample()->m_processList[0].m_runnables.size(), Eq(0U));
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}
<commit_msg>iox-#252 Remove obsolete code from test<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "test.hpp"
#include "testutils/timing_test.hpp"

using namespace ::testing;
using ::testing::Return;

#define private public
#define protected public
#include "iceoryx_posh/internal/roudi/introspection/process_introspection.hpp"
#undef private
#undef protected

#include "iceoryx_posh/internal/popo/ports/publisher_port_data.hpp"
#include "mocks/chunk_mock.hpp"
#include "mocks/publisher_mock.hpp"

class MockPublisherPortUserIntrospection : public MockPublisherPortUser
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    MockPublisherPortUserIntrospection() = default;
    MockPublisherPortUserIntrospection(iox::popo::PublisherPortData*){};

    ChunkMock<Topic> m_chunk;

    iox::cxx::expected<iox::mepoo::ChunkHeader*, iox::popo::AllocationError> tryAllocateChunk(const uint32_t)
    {
        return iox::cxx::success<iox::mepoo::ChunkHeader*>(m_chunk.chunkHeader());
    }

    ChunkMock<Topic>* getChunk()
    {
        return &m_chunk;
    }
};

class ProcessIntrospectionAccess : public iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>
{
  public:
    void send()
    {
        iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>::send();
    }

    iox::cxx::optional<MockPublisherPortUserIntrospection>& getPublisherPort()
    {
        return this->m_publisherPort;
    }
};

class ProcessIntrospection_test : public Test
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    ProcessIntrospection_test()
    {
    }

    ~ProcessIntrospection_test()
    {
    }

    virtual void SetUp()
    {
        internal::CaptureStdout();
    }

    virtual void TearDown()
    {
        std::string output = internal::GetCapturedStdout();
        if (Test::HasFailure())
        {
            std::cout << output << std::endl;
        }
    }

    ChunkMock<Topic>* createMemoryChunkAndSend(ProcessIntrospectionAccess& introspectionAccess)
    {
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(1);

        introspectionAccess.send();

        return introspectionAccess.getPublisherPort().value().getChunk();
    }

    iox::mepoo::MemoryManager m_memoryManager;
    iox::capro::ServiceDescription m_serviceDescription;
    iox::popo::PublisherPortData m_publisherPortData{m_serviceDescription, "Foo", &m_memoryManager};
};

TEST_F(ProcessIntrospection_test, CTOR)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        EXPECT_THAT(introspectionAccess.getPublisherPort().has_value(), Eq(false));
    }
}

TEST_F(ProcessIntrospection_test, registerPublisherPort)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }

    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, send)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        auto chunk = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk->sample()->m_processList.size(), Eq(0U));
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveProcess)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        // invalid removal doesn't cause problems
        introspectionAccess.removeProcess(PID);
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process should be sent
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_pid, Eq(PID));
        EXPECT_THAT(iox::ProcessName_t(PROCESS_NAME) == chunk2->sample()->m_processList[0].m_name, Eq(true));

        // list should be empty after removal
        introspectionAccess.removeProcess(PID);
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(0U));

        // if there isn't any change, no data are deliverd
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(0);
        introspectionAccess.send();
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, thread)
{
    {
        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), offer()).Times(1);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(AtLeast(1));

        // we use the deliverChunk call to check how often the thread calls the send method
        std::chrono::milliseconds& sendIntervalSleep =
            const_cast<std::chrono::milliseconds&>(introspectionAccess.m_sendIntervalSleep);
        sendIntervalSleep = std::chrono::milliseconds(10);

        introspectionAccess.setSendInterval(10);
        introspectionAccess.run();

        for (size_t i = 0; i < 3; ++i)
        {
            introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
            introspectionAccess.removeProcess(PID);
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
        }

        // within this time, the thread should have sent the 6 updates
        introspectionAccess.stop();
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveRunnable)
{
    {
        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";
        const char RUNNABLE_1[] = "the_wrecking_crew";
        const char RUNNABLE_2[] = "the_octagon";
        const char RUNNABLE_3[] = "the_hitman";

        // invalid removal of unknown runnable of unknown process
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));

        // invalid removal of unknown runnable of known process
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_runnables.size(), Eq(0U));

        // add a runnable
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk3->sample()->m_processList[0].m_runnables.size(), Eq(1U));

        // add it again, must be ignored
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        auto chunk4 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk4->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk4->sample()->m_processList[0].m_runnables.size(), Eq(1U));

        // add some more
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_2));
        introspectionAccess.addRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_3));
        auto chunk5 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk5->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk5->sample()->m_processList[0].m_runnables.size(), Eq(3U));

        // remove some runnables
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_1));
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_3));
        auto chunk6 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk6->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk6->sample()->m_processList[0].m_runnables.size(), Eq(1U));
        EXPECT_THAT(strcmp(RUNNABLE_2, chunk6->sample()->m_processList[0].m_runnables[0].c_str()), Eq(0));

        // remove last runnable list empty again
        introspectionAccess.removeRunnable(iox::ProcessName_t(PROCESS_NAME), iox::RunnableName_t(RUNNABLE_2));
        auto chunk7 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk7->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk7->sample()->m_processList[0].m_runnables.size(), Eq(0U));
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}
<|endoftext|>


<commit_before>//
//    Copyright (C) 2014 Haruki Hasegawa
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//

#ifndef CXXDASP_RESAMPLER_SMART_SMART_RESAMPLER_PARAMS_FACTORY_HPP_
#define CXXDASP_RESAMPLER_SMART_SMART_RESAMPLER_PARAMS_FACTORY_HPP_

#include <cxxporthelper/compiler.hpp>

#include <cxxdasp/resampler/smart/smart_resampler_params.hpp>

namespace cxxdasp {
namespace resampler {

/**
 * Factory class of the smart_resampler_params
 */
class smart_resampler_params_factory {

    /// @cond INTERNAL_FIELD
    smart_resampler_params_factory(const smart_resampler_params_factory &) = delete;
    smart_resampler_params_factory &operator=(const smart_resampler_params_factory &) = delete;
    /// @endcond

public:
    /**
     * Quality specifiers.
     */
    enum quality_spec_t { LowQuality, MidQuality, HighQuality, };

    /**
     * Constructor.
     *
     * @param input_freq [in] input frequency [Hz]
     * @param output_freq [in] output frequency [Hz]
     * @param quality [in] quality specifier
     */
    smart_resampler_params_factory(int input_freq, int output_freq, quality_spec_t quality);

    /**
     * Obtein parameters of smart_resampler
     *
     * @returns reference to smart_resampler_params
     */
    const smart_resampler_params &params() const CXXPH_NOEXCEPT { return params_; }

    /**
     * 'bool' operator
     *
     * @returns whether the parameters are vaild
     */
    operator bool() const CXXPH_NOEXCEPT { return is_valid_; }

private:
    /// @cond INTERNAL_FIELD
    bool is_valid_;
    smart_resampler_params params_;
    /// @endcond
};

} // namespace resampler
} // namespace cxxdasp

#endif // CXXDASP_RESAMPLER_SMART_SMART_RESAMPLER_PARAMS_FACTORY_HPP_
<commit_msg>Fix typo<commit_after>//
//    Copyright (C) 2014 Haruki Hasegawa
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//

#ifndef CXXDASP_RESAMPLER_SMART_SMART_RESAMPLER_PARAMS_FACTORY_HPP_
#define CXXDASP_RESAMPLER_SMART_SMART_RESAMPLER_PARAMS_FACTORY_HPP_

#include <cxxporthelper/compiler.hpp>

#include <cxxdasp/resampler/smart/smart_resampler_params.hpp>

namespace cxxdasp {
namespace resampler {

/**
 * Factory class of the smart_resampler_params
 */
class smart_resampler_params_factory {

    /// @cond INTERNAL_FIELD
    smart_resampler_params_factory(const smart_resampler_params_factory &) = delete;
    smart_resampler_params_factory &operator=(const smart_resampler_params_factory &) = delete;
    /// @endcond

public:
    /**
     * Quality specifiers.
     */
    enum quality_spec_t { LowQuality, MidQuality, HighQuality, };

    /**
     * Constructor.
     *
     * @param input_freq [in] input frequency [Hz]
     * @param output_freq [in] output frequency [Hz]
     * @param quality [in] quality specifier
     */
    smart_resampler_params_factory(int input_freq, int output_freq, quality_spec_t quality);

    /**
     * Obtein parameters of smart_resampler
     *
     * @returns reference to smart_resampler_params
     */
    const smart_resampler_params &params() const CXXPH_NOEXCEPT { return params_; }

    /**
     * 'bool' operator
     *
     * @returns whether the parameters are valid
     */
    operator bool() const CXXPH_NOEXCEPT { return is_valid_; }

private:
    /// @cond INTERNAL_FIELD
    bool is_valid_;
    smart_resampler_params params_;
    /// @endcond
};

} // namespace resampler
} // namespace cxxdasp

#endif // CXXDASP_RESAMPLER_SMART_SMART_RESAMPLER_PARAMS_FACTORY_HPP_
<|endoftext|>


<commit_before>#include <iostream>

int main()
{
	int a = 10;
	int& refa = a;

	const int b = 3;
	const int& refb = b;

	const int& refc = a;

	const int& refd = 100;

	int&& refe = 100; // C++11

	//int&& reff = a;

	return 0;
}
<commit_msg>const_ref.cc<commit_after>#include <iostream>

int main()
{
	int a = 10;
	// 非常量左值引用只能绑定到非常量左值
	int& refa = a;

	// 常量左值引用可以绑定到所有类型
	const int b = 3;
	const int& refb = b;
	const int& refc = a;

	// 常量左值引用可以绑定到左值和右值
	const int& refd = 100;

	// 右值引用
	int&& refe = 100; // C++11

	// 右值引用不可以绑定到左值
	//int&& reff = a;

	return 0;
}
<|endoftext|>