<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#define EIGEN_DEBUG_ASSIGN
#include "main.h"
#include <typeinfo>

std::string demangle_traversal(int t)
{
  if(t==DefaultTraversal) return "DefaultTraversal";
  if(t==LinearTraversal) return "LinearTraversal";
  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
  return "?";
}
std::string demangle_unrolling(int t)
{
  if(t==NoUnrolling) return "NoUnrolling";
  if(t==InnerUnrolling) return "InnerUnrolling";
  if(t==CompleteUnrolling) return "CompleteUnrolling";
  return "?";
}

template<typename Dst, typename Src>
bool test_assign(const Dst&, const Src&, int traversal, int unrolling)
{
  internal::assign_traits<Dst,Src>::debug();
  bool res = internal::assign_traits<Dst,Src>::Traversal==traversal
          && internal::assign_traits<Dst,Src>::Unrolling==unrolling;
  if(!res)
  {
    std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
              << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n";
    std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
              << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n";
  }
  return res;
}

template<typename Dst, typename Src>
bool test_assign(int traversal, int unrolling)
{
  internal::assign_traits<Dst,Src>::debug();
  bool res = internal::assign_traits<Dst,Src>::Traversal==traversal
          && internal::assign_traits<Dst,Src>::Unrolling==unrolling;
  if(!res)
  {
    std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
              << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n";
    std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
              << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n";
  }
  return res;
}

template<typename Xpr>
bool test_redux(const Xpr&, int traversal, int unrolling)
{
  typedef internal::redux_traits<internal::scalar_sum_op<typename Xpr::Scalar>,Xpr> traits;
  bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
  if(!res)
  {
    std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
              << " got " << demangle_traversal(traits::Traversal) << "\n";
    std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
              << " got " << demangle_unrolling(traits::Unrolling) << "\n";
  }
  return res;
}

template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectorizable> struct vectorization_logic
{
  enum {
    PacketSize = internal::packet_traits<Scalar>::size
  };
  static void run()
  {

    typedef Matrix<Scalar,PacketSize,1> Vector1;
    typedef Matrix<Scalar,Dynamic,1> VectorX;
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixXX;
    typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;
    typedef Matrix<Scalar,2*PacketSize,2*PacketSize> Matrix22;
    typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16> Matrix44;
    typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16,DontAlign|EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION> Matrix44u;
    typedef Matrix<Scalar,4*PacketSize,4*PacketSize,ColMajor> Matrix44c;
    typedef Matrix<Scalar,4*PacketSize,4*PacketSize,RowMajor> Matrix44r;

    typedef Matrix<Scalar,
        (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
        (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
      > Matrix1;

    typedef Matrix<Scalar,
        (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
        (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
      DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;

    // this type is made such that it can only be vectorized when viewed as a linear 1D vector
    typedef Matrix<Scalar,
        (PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
        (PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
      > Matrix3;

    #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
    VERIFY(test_assign(Vector1(),Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
      InnerVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_assign(Vector1(),Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
      InnerVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_assign(Matrix44(),Matrix44()+Matrix44(),
      InnerVectorizedTraversal,InnerUnrolling));

    VERIFY(test_assign(Matrix44u(),Matrix44()+Matrix44(),
      LinearTraversal,NoUnrolling));

    VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
      LinearTraversal,CompleteUnrolling));

    VERIFY(test_assign(Matrix44c().col(1),Matrix44c().col(2)+Matrix44c().col(3),
      InnerVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_assign(Matrix44r().row(2),Matrix44r().row(1)+Matrix44r().row(1),
      InnerVectorizedTraversal,CompleteUnrolling));

    if(PacketSize>1)
    {
      typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
      VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
        LinearTraversal,CompleteUnrolling));
      VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1),
        LinearTraversal,CompleteUnrolling));

      VERIFY(test_assign(Matrix3(),Matrix3().cwiseQuotient(Matrix3()),
        LinearVectorizedTraversal,CompleteUnrolling));

      VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(),
        LinearTraversal,NoUnrolling));

      VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(8,4),
        DefaultTraversal,PacketSize>4?InnerUnrolling:CompleteUnrolling));
    }

    VERIFY(test_redux(Matrix3(),
      LinearVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix44(),
      LinearVectorizedTraversal,NoUnrolling));

    VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?4:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:4>(1,2),
      DefaultTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix44c().template block<2*PacketSize,1>(1,2),
      LinearVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix44r().template block<1,2*PacketSize>(2,1),
      LinearVectorizedTraversal,CompleteUnrolling));

    VERIFY((test_assign<
            Map<Matrix22, Aligned, OuterStride<3*PacketSize> >,
            Matrix22
            >(InnerVectorizedTraversal,CompleteUnrolling)));

    VERIFY((test_assign<
            Map<Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>, Aligned, InnerStride<3*PacketSize> >,
            Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>
            >(DefaultTraversal,CompleteUnrolling)));

    VERIFY((test_assign(Matrix11(), Matrix<Scalar,PacketSize,EIGEN_PLAIN_ENUM_MIN(2,PacketSize)>()*Matrix<Scalar,EIGEN_PLAIN_ENUM_MIN(2,PacketSize),PacketSize>(),
                        PacketSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD?DefaultTraversal:InnerVectorizedTraversal, CompleteUnrolling)));
    #endif

    VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3),
      SliceVectorizedTraversal,NoUnrolling));

    VERIFY(test_redux(VectorX(10),
      LinearVectorizedTraversal,NoUnrolling));

  }
};

template<typename Scalar> struct vectorization_logic<Scalar,false>
{
  static void run() {}
};

void test_vectorization_logic()
{

#ifdef EIGEN_VECTORIZE

  CALL_SUBTEST( vectorization_logic<float>::run() );
  CALL_SUBTEST( vectorization_logic<double>::run() );
  CALL_SUBTEST( vectorization_logic<std::complex<float> >::run() );
  CALL_SUBTEST( vectorization_logic<std::complex<double> >::run() );

  if(internal::packet_traits<float>::Vectorizable)
  {
    VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(),
      LinearTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix<float,5,2>(),
      DefaultTraversal,CompleteUnrolling));
  }

  if(internal::packet_traits<double>::Vectorizable)
  {
    VERIFY(test_assign(Matrix<double,3,3>(),Matrix<double,3,3>()+Matrix<double,3,3>(),
      LinearTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix<double,7,3>(),
      DefaultTraversal,CompleteUnrolling));
  }
#endif // EIGEN_VECTORIZE

}
<commit_msg>Test vectorization logic for int<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#define EIGEN_DEBUG_ASSIGN
#include "main.h"
#include <typeinfo>

std::string demangle_traversal(int t)
{
  if(t==DefaultTraversal) return "DefaultTraversal";
  if(t==LinearTraversal) return "LinearTraversal";
  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
  return "?";
}
std::string demangle_unrolling(int t)
{
  if(t==NoUnrolling) return "NoUnrolling";
  if(t==InnerUnrolling) return "InnerUnrolling";
  if(t==CompleteUnrolling) return "CompleteUnrolling";
  return "?";
}

template<typename Dst, typename Src>
bool test_assign(const Dst&, const Src&, int traversal, int unrolling)
{
  internal::assign_traits<Dst,Src>::debug();
  bool res = internal::assign_traits<Dst,Src>::Traversal==traversal
          && internal::assign_traits<Dst,Src>::Unrolling==unrolling;
  if(!res)
  {
    std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
              << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n";
    std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
              << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n";
  }
  return res;
}

template<typename Dst, typename Src>
bool test_assign(int traversal, int unrolling)
{
  internal::assign_traits<Dst,Src>::debug();
  bool res = internal::assign_traits<Dst,Src>::Traversal==traversal
          && internal::assign_traits<Dst,Src>::Unrolling==unrolling;
  if(!res)
  {
    std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
              << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n";
    std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
              << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n";
  }
  return res;
}

template<typename Xpr>
bool test_redux(const Xpr&, int traversal, int unrolling)
{
  typedef internal::redux_traits<internal::scalar_sum_op<typename Xpr::Scalar>,Xpr> traits;
  bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
  if(!res)
  {
    std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
              << " got " << demangle_traversal(traits::Traversal) << "\n";
    std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
              << " got " << demangle_unrolling(traits::Unrolling) << "\n";
  }
  return res;
}

template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectorizable> struct vectorization_logic
{
  typedef internal::packet_traits<Scalar> PacketTraits;
  enum {
    PacketSize = PacketTraits::size
  };
  static void run()
  {

    typedef Matrix<Scalar,PacketSize,1> Vector1;
    typedef Matrix<Scalar,Dynamic,1> VectorX;
    typedef Matrix<Scalar,Dynamic,Dynamic> MatrixXX;
    typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;
    typedef Matrix<Scalar,2*PacketSize,2*PacketSize> Matrix22;
    typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16> Matrix44;
    typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16,DontAlign|EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION> Matrix44u;
    typedef Matrix<Scalar,4*PacketSize,4*PacketSize,ColMajor> Matrix44c;
    typedef Matrix<Scalar,4*PacketSize,4*PacketSize,RowMajor> Matrix44r;

    typedef Matrix<Scalar,
        (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
        (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
      > Matrix1;

    typedef Matrix<Scalar,
        (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
        (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
      DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;

    // this type is made such that it can only be vectorized when viewed as a linear 1D vector
    typedef Matrix<Scalar,
        (PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
        (PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
      > Matrix3;

    #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
    VERIFY(test_assign(Vector1(),Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
      InnerVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_assign(Vector1(),Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
      InnerVectorizedTraversal,CompleteUnrolling));
    VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
      InnerVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_assign(Matrix44(),Matrix44()+Matrix44(),
      InnerVectorizedTraversal,InnerUnrolling));

    VERIFY(test_assign(Matrix44u(),Matrix44()+Matrix44(),
      LinearTraversal,NoUnrolling));

    VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
      LinearTraversal,CompleteUnrolling));

    VERIFY(test_assign(Matrix44c().col(1),Matrix44c().col(2)+Matrix44c().col(3),
      InnerVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_assign(Matrix44r().row(2),Matrix44r().row(1)+Matrix44r().row(1),
      InnerVectorizedTraversal,CompleteUnrolling));

    if(PacketSize>1)
    {
      typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
      VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
        LinearTraversal,CompleteUnrolling));
      VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1),
        LinearTraversal,CompleteUnrolling));

      VERIFY(test_assign(Matrix3(),Matrix3().cwiseQuotient(Matrix3()),
        PacketTraits::HasDiv ? LinearVectorizedTraversal : LinearTraversal,CompleteUnrolling));

      VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(),
        LinearTraversal,NoUnrolling));

      VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(8,4),
        DefaultTraversal,PacketSize>4?InnerUnrolling:CompleteUnrolling));
    }

    VERIFY(test_redux(Matrix3(),
      LinearVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix44(),
      LinearVectorizedTraversal,NoUnrolling));

    VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?4:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:4>(1,2),
      DefaultTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix44c().template block<2*PacketSize,1>(1,2),
      LinearVectorizedTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix44r().template block<1,2*PacketSize>(2,1),
      LinearVectorizedTraversal,CompleteUnrolling));

    VERIFY((test_assign<
            Map<Matrix22, Aligned, OuterStride<3*PacketSize> >,
            Matrix22
            >(InnerVectorizedTraversal,CompleteUnrolling)));

    VERIFY((test_assign<
            Map<Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>, Aligned, InnerStride<3*PacketSize> >,
            Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>
            >(DefaultTraversal,CompleteUnrolling)));

    VERIFY((test_assign(Matrix11(), Matrix<Scalar,PacketSize,EIGEN_PLAIN_ENUM_MIN(2,PacketSize)>()*Matrix<Scalar,EIGEN_PLAIN_ENUM_MIN(2,PacketSize),PacketSize>(),
                        PacketSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD?DefaultTraversal:InnerVectorizedTraversal, CompleteUnrolling)));
    #endif

    VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3),
      SliceVectorizedTraversal,NoUnrolling));

    VERIFY(test_redux(VectorX(10),
      LinearVectorizedTraversal,NoUnrolling));

  }
};

template<typename Scalar> struct vectorization_logic<Scalar,false>
{
  static void run() {}
};

void test_vectorization_logic()
{

#ifdef EIGEN_VECTORIZE

  CALL_SUBTEST( vectorization_logic<int>::run() );
  CALL_SUBTEST( vectorization_logic<float>::run() );
  CALL_SUBTEST( vectorization_logic<double>::run() );
  CALL_SUBTEST( vectorization_logic<std::complex<float> >::run() );
  CALL_SUBTEST( vectorization_logic<std::complex<double> >::run() );

  if(internal::packet_traits<float>::Vectorizable)
  {
    VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(),
      LinearTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix<float,5,2>(),
      DefaultTraversal,CompleteUnrolling));
  }

  if(internal::packet_traits<double>::Vectorizable)
  {
    VERIFY(test_assign(Matrix<double,3,3>(),Matrix<double,3,3>()+Matrix<double,3,3>(),
      LinearTraversal,CompleteUnrolling));

    VERIFY(test_redux(Matrix<double,7,3>(),
      DefaultTraversal,CompleteUnrolling));
  }
#endif // EIGEN_VECTORIZE

}
<|endoftext|>


<commit_before>/*
 * StructureZoneComponent.cpp
 *
 *  Created on: Apr 15, 2012
 *      Author: TragD
 */

#include "server/zone/objects/scene/components/ZoneComponent.h"
#include "StructureZoneComponent.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/templates/tangible/SharedStructureObjectTemplate.h"

void StructureZoneComponent::notifyInsertToZone(SceneObject* sceneObject, Zone* zone) {
	ZoneComponent::notifyInsertToZone(sceneObject, zone);

}

void StructureZoneComponent::notifyRemoveFromZone(SceneObject* sceneObject) {
	ZoneComponent::notifyRemoveFromZone(sceneObject);

	//moved to StructureManager::destroyStructure
}
<commit_msg>(unstable) [fixed] Missing file from commit 6270 - prevented NPC from spawning<commit_after>/*
 * StructureZoneComponent.cpp
 *
 *  Created on: Apr 15, 2012
 *      Author: TragD
 */

#include "server/zone/objects/scene/components/ZoneComponent.h"
#include "StructureZoneComponent.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/templates/tangible/SharedStructureObjectTemplate.h"
#include "server/zone/objects/building/BuildingObject.h"
void StructureZoneComponent::notifyInsertToZone(SceneObject* sceneObject, Zone* zone) {
	ZoneComponent::notifyInsertToZone(sceneObject, zone);

	if(sceneObject->isGCWBase()){
		ManagedReference<BuildingObject*> building = cast<BuildingObject*>(sceneObject);
		if(building->hasChildCreatures())
			building->spawnChildCreatures();
	}
}

void StructureZoneComponent::notifyRemoveFromZone(SceneObject* sceneObject) {
	ZoneComponent::notifyRemoveFromZone(sceneObject);

	//moved to StructureManager::destroyStructure
}
<|endoftext|>


<commit_before>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   EC_SkyX.cpp
 *  @brief  A sky component using SkyX, http://www.ogre3d.org/tikiwiki/SkyX
 */

#define OGRE_INTEROP

#include "DebugOperatorNew.h"

#include "EC_SkyX.h"

#include "Scene.h"
#include "Framework.h"
#include "FrameAPI.h"
#include "OgreWorld.h"
#include "Renderer.h"
#include "EC_Camera.h"
#include "LoggingFunctions.h"
#include "OgreConversionUtils.h"

#include <Ogre.h>

#include <SkyX.h>

#include "MemoryLeakCheck.h"

struct EC_SkyXImpl
{
    EC_SkyXImpl() : skyX(0), sunlight(0), cloudLayer(0) {}
    ~EC_SkyXImpl()
    {
        if (skyX)
        {
            skyX->remove();
            if (sunlight)
                skyX->getSceneManager()->destroyLight(sunlight);
        }

        sunlight = 0;
        SAFE_DELETE(skyX)
    }

    SkyX::SkyX *skyX;
    Ogre::Light *sunlight;
    SkyX::CloudLayer *cloudLayer; ///< Currently just once cloud layer used.
};

EC_SkyX::EC_SkyX(Scene* scene) :
    IComponent(scene),
    volumetricClouds(this, "Volumetric clouds", false),
    timeMultiplier(this, "Time multiplier", 0.0f),
    time(this, "Time", float3(14.f, 7.5f, 20.5f)),
    weather(this, "Weather (volumetric clouds only)", float2(1.f, 1.f)),
//    windSpeed(this, "Wind speed", 0.0f),
    windDirection(this, "Wind direction", 0.0f),
    impl(0)
{
    OgreWorldPtr w = scene->GetWorld<OgreWorld>();
    if (!w)
    {
        LogError("EC_SkyX: no OgreWorld available. Cannot be created.");
        return;
    }

    connect(w.get(), SIGNAL(ActiveCameraChanged(EC_Camera *)), SLOT(OnActiveCameraChanged(EC_Camera*)));
    connect(this, SIGNAL(ParentEntitySet()), SLOT(Create()));
}

EC_SkyX::~EC_SkyX()
{
    if (ParentScene() && ParentScene()->GetWorld<OgreWorld>())
        delete impl;
}

float3 EC_SkyX::SunPosition() const
{
    if (impl->skyX)
        return impl->skyX->getAtmosphereManager()->getSunPosition();
    return float3();
}

void EC_SkyX::CreateSunlight()
{
    if (impl)
    {
        OgreWorldPtr w = ParentScene()->GetWorld<OgreWorld>();
        Ogre::SceneManager *sm = w->GetSceneManager();
        impl->sunlight = sm->createLight(w->GetRenderer()->GetUniqueObjectName("SkyXSunlight"));
        impl->sunlight->setType(Ogre::Light::LT_DIRECTIONAL);
        impl->sunlight->setDiffuseColour(1.f, 1.f, 1.f);
        impl->sunlight->setSpecularColour(0.f,0.f,0.f);
        impl->sunlight->setDirection(-1.f, -1.f, -1.f);
        impl->sunlight->setCastShadows(true);

        sm->setAmbientLight(Ogre::ColourValue(1.f, 1.f, 1.f));
    }
}

void EC_SkyX::Create()
{
    SAFE_DELETE(impl);

    try
    {
        if (!ParentScene())
        {
            LogError("EC_SkyX: no parent scene. Cannot be created.");
            return;
        }

        OgreWorldPtr w = ParentScene()->GetWorld<OgreWorld>();
        assert(w);

        if (!w->GetRenderer() || !w->GetRenderer()->GetActiveCamera())
            return; // Can't create SkyX just yet, no main camera set.

        Ogre::SceneManager *sm = w->GetSceneManager();

        impl = new EC_SkyXImpl();

        // Create Sky
        impl->skyX = new SkyX::SkyX(sm, static_cast<EC_Camera *>(w->GetRenderer()->GetActiveCamera())->GetCamera());
        impl->skyX->create();

        // A little change to default atmosphere settings.
        SkyX::AtmosphereManager::Options atOpt = impl->skyX->getAtmosphereManager()->getOptions();
        atOpt.RayleighMultiplier = 0.0045f;
        impl->skyX->getAtmosphereManager()->setOptions(atOpt);

        UpdateAttribute(&volumetricClouds);
        UpdateAttribute(&timeMultiplier);
        UpdateAttribute(&time);

        connect(framework->Frame(), SIGNAL(PostFrameUpdate(float)), SLOT(Update(float)), Qt::UniqueConnection);
        connect(this, SIGNAL(AttributeChanged(IAttribute*, AttributeChange::Type)), SLOT(UpdateAttribute(IAttribute*)), Qt::UniqueConnection);
    }
    catch(Ogre::Exception &e)
    {
        // Currently if we try to create more than one SkyX component we end up here due to Ogre internal name collision.
        LogError("Could not create EC_SkyX: " + std::string(e.what()));
    }
}

void EC_SkyX::OnActiveCameraChanged(EC_Camera *newActiveCamera)
{
    // If we haven't yet initialized, do a full init.
    if (!impl)
        Create();
    else // Otherwise, update the camera to an existing initialized SkyX instance.
        if (impl && impl->skyX)
            impl->skyX->setCamera(newActiveCamera->GetCamera());
}

void EC_SkyX::UpdateAttribute(IAttribute *attr)
{
    if (!impl->skyX)
        return;

    if (attr == &volumetricClouds)
    {
        if (volumetricClouds.Get())
        {
            impl->skyX->getCloudsManager()->removeAll();
            impl->skyX->getVCloudsManager()->create();
        }
        else
        {
            impl->skyX->getVCloudsManager()->remove();
            impl->skyX->getCloudsManager()->removeAll();
            impl->cloudLayer = impl->skyX->getCloudsManager()->add(SkyX::CloudLayer::Options());
        }
    }
    else if (attr == &timeMultiplier)
    {
        impl->skyX->setTimeMultiplier((Ogre::Real)timeMultiplier.Get());
    }
    else if (attr == &time)
    {
        SkyX::AtmosphereManager::Options atOpt = impl->skyX->getAtmosphereManager()->getOptions();
        atOpt.Time = time.Get();
        impl->skyX->getAtmosphereManager()->setOptions(atOpt);
    }
    else if (attr == &weather)
    {
        if (volumetricClouds.Get())
        {
            //Negative value for humidity causes crash within SkyX, so clamp value to min 0.
            float humidity = (weather.Get().x >= 0) ? weather.Get().x : 0.f;
            impl->skyX->getVCloudsManager()->getVClouds()->setWheater(humidity, weather.Get().y, 2);
        }
    }
/*
    else if (attr == &windSpeed)
    {
       if (volumetricClouds.Get())
            impl->skyX->getVCloudsManager()->setWindSpeed(0.f);
        else
            ;
    }
*/
    else if (attr == &windDirection)
    {
        if (volumetricClouds.Get())
        {
            impl->skyX->getVCloudsManager()->getVClouds()->setWindDirection(Ogre::Radian(DegToRad(windDirection.Get())));
        }
        else
        {
            SkyX::CloudLayer::Options options = impl->cloudLayer->getOptions();
            Ogre::Radian r1(Ogre::Degree(windDirection.Get())), r2(Ogre::Degree(windDirection.Get()));
            options.WindDirection = Ogre::Vector2(Ogre::Math::Cos(r1), Ogre::Math::Sin(r2));
            impl->skyX->getCloudsManager()->removeAll();
            impl->skyX->getCloudsManager()->add(options);
        }
    }
}

void EC_SkyX::Update(float frameTime)
{
    if (impl && impl->skyX)
    {
        if (impl->sunlight)
            impl->sunlight->setDirection(impl->skyX->getAtmosphereManager()->getSunDirection());
        impl->skyX->update(frameTime);
        // Do not trigger AttributeChanged for time as SkyX internals are authorative for it.
        settime(impl->skyX->getAtmosphereManager()->getOptions().Time);
    }
}
<commit_msg>Delete SkyX pimpl always in EC_SkyX dtor, not only if parent entity is available.<commit_after>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   EC_SkyX.cpp
 *  @brief  A sky component using SkyX, http://www.ogre3d.org/tikiwiki/SkyX
 */

#define OGRE_INTEROP

#include "DebugOperatorNew.h"

#include "EC_SkyX.h"

#include "Scene.h"
#include "Framework.h"
#include "FrameAPI.h"
#include "OgreWorld.h"
#include "Renderer.h"
#include "EC_Camera.h"
#include "LoggingFunctions.h"
#include "OgreConversionUtils.h"

#include <Ogre.h>

#include <SkyX.h>

#include "MemoryLeakCheck.h"

struct EC_SkyXImpl
{
    EC_SkyXImpl() : skyX(0), sunlight(0), cloudLayer(0) {}
    ~EC_SkyXImpl()
    {
        if (skyX)
        {
            skyX->remove();
            if (sunlight && skyX->getSceneManager())
                skyX->getSceneManager()->destroyLight(sunlight);
        }

        sunlight = 0;
        SAFE_DELETE(skyX)
    }

    SkyX::SkyX *skyX;
    Ogre::Light *sunlight;
    SkyX::CloudLayer *cloudLayer; ///< Currently just one cloud layer used.
};

EC_SkyX::EC_SkyX(Scene* scene) :
    IComponent(scene),
    volumetricClouds(this, "Volumetric clouds", false),
    timeMultiplier(this, "Time multiplier", 0.0f),
    time(this, "Time", float3(14.f, 7.5f, 20.5f)),
    weather(this, "Weather (volumetric clouds only)", float2(1.f, 1.f)),
//    windSpeed(this, "Wind speed", 0.0f),
    windDirection(this, "Wind direction", 0.0f),
    impl(0)
{
    OgreWorldPtr w = scene->GetWorld<OgreWorld>();
    if (!w)
    {
        LogError("EC_SkyX: no OgreWorld available. Cannot be created.");
        return;
    }

    connect(w.get(), SIGNAL(ActiveCameraChanged(EC_Camera *)), SLOT(OnActiveCameraChanged(EC_Camera*)));
    connect(this, SIGNAL(ParentEntitySet()), SLOT(Create()));
}

EC_SkyX::~EC_SkyX()
{
    SAFE_DELETE(impl);
}

float3 EC_SkyX::SunPosition() const
{
    if (impl->skyX)
        return impl->skyX->getAtmosphereManager()->getSunPosition();
    return float3();
}

void EC_SkyX::CreateSunlight()
{
    if (impl)
    {
        OgreWorldPtr w = ParentScene()->GetWorld<OgreWorld>();
        Ogre::SceneManager *sm = w->GetSceneManager();
        impl->sunlight = sm->createLight(w->GetRenderer()->GetUniqueObjectName("SkyXSunlight"));
        impl->sunlight->setType(Ogre::Light::LT_DIRECTIONAL);
        impl->sunlight->setDiffuseColour(1.f, 1.f, 1.f);
        impl->sunlight->setSpecularColour(0.f,0.f,0.f);
        impl->sunlight->setDirection(-1.f, -1.f, -1.f);
        impl->sunlight->setCastShadows(true);

        sm->setAmbientLight(Ogre::ColourValue(1.f, 1.f, 1.f));
    }
}

void EC_SkyX::Create()
{
    SAFE_DELETE(impl);

    try
    {
        if (!ParentScene())
        {
            LogError("EC_SkyX: no parent scene. Cannot be created.");
            return;
        }

        OgreWorldPtr w = ParentScene()->GetWorld<OgreWorld>();
        assert(w);

        if (!w->GetRenderer() || !w->GetRenderer()->GetActiveCamera())
            return; // Can't create SkyX just yet, no main camera set.

        Ogre::SceneManager *sm = w->GetSceneManager();

        impl = new EC_SkyXImpl();

        // Create Sky
        impl->skyX = new SkyX::SkyX(sm, static_cast<EC_Camera *>(w->GetRenderer()->GetActiveCamera())->GetCamera());
        impl->skyX->create();

        // A little change to default atmosphere settings.
        SkyX::AtmosphereManager::Options atOpt = impl->skyX->getAtmosphereManager()->getOptions();
        atOpt.RayleighMultiplier = 0.0045f;
        impl->skyX->getAtmosphereManager()->setOptions(atOpt);

        UpdateAttribute(&volumetricClouds);
        UpdateAttribute(&timeMultiplier);
        UpdateAttribute(&time);

        connect(framework->Frame(), SIGNAL(PostFrameUpdate(float)), SLOT(Update(float)), Qt::UniqueConnection);
        connect(this, SIGNAL(AttributeChanged(IAttribute*, AttributeChange::Type)), SLOT(UpdateAttribute(IAttribute*)), Qt::UniqueConnection);
    }
    catch(Ogre::Exception &e)
    {
        // Currently if we try to create more than one SkyX component we end up here due to Ogre internal name collision.
        LogError("Could not create EC_SkyX: " + std::string(e.what()));
    }
}

void EC_SkyX::OnActiveCameraChanged(EC_Camera *newActiveCamera)
{
    // If we haven't yet initialized, do a full init.
    if (!impl)
        Create();
    else // Otherwise, update the camera to an existing initialized SkyX instance.
        if (impl && impl->skyX)
            impl->skyX->setCamera(newActiveCamera->GetCamera());
}

void EC_SkyX::UpdateAttribute(IAttribute *attr)
{
    if (!impl->skyX)
        return;

    if (attr == &volumetricClouds)
    {
        if (volumetricClouds.Get())
        {
            impl->skyX->getCloudsManager()->removeAll();
            impl->skyX->getVCloudsManager()->create();
        }
        else
        {
            impl->skyX->getVCloudsManager()->remove();
            impl->skyX->getCloudsManager()->removeAll();
            impl->cloudLayer = impl->skyX->getCloudsManager()->add(SkyX::CloudLayer::Options());
        }
    }
    else if (attr == &timeMultiplier)
    {
        impl->skyX->setTimeMultiplier((Ogre::Real)timeMultiplier.Get());
    }
    else if (attr == &time)
    {
        SkyX::AtmosphereManager::Options atOpt = impl->skyX->getAtmosphereManager()->getOptions();
        atOpt.Time = time.Get();
        impl->skyX->getAtmosphereManager()->setOptions(atOpt);
    }
    else if (attr == &weather)
    {
        if (volumetricClouds.Get())
        {
            //Negative value for humidity causes crash within SkyX, so clamp value to min 0.
            float humidity = (weather.Get().x >= 0) ? weather.Get().x : 0.f;
            impl->skyX->getVCloudsManager()->getVClouds()->setWheater(humidity, weather.Get().y, 2);
        }
    }
/*
    else if (attr == &windSpeed)
    {
       if (volumetricClouds.Get())
            impl->skyX->getVCloudsManager()->setWindSpeed(0.f);
        else
            ;
    }
*/
    else if (attr == &windDirection)
    {
        if (volumetricClouds.Get())
        {
            impl->skyX->getVCloudsManager()->getVClouds()->setWindDirection(Ogre::Radian(DegToRad(windDirection.Get())));
        }
        else
        {
            SkyX::CloudLayer::Options options = impl->cloudLayer->getOptions();
            Ogre::Radian r1(Ogre::Degree(windDirection.Get())), r2(Ogre::Degree(windDirection.Get()));
            options.WindDirection = Ogre::Vector2(Ogre::Math::Cos(r1), Ogre::Math::Sin(r2));
            impl->skyX->getCloudsManager()->removeAll();
            impl->skyX->getCloudsManager()->add(options);
        }
    }
}

void EC_SkyX::Update(float frameTime)
{
    if (impl && impl->skyX)
    {
        if (impl->sunlight)
            impl->sunlight->setDirection(impl->skyX->getAtmosphereManager()->getSunDirection());
        impl->skyX->update(frameTime);
        // Do not trigger AttributeChanged for time as SkyX internals are authorative for it.
        settime(impl->skyX->getAtmosphereManager()->getOptions().Time);
    }
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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
 *
 *         https://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  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 "itkWin32Header.h"

#include <fstream>

#include "itkImageToNeighborhoodSampleAdaptor.h"
#include "itkSubsample.h"
#include "itkImageFileWriter.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"

#include "itkUniformRandomSpatialNeighborSubsampler.h"
#include "itkTestingMacros.h"

int
itkUniformRandomSpatialNeighborSubsamplerTest(int argc, char * argv[])
{
  if (argc < 2)
  {
    std::cerr << "Missing Parameters." << std::endl;
    std::cerr << "Usage: " << itkNameOfTestExecutableMacro(argv) << " useClockForSeed [outFileName]" << std::endl;
    return EXIT_FAILURE;
  }

  constexpr unsigned int Dimension = 2;

  using FloatImage = itk::Image<float, Dimension>;
  using RegionType = FloatImage::RegionType;
  using IndexType = FloatImage::IndexType;
  using SizeType = FloatImage::SizeType;
  using BoundaryCondition = itk::ZeroFluxNeumannBoundaryCondition<FloatImage>;
  using AdaptorType = itk::Statistics::ImageToNeighborhoodSampleAdaptor<FloatImage, BoundaryCondition>;
  using SamplerType = itk::Statistics::UniformRandomSpatialNeighborSubsampler<AdaptorType, RegionType>;
  using WriterType = itk::ImageFileWriter<FloatImage>;

  auto     inImage = FloatImage::New();
  SizeType sz;
  sz.Fill(35);
  IndexType idx;
  idx.Fill(0);
  RegionType region;
  region.SetSize(sz);
  region.SetIndex(idx);

  inImage->SetRegions(region);
  inImage->Allocate(true); // initialize buffer to zero

  auto sample = AdaptorType::New();
  sample->SetImage(inImage);

  auto samplerOrig = SamplerType::New();

  ITK_EXERCISE_BASIC_OBJECT_METHODS(samplerOrig, UniformRandomSpatialNeighborSubsampler, SpatialNeighborSubsampler);

  samplerOrig->SetSample(sample);
  samplerOrig->SetSampleRegion(region);
  samplerOrig->SetRadius(20);
  samplerOrig->SetNumberOfResultsRequested(50);
  samplerOrig->SetSeed(100);
  samplerOrig->CanSelectQueryOff();

  auto useClockForSeed = static_cast<bool>(std::stoi(argv[1]));
  ITK_TEST_SET_GET_BOOLEAN(samplerOrig, UseClockForSeed, useClockForSeed);

  // Test clone mechanism
  SamplerType::Pointer sampler = samplerOrig->Clone().GetPointer();

  ITK_TEST_SET_GET_VALUE(samplerOrig->GetSample(), sampler->GetSample());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetSampleRegion(), sampler->GetSampleRegion());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetRadius(), sampler->GetRadius());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetNumberOfResultsRequested(), sampler->GetNumberOfResultsRequested());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetSeed(), sampler->GetSeed());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetCanSelectQuery(), sampler->GetCanSelectQuery());

  SamplerType::SubsamplePointer subsample = SamplerType::SubsampleType::New();
  sampler->Search(612, subsample);

  for (SamplerType::SubsampleConstIterator sIt = subsample->Begin(); sIt != subsample->End(); ++sIt)
  {
    IndexType index;
    index = sIt.GetMeasurementVector()[0].GetIndex();
    inImage->SetPixel(index, 255);
  }

  if (argc > 2)
  {
    const std::string outFileName(argv[2]);

    auto writer = WriterType::New();
    writer->SetFileName(outFileName);
    writer->SetInput(inImage);

    ITK_TRY_EXPECT_NO_EXCEPTION(writer->Update());
  }

  std::cout << "Test finished." << std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>ENH: Increase `itk::UniformRandomSpatialNeighborSubsampler` coverage<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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
 *
 *         https://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  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 "itkWin32Header.h"

#include <fstream>

#include "itkImageToNeighborhoodSampleAdaptor.h"
#include "itkSubsample.h"
#include "itkImageFileWriter.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"

#include "itkUniformRandomSpatialNeighborSubsampler.h"
#include "itkTestingMacros.h"

int
itkUniformRandomSpatialNeighborSubsamplerTest(int argc, char * argv[])
{
  if (argc < 2)
  {
    std::cerr << "Missing Parameters." << std::endl;
    std::cerr << "Usage: " << itkNameOfTestExecutableMacro(argv) << " useClockForSeed [outFileName]" << std::endl;
    return EXIT_FAILURE;
  }

  constexpr unsigned int Dimension = 2;

  using FloatImage = itk::Image<float, Dimension>;
  using RegionType = FloatImage::RegionType;
  using IndexType = FloatImage::IndexType;
  using SizeType = FloatImage::SizeType;
  using BoundaryCondition = itk::ZeroFluxNeumannBoundaryCondition<FloatImage>;
  using AdaptorType = itk::Statistics::ImageToNeighborhoodSampleAdaptor<FloatImage, BoundaryCondition>;
  using SamplerType = itk::Statistics::UniformRandomSpatialNeighborSubsampler<AdaptorType, RegionType>;
  using WriterType = itk::ImageFileWriter<FloatImage>;

  auto                          inImage = FloatImage::New();
  typename SizeType::value_type regionSizeVal = 35;
  SizeType                      sz;
  sz.Fill(regionSizeVal);
  IndexType idx;
  idx.Fill(0);
  RegionType region;
  region.SetSize(sz);
  region.SetIndex(idx);

  inImage->SetRegions(region);
  inImage->Allocate(true); // initialize buffer to zero

  auto sample = AdaptorType::New();
  sample->SetImage(inImage);

  auto samplerOrig = SamplerType::New();

  ITK_EXERCISE_BASIC_OBJECT_METHODS(samplerOrig, UniformRandomSpatialNeighborSubsampler, SpatialNeighborSubsampler);

  SamplerType::InstanceIdentifier query(612);
  SamplerType::SubsamplePointer   subsample = SamplerType::SubsampleType::New();

  // Test exceptions
  ITK_TRY_EXPECT_EXCEPTION(samplerOrig->Search(query, subsample));

  samplerOrig->SetRadius(20);

  ITK_TRY_EXPECT_EXCEPTION(samplerOrig->Search(query, subsample));

  samplerOrig->SetSampleRegion(region);

  samplerOrig->SetSample(sample);

  // Expect a warning about the index being outside the given image region and an empty result
  query = std::pow(regionSizeVal, Dimension);
  samplerOrig->Search(query, subsample);

  typename SamplerType::SubsampleType::TotalAbsoluteFrequencyType expectedTotalFrequency = 0;
  ITK_TEST_EXPECT_EQUAL(expectedTotalFrequency, subsample->GetTotalFrequency());
  size_t expectedIdHolderSize = 0;
  ITK_TEST_EXPECT_EQUAL(expectedIdHolderSize, subsample->GetIdHolder().size());

  samplerOrig->CanSelectQueryOn();
  query = std::pow(regionSizeVal, Dimension) - 1;
  samplerOrig->Search(query, subsample);

  expectedTotalFrequency = 441;
  ITK_TEST_EXPECT_EQUAL(expectedTotalFrequency, subsample->GetTotalFrequency());
  expectedIdHolderSize = 441;
  ITK_TEST_EXPECT_EQUAL(expectedIdHolderSize, subsample->GetIdHolder().size());

  samplerOrig->SetNumberOfResultsRequested(50);
  samplerOrig->SetSeed(100);
  samplerOrig->CanSelectQueryOff();

  auto useClockForSeed = static_cast<bool>(std::stoi(argv[1]));
  ITK_TEST_SET_GET_BOOLEAN(samplerOrig, UseClockForSeed, useClockForSeed);

  // Test clone mechanism
  SamplerType::Pointer sampler = samplerOrig->Clone().GetPointer();

  ITK_TEST_SET_GET_VALUE(samplerOrig->GetSample(), sampler->GetSample());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetSampleRegion(), sampler->GetSampleRegion());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetRadius(), sampler->GetRadius());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetNumberOfResultsRequested(), sampler->GetNumberOfResultsRequested());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetSeed(), sampler->GetSeed());
  ITK_TEST_SET_GET_VALUE(samplerOrig->GetCanSelectQuery(), sampler->GetCanSelectQuery());

  query = 612;
  sampler->Search(query, subsample);

  for (SamplerType::SubsampleConstIterator sIt = subsample->Begin(); sIt != subsample->End(); ++sIt)
  {
    IndexType index;
    index = sIt.GetMeasurementVector()[0].GetIndex();
    inImage->SetPixel(index, 255);
  }

  if (argc > 2)
  {
    const std::string outFileName(argv[2]);

    auto writer = WriterType::New();
    writer->SetFileName(outFileName);
    writer->SetInput(inImage);

    ITK_TRY_EXPECT_NO_EXCEPTION(writer->Update());
  }

  std::cout << "Test finished." << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>
// ---------------------------------------------------
// The FDiffDelete Project
// Github: https://github.com/shishir993/fdiffdelete
// Author: Shishir Bhat
// The MIT License (MIT)
// Copyright (c) 2014
//

#include "HashFactory.h"
#include <WinCrypt.h>

#define MBYTES  (1024 * 1024)

static HRESULT _HashFileOneShot(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ DWORD cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash);
static HRESULT _HashFilePieceMeal(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ INT64 cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash);

HRESULT HashFactoryInit(_Out_ HCRYPTPROV *phCrypt)
{
    HRESULT hr = S_OK;

    *phCrypt = NULL;

    HCRYPTPROV hCrypt = NULL;
    if (CryptAcquireContext(
        &hCrypt,// handle out
        NULL,   // container
        NULL,   // provider
        PROV_DSS,           // provider type
        CRYPT_VERIFYCONTEXT))   // flags
    {
        *phCrypt = hCrypt;
    }
    else
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptAcquireContext() failed.");
    }
    return hr;
}

void HashFactoryDestroy(_In_ HCRYPTPROV hCrypt)
{
    SB_ASSERT(hCrypt != NULL);
    CryptReleaseContext(hCrypt, 0);
}

HRESULT CalculateSHA1(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash)
{
    SB_ASSERT(hCrypt != NULL);

    HRESULT hr = S_OK;
    LARGE_INTEGER fileSize = {};

    if (!GetFileSizeEx(hFile, &fileSize))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"GetFileSizeEx failed, hr: %x", hr);
        goto fend;
    }

    if ((200 * MBYTES) <= fileSize.QuadPart)
    {
        hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
        logerr(L"File too big");
        goto fend;
    }

    hr = _HashFileOneShot(hCrypt, hFile, fileSize.LowPart, pbHash);

#ifdef _DEBUG
    CHAR szHash[STRLEN_SHA1];
    HashValueToString(pbHash, szHash);
    logdbg(L"Hash string = [%S]", szHash);
#endif

fend:
    return hr;
}

void HashValueToString(_In_bytecount_c_(HASHLEN_SHA1) PBYTE pbHash, _Inout_z_ PSTR pszHashValue)
{
    for (int i = 0; i < HASHLEN_SHA1; ++i)
    {
        sprintf_s(pszHashValue + (i << 1), STRLEN_SHA1 - (i << 1), "%02x", pbHash[i]);
    }
    pszHashValue[STRLEN_SHA1 - 1] = 0;
}

HRESULT _HashFileOneShot(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ DWORD cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash)
{
    HRESULT hr = S_OK;
    HCRYPTHASH hHash = NULL;
    HANDLE hMapObj = NULL;
    HANDLE hMapView = NULL;
    DWORD dwHashSize = HASHLEN_SHA1;

    hr = CHL_GnCreateMemMapOfFile(hFile, PAGE_READONLY, &hMapObj, &hMapView);
    if (FAILED(hr))
    {
        logerr(L"Failed to mem-map file, hr: %x", hr);
        goto fend;
    }

    if (!CryptCreateHash(hCrypt, CALG_SHA1, NULL, 0, &hHash))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptCreateHash() failed");
        goto fend;
    }

    if (!CryptHashData(hHash, (PBYTE)hMapView, cbFile, 0))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptHashData failed, hr: %x", hr);
        goto fend;
    }

    if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwHashSize, 0))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptGetHashParam failed, hr: %x", hr);
        goto fend;
    }

fend:
    if (hHash != NULL)
    {
        CryptDestroyHash(hHash);
        hHash = NULL;
    }

    if (hMapView != NULL)
    {
        UnmapViewOfFile(hMapView);
        hMapView = NULL;
    }

    if (hMapObj != NULL)
    {
        CloseHandle(hMapObj);
        hMapObj = NULL;
    }

    return hr;
}

HRESULT _HashFilePieceMeal(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ INT64 cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash)
{
    return E_NOTIMPL;
}
<commit_msg>Fix #25 Enable hashing of large files<commit_after>
// ---------------------------------------------------
// The FDiffDelete Project
// Github: https://github.com/shishir993/fdiffdelete
// Author: Shishir Bhat
// The MIT License (MIT)
// Copyright (c) 2014
//

#include "HashFactory.h"
#include <WinCrypt.h>

#define MBYTES  (1024 * 1024)

static HRESULT _HashFileOneShot(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ DWORD cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash);
static HRESULT _HashFilePieceMeal(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ UINT64 cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash);

HRESULT HashFactoryInit(_Out_ HCRYPTPROV *phCrypt)
{
    HRESULT hr = S_OK;

    *phCrypt = NULL;

    HCRYPTPROV hCrypt = NULL;
    if (CryptAcquireContext(
        &hCrypt,// handle out
        NULL,   // container
        NULL,   // provider
        PROV_DSS,           // provider type
        CRYPT_VERIFYCONTEXT))   // flags
    {
        *phCrypt = hCrypt;
    }
    else
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptAcquireContext() failed.");
    }
    return hr;
}

void HashFactoryDestroy(_In_ HCRYPTPROV hCrypt)
{
    SB_ASSERT(hCrypt != NULL);
    CryptReleaseContext(hCrypt, 0);
}

HRESULT CalculateSHA1(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash)
{
    SB_ASSERT(hCrypt != NULL);

    HRESULT hr = S_OK;
    LARGE_INTEGER fileSize = {};

    if (!GetFileSizeEx(hFile, &fileSize))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"GetFileSizeEx failed, hr: %x", hr);
        goto fend;
    }

    if ((200 * MBYTES) <= fileSize.QuadPart)
    {
        hr = _HashFilePieceMeal(hCrypt, hFile, fileSize.QuadPart, pbHash);
    }
    else
    {
        hr = _HashFileOneShot(hCrypt, hFile, fileSize.LowPart, pbHash);
    }

    if (SUCCEEDED(hr))
    {
#ifdef _DEBUG
        CHAR szHash[STRLEN_SHA1];
        HashValueToString(pbHash, szHash);
        logdbg(L"Hash string = [%S]", szHash);
#endif
    }

fend:
    return hr;
}

void HashValueToString(_In_bytecount_c_(HASHLEN_SHA1) PBYTE pbHash, _Inout_z_ PSTR pszHashValue)
{
    for (int i = 0; i < HASHLEN_SHA1; ++i)
    {
        sprintf_s(pszHashValue + (i << 1), STRLEN_SHA1 - (i << 1), "%02x", pbHash[i]);
    }
    pszHashValue[STRLEN_SHA1 - 1] = 0;
}

HRESULT _HashFileOneShot(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ DWORD cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash)
{
    HRESULT hr = S_OK;
    HCRYPTHASH hHash = NULL;
    HANDLE hMapObj = NULL;
    HANDLE hMapView = NULL;
    DWORD dwHashSize = HASHLEN_SHA1;

    hr = CHL_GnCreateMemMapOfFile(hFile, PAGE_READONLY, &hMapObj, &hMapView);
    if (FAILED(hr))
    {
        logerr(L"Failed to mem-map file, hr: %x", hr);
        goto fend;
    }

    if (!CryptCreateHash(hCrypt, CALG_SHA1, NULL, 0, &hHash))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptCreateHash() failed");
        goto fend;
    }

    if (!CryptHashData(hHash, (PBYTE)hMapView, cbFile, 0))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptHashData failed, hr: %x", hr);
        goto fend;
    }

    if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwHashSize, 0))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptGetHashParam failed, hr: %x", hr);
        goto fend;
    }

fend:
    if (hHash != NULL)
    {
        CryptDestroyHash(hHash);
        hHash = NULL;
    }

    if (hMapView != NULL)
    {
        UnmapViewOfFile(hMapView);
        hMapView = NULL;
    }

    if (hMapObj != NULL)
    {
        CloseHandle(hMapObj);
        hMapObj = NULL;
    }

    return hr;
}

HRESULT _HashFilePieceMeal(_In_ HCRYPTPROV hCrypt, _In_ HANDLE hFile, _In_ UINT64 cbFile, _Out_bytecap_c_(HASHLEN_SHA1) PBYTE pbHash)
{
    HRESULT hr = S_OK;
    void* pBuffer = NULL;
    UINT64 cbRemaining = cbFile;
    const DWORD cbBuf = 16 * MBYTES;

    HCRYPTHASH hHash = NULL;
    DWORD dwHashSize = HASHLEN_SHA1;

    hr = CHL_MmAlloc(&pBuffer, cbBuf, NULL);
    if (FAILED(hr))
    {
        goto fend;
    }

    if (!CryptCreateHash(hCrypt, CALG_SHA1, NULL, 0, &hHash))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptCreateHash() failed");
        goto fend;
    }

    while (0 < cbRemaining)
    {
        DWORD cbRead = 0;
        DWORD cbToRead = (DWORD)(min(cbRemaining, cbBuf));
        if (!ReadFile(hFile, pBuffer, cbToRead, &cbRead, NULL))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            logerr(L"ReadFile failed, hr: %x", hr);
            goto fend;
        }

        if (cbRead != cbToRead)
        {
            hr = E_UNEXPECTED;
            goto fend;
        }

        cbRemaining -= cbRead;

        if (!CryptHashData(hHash, (LPCBYTE)pBuffer, cbRead, 0))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            logerr(L"CryptHashData failed, hr: %x", hr);
            goto fend;
        }
    }

    if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwHashSize, 0))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        logerr(L"CryptGetHashParam failed, hr: %x", hr);
        goto fend;
    }

fend:
    if (hHash != NULL)
    {
        CryptDestroyHash(hHash);
        hHash = NULL;
    }
    CHL_MmFree(&pBuffer);
    return hr;
}
<|endoftext|>


<commit_before>#include "Model.h"

#include <iostream>

Model_Data :: Model_Data (GLuint vao,
                          GLuint vertexPosId,
                          GLuint uvCoordsId,
                          size_t vertexCount)
:   vao         (vao )
,   vertexPosId (vertexPosId)
,   uvCoordsId  (uvCoordsId)
,   vertexCount (vertexCount)
{ }

Model :: Model(const Model_Data& data)
:   m_glData (data)
{ }

void Model::addData (const Model_Data& data)
{
    deleteData ();
    m_glData = data;
}

void Model::bind   () const
{
    glBindVertexArray (m_glData.vao);
}

void Model::unbind () const
{
    glBindVertexArray (0);
}

GLuint Model :: getVertexCount() const
{
    return m_glData.vertexCount;
}

Model :: ~Model  ()
{
    deleteData ();
}

void Model :: deleteData ()
{
    glDeleteVertexArrays (1, &m_glData.vao);

    glDeleteBuffers (1, &m_glData.vertexPosId);
    glDeleteBuffers (1, &m_glData.uvCoordsId);
}
<commit_msg>Reformat model class source<commit_after>#include "Model.h"

#include <iostream>

Model_Data::Model_Data (GLuint vao,
                        GLuint vertexPosId,
                        GLuint uvCoordsId,
                        size_t vertexCount)
:   vao         (vao )
,   vertexPosId (vertexPosId)
,   uvCoordsId  (uvCoordsId)
,   vertexCount (vertexCount)
{ }

Model::Model(const Model_Data& data)
:   m_glData (data)
{ }

void Model::addData (const Model_Data& data)
{
    deleteData ();
    m_glData = data;
}

void Model::bind () const
{
    glBindVertexArray (m_glData.vao);
}

void Model::unbind () const
{
    glBindVertexArray (0);
}

GLuint Model::getVertexCount() const
{
    return m_glData.vertexCount;
}

Model::~Model  ()
{
    deleteData ();
}

void Model::deleteData ()
{
    glDeleteVertexArrays (1, &m_glData.vao);

    glDeleteBuffers (1, &m_glData.vertexPosId);
    glDeleteBuffers (1, &m_glData.uvCoordsId);
}
<|endoftext|>


<commit_before>//
//  Guard.cpp
//  Created by Matt Kaufmann on 02/06/14.
//

#include "ExampleGame/Components/GameScripts/UnitCustomizers/Definitions.h"
#include "ExampleGame/Components/GameScripts/Units/Guard.h"
#include "ExampleGame/Components/Grid/GameGrid.h"
#include "ExampleGame/Components/Grid/GridManager.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"
#include "ExampleGame/Messages/Declarations.h"
#include "Libraries/glm/gtx/vector_angle.hpp"
#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/MessageHub/MessageHub.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Engine/Timer/Timer.h"
#include "Vajra/Utilities/MathUtilities.h"

// Wait time to return to idle after losing sight of players
#define GUARD_COOLDOWN_TIME 1.0f
// Wait time for guards to attack
#define GUARD_ATTACK_TIME 1.0f
// Range within which guards will attack players
#define ATTACK_RANGE 2.5f
// Angle at which the guard's attack can hit the player
#define ATTACK_ANGLE (15.0f inRadians)
// Guards can't be harmed if attacked from the front
#define INVINCIBLE_ANGLE (50.0f inRadians)

Guard::Guard() : EnemyUnit() {
	this->init();
}

Guard::Guard(Object* object_) : EnemyUnit(object_) {
	this->init();
}

Guard::~Guard() {
	this->destroy();
}

void Guard::init() {
	this->numPlayerUnitsSpotted = 0;
	this->cooldownTimer = GUARD_COOLDOWN_TIME;
	this->attackTimer = GUARD_ATTACK_TIME;
	this->targetId = OBJECT_ID_INVALID;
	this->weaponObjId = OBJECT_ID_INVALID;
	this->shieldObjId = OBJECT_ID_INVALID;

	this->addSubscriptionToMessageType(MESSAGE_TYPE_ANIMATION_ENDED_EVENT, this->GetTypeId(), true);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_SCENE_START, this->GetTypeId(), true);
}

void Guard::destroy() {

}

void Guard::HandleMessage(MessageChunk messageChunk) {
	EnemyUnit::HandleMessage(messageChunk);

	switch (messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_ANIMATION_ENDED_EVENT:
			this->onAnimationEnded(messageChunk->messageData.s);
			break;
	}
}

void Guard::SwitchActionState(UnitActionState newState) {
	if(newState != this->GetUnitActionState()) {
		UnitActionState oldState = this->GetUnitActionState();
		MessageChunk messageChunk = ENGINE->GetMessageHub()->GetOneFreeMessage();
		messageChunk->SetMessageType(MESSAGE_TYPE_UNIT_ACTION_STATE_CHANGED);
		messageChunk->messageData.iv1.x = oldState;
		messageChunk->messageData.iv1.y = newState;
		if (this->weaponObjId != OBJECT_ID_INVALID) {
			ENGINE->GetMessageHub()->SendPointcastMessage(messageChunk, this->weaponObjId, this->GetObject()->GetId());
		}
		if (this->shieldObjId != OBJECT_ID_INVALID) {
			ENGINE->GetMessageHub()->SendPointcastMessage(messageChunk, this->shieldObjId, this->GetObject()->GetId());
		}
	}

	BaseUnit::SwitchActionState(newState);
}

bool Guard::CanBeKilledBy(ObjectIdType id, glm::vec3 /*source*/) {
	GameObject* gObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(id);
	if (gObj != nullptr) {
		BaseUnit* unit = gObj->GetComponent<BaseUnit>();
		if (unit != nullptr) {
			if ((unit->GetUnitType() >= FIRST_PLAYER_UNIT_TYPE) && (unit->GetUnitType() <= LAST_PLAYER_UNIT_TYPE)) {
				// Guards can only be killed if they are unaware.
				auto iter = std::find(this->knownPlayers.begin(), this->knownPlayers.end(), id);
				return (iter == this->knownPlayers.end());
				/*
				// Guards are invincible from the front, so check the angle of the attack.
				glm::vec3 dir = source - this->gameObjectRef->GetTransform()->GetPositionWorld();
				glm::vec3 forward = QuaternionForwardVector(this->gameObjectRef->GetTransform()->GetOrientationWorld());
				// Don't use glm's vector angle function because it never returns an angle greater than PI/2
				float angle = acos(glm::clamp(glm::dot(dir, forward), -1.0f, 1.0f));
				if (angle >= INVINCIBLE_ANGLE) {
					return true;
				}
				*/
			}
		}
	}
	return false;
}

void Guard::start() {
	std::list<ObjectIdType> childIds = this->gameObjectRef->GetChildren();
	for (ObjectIdType childId : childIds) {
		GameObject* childObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(childId);
		if (childObj != nullptr) {
			if (childObj->HasTag("Weapon")) {
				this->weaponObjId = childId;
			}
			if (childObj->HasTag("Shield")) {
				this->shieldObjId = childId;
			}
		}
	}
}

void Guard::determineBrainState() {
	if (this->brainState == ENEMY_BRAIN_CALM) {
		if (this->knownPlayers.size() > 0) {
			this->setBrainState(ENEMY_BRAIN_CAUTIOUS);
		}
	}
	else if (this->brainState == ENEMY_BRAIN_CAUTIOUS) {
		if (this->cooldownTimer <= 0.0f) {
			this->setBrainState(ENEMY_BRAIN_CALM);
		}
	}
}

void Guard::onBrainBecameCalm() {
	EnemyUnit::onBrainBecameCalm();
	this->SwitchActionState(UNIT_ACTION_STATE_IDLE);
}

void Guard::onBrainBecameCautious() {
	EnemyUnit::onBrainBecameCautious();
	this->attackTimer = GUARD_ATTACK_TIME;
	this->cooldownTimer = GUARD_COOLDOWN_TIME;
	this->SwitchActionState(UNIT_ACTION_STATE_PRE_BLOCK);
	this->gridNavRef->HaltMovement();
}

void Guard::onBrainBecameAggressive() {
	EnemyUnit::onBrainBecameAggressive();
	this->SwitchActionState(UNIT_ACTION_STATE_DOING_SPECIAL);
}

void Guard::cautiousUpdate() {
	float dt = ENGINE->GetTimer()->GetDeltaFrameTime();

	this->attackTimer -= dt;

	if (this->knownPlayers.size() > 0) {
		this->cooldownTimer = GUARD_COOLDOWN_TIME;
	}
	else {
		this->targetId = OBJECT_ID_INVALID;
		this->cooldownTimer -= dt;
		if (this->cooldownTimer <= 0.0f) {
			this->setBrainState(ENEMY_BRAIN_CALM);
		}
	}

	glm::vec3 myLocation = this->GetObject()->GetComponent<Transform>()->GetPositionWorld();
	float minDistance = 100.0f;
	GameObject* targetObj = nullptr;
	for (auto iter = this->knownPlayers.begin(); iter != this->knownPlayers.end(); ++iter) {
		GameObject* playerObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(*iter);
		glm::vec3 unitLocation = playerObj->GetTransform()->GetPositionWorld();
		float distance = glm::distance(myLocation, unitLocation);
		if (distance < minDistance) {
			this->targetId = *iter;
			targetObj = playerObj;
			minDistance = distance;
		}
	}

	if (targetObj != nullptr) {
		// Turn to face towards the target
		this->gridNavRef->SetLookTarget(targetObj->GetTransform()->GetPositionWorld());

		// Attack the target if it's in range or it's doing a special.
		BaseUnit* targetUnit = targetObj->GetComponent<BaseUnit>();
		if (((minDistance <= ATTACK_RANGE) && (this->GetUnitActionState() == UNIT_ACTION_STATE_BLOCK_IDLE))
				|| (targetUnit->GetUnitActionState() == UNIT_ACTION_STATE_DOING_SPECIAL)) {
			this->setBrainState(ENEMY_BRAIN_AGGRESSIVE);
		}
	}
}

void Guard::aggressiveUpdate() {
	// Keep turning towards the target
	GameObject* targetObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(this->targetId);
	if (targetObj != nullptr) {
		this->gridNavRef->SetLookTarget(targetObj->GetTransform()->GetPositionWorld());
	}
}

void Guard::onSightedPlayerUnit(ObjectIdType id) {
	this->numPlayerUnitsSpotted++;
	this->knownPlayers.push_back(id);

	if ((this->brainState == ENEMY_BRAIN_CALM) && (this->numPlayerUnitsSpotted > 0)) {
		this->setBrainState(ENEMY_BRAIN_CAUTIOUS);
	}
}

void Guard::onLostSightOfPlayerUnit(ObjectIdType id) {
	this->numPlayerUnitsSpotted--;
	this->knownPlayers.remove(id);
}

void Guard::onAnimationEnded(std::string animName) {
	if (animName == UNIT_ANIMATION_CLIP_NAME_block) {
		this->SwitchActionState(UNIT_ACTION_STATE_BLOCK_IDLE);
	}
	else if (animName == UNIT_ANIMATION_CLIP_NAME_doingspecial) {
		this->SwitchActionState(UNIT_ACTION_STATE_POST_SPECIAL);
		this->performAttack();
	}
	else if (animName == UNIT_ANIMATION_CLIP_NAME_postspecial) {
		this->setBrainState(ENEMY_BRAIN_CAUTIOUS);
	}
}

void Guard::performAttack() {
	GameObject* targetObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(this->targetId);
	if (targetObj != nullptr) {
		// Verify that the target is within reach
		glm::vec3 myPosition = this->gameObjectRef->GetTransform()->GetPositionWorld();
		glm::vec3 targetPosition = targetObj->GetTransform()->GetPositionWorld();
		float dist = glm::distance(targetPosition, myPosition);
		glm::vec3 forward = QuaternionForwardVector(this->gameObjectRef->GetTransform()->GetOrientationWorld());
		// Don't use glm's vector angle function because it never returns an angle greater than PI/2
		float angle = acos(glm::clamp(glm::dot(forward, targetPosition - myPosition), -1.0f, 1.0f));
		if ((dist <= ATTACK_RANGE) && (angle <= ATTACK_ANGLE)) {
			GridCell* cell = SINGLETONS->GetGridManager()->GetGrid()->GetCell(targetPosition);
			if (cell != nullptr) {
				int elevation = SINGLETONS->GetGridManager()->GetGrid()->GetElevationFromWorldY(myPosition.y);

				// Attack the intended target
				MessageChunk attackMessage = ENGINE->GetMessageHub()->GetOneFreeMessage();
				attackMessage->SetMessageType(MESSAGE_TYPE_UNIT_SPECIAL_HIT);
				attackMessage->messageData.iv1.x = cell->x;
				attackMessage->messageData.iv1.y = elevation;
				attackMessage->messageData.iv1.z = cell->z;
				attackMessage->messageData.fv1 = this->gameObjectRef->GetTransform()->GetPositionWorld();
				ENGINE->GetMessageHub()->SendMulticastMessage(attackMessage, this->GetObject()->GetId());
			}
		}
	}
}
<commit_msg>Added a hook to Guard for an attack sound<commit_after>//
//  Guard.cpp
//  Created by Matt Kaufmann on 02/06/14.
//

#include "ExampleGame/Components/GameScripts/UnitCustomizers/Definitions.h"
#include "ExampleGame/Components/GameScripts/Units/Guard.h"
#include "ExampleGame/Components/Grid/GameGrid.h"
#include "ExampleGame/Components/Grid/GridManager.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"
#include "ExampleGame/Messages/Declarations.h"
#include "Libraries/glm/gtx/vector_angle.hpp"
#include "Vajra/Engine/Components/DerivedComponents/Audio/AudioSource.h"
#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/MessageHub/MessageHub.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Engine/Timer/Timer.h"
#include "Vajra/Utilities/MathUtilities.h"

// Wait time to return to idle after losing sight of players
#define GUARD_COOLDOWN_TIME 1.0f
// Wait time for guards to attack
#define GUARD_ATTACK_TIME 1.0f
// Range within which guards will attack players
#define ATTACK_RANGE 2.5f
// Angle at which the guard's attack can hit the player
#define ATTACK_ANGLE (15.0f inRadians)
// Guards can't be harmed if attacked from the front
#define INVINCIBLE_ANGLE (50.0f inRadians)

Guard::Guard() : EnemyUnit() {
	this->init();
}

Guard::Guard(Object* object_) : EnemyUnit(object_) {
	this->init();
}

Guard::~Guard() {
	this->destroy();
}

void Guard::init() {
	this->numPlayerUnitsSpotted = 0;
	this->cooldownTimer = GUARD_COOLDOWN_TIME;
	this->attackTimer = GUARD_ATTACK_TIME;
	this->targetId = OBJECT_ID_INVALID;
	this->weaponObjId = OBJECT_ID_INVALID;
	this->shieldObjId = OBJECT_ID_INVALID;

	this->addSubscriptionToMessageType(MESSAGE_TYPE_ANIMATION_ENDED_EVENT, this->GetTypeId(), true);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_SCENE_START, this->GetTypeId(), true);
}

void Guard::destroy() {

}

void Guard::HandleMessage(MessageChunk messageChunk) {
	EnemyUnit::HandleMessage(messageChunk);

	switch (messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_ANIMATION_ENDED_EVENT:
			this->onAnimationEnded(messageChunk->messageData.s);
			break;
	}
}

void Guard::SwitchActionState(UnitActionState newState) {
	if(newState != this->GetUnitActionState()) {
		UnitActionState oldState = this->GetUnitActionState();
		MessageChunk messageChunk = ENGINE->GetMessageHub()->GetOneFreeMessage();
		messageChunk->SetMessageType(MESSAGE_TYPE_UNIT_ACTION_STATE_CHANGED);
		messageChunk->messageData.iv1.x = oldState;
		messageChunk->messageData.iv1.y = newState;
		if (this->weaponObjId != OBJECT_ID_INVALID) {
			ENGINE->GetMessageHub()->SendPointcastMessage(messageChunk, this->weaponObjId, this->GetObject()->GetId());
		}
		if (this->shieldObjId != OBJECT_ID_INVALID) {
			ENGINE->GetMessageHub()->SendPointcastMessage(messageChunk, this->shieldObjId, this->GetObject()->GetId());
		}
	}

	BaseUnit::SwitchActionState(newState);
}

bool Guard::CanBeKilledBy(ObjectIdType id, glm::vec3 /*source*/) {
	GameObject* gObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(id);
	if (gObj != nullptr) {
		BaseUnit* unit = gObj->GetComponent<BaseUnit>();
		if (unit != nullptr) {
			if ((unit->GetUnitType() >= FIRST_PLAYER_UNIT_TYPE) && (unit->GetUnitType() <= LAST_PLAYER_UNIT_TYPE)) {
				// Guards can only be killed if they are unaware.
				auto iter = std::find(this->knownPlayers.begin(), this->knownPlayers.end(), id);
				return (iter == this->knownPlayers.end());
				/*
				// Guards are invincible from the front, so check the angle of the attack.
				glm::vec3 dir = source - this->gameObjectRef->GetTransform()->GetPositionWorld();
				glm::vec3 forward = QuaternionForwardVector(this->gameObjectRef->GetTransform()->GetOrientationWorld());
				// Don't use glm's vector angle function because it never returns an angle greater than PI/2
				float angle = acos(glm::clamp(glm::dot(dir, forward), -1.0f, 1.0f));
				if (angle >= INVINCIBLE_ANGLE) {
					return true;
				}
				*/
			}
		}
	}
	return false;
}

void Guard::start() {
	std::list<ObjectIdType> childIds = this->gameObjectRef->GetChildren();
	for (ObjectIdType childId : childIds) {
		GameObject* childObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(childId);
		if (childObj != nullptr) {
			if (childObj->HasTag("Weapon")) {
				this->weaponObjId = childId;
			}
			if (childObj->HasTag("Shield")) {
				this->shieldObjId = childId;
			}
		}
	}
}

void Guard::determineBrainState() {
	if (this->brainState == ENEMY_BRAIN_CALM) {
		if (this->knownPlayers.size() > 0) {
			this->setBrainState(ENEMY_BRAIN_CAUTIOUS);
		}
	}
	else if (this->brainState == ENEMY_BRAIN_CAUTIOUS) {
		if (this->cooldownTimer <= 0.0f) {
			this->setBrainState(ENEMY_BRAIN_CALM);
		}
	}
}

void Guard::onBrainBecameCalm() {
	EnemyUnit::onBrainBecameCalm();
	this->SwitchActionState(UNIT_ACTION_STATE_IDLE);
}

void Guard::onBrainBecameCautious() {
	EnemyUnit::onBrainBecameCautious();
	this->attackTimer = GUARD_ATTACK_TIME;
	this->cooldownTimer = GUARD_COOLDOWN_TIME;
	this->SwitchActionState(UNIT_ACTION_STATE_PRE_BLOCK);
	this->gridNavRef->HaltMovement();
}

void Guard::onBrainBecameAggressive() {
	EnemyUnit::onBrainBecameAggressive();
	this->SwitchActionState(UNIT_ACTION_STATE_DOING_SPECIAL);
}

void Guard::cautiousUpdate() {
	float dt = ENGINE->GetTimer()->GetDeltaFrameTime();

	this->attackTimer -= dt;

	if (this->knownPlayers.size() > 0) {
		this->cooldownTimer = GUARD_COOLDOWN_TIME;
	}
	else {
		this->targetId = OBJECT_ID_INVALID;
		this->cooldownTimer -= dt;
		if (this->cooldownTimer <= 0.0f) {
			this->setBrainState(ENEMY_BRAIN_CALM);
		}
	}

	glm::vec3 myLocation = this->GetObject()->GetComponent<Transform>()->GetPositionWorld();
	float minDistance = 100.0f;
	GameObject* targetObj = nullptr;
	for (auto iter = this->knownPlayers.begin(); iter != this->knownPlayers.end(); ++iter) {
		GameObject* playerObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(*iter);
		glm::vec3 unitLocation = playerObj->GetTransform()->GetPositionWorld();
		float distance = glm::distance(myLocation, unitLocation);
		if (distance < minDistance) {
			this->targetId = *iter;
			targetObj = playerObj;
			minDistance = distance;
		}
	}

	if (targetObj != nullptr) {
		// Turn to face towards the target
		this->gridNavRef->SetLookTarget(targetObj->GetTransform()->GetPositionWorld());

		// Attack the target if it's in range or it's doing a special.
		BaseUnit* targetUnit = targetObj->GetComponent<BaseUnit>();
		if (((minDistance <= ATTACK_RANGE) && (this->GetUnitActionState() == UNIT_ACTION_STATE_BLOCK_IDLE))
				|| (targetUnit->GetUnitActionState() == UNIT_ACTION_STATE_DOING_SPECIAL)) {
			this->setBrainState(ENEMY_BRAIN_AGGRESSIVE);
		}
	}
}

void Guard::aggressiveUpdate() {
	// Keep turning towards the target
	GameObject* targetObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(this->targetId);
	if (targetObj != nullptr) {
		this->gridNavRef->SetLookTarget(targetObj->GetTransform()->GetPositionWorld());
	}
}

void Guard::onSightedPlayerUnit(ObjectIdType id) {
	this->numPlayerUnitsSpotted++;
	this->knownPlayers.push_back(id);

	if ((this->brainState == ENEMY_BRAIN_CALM) && (this->numPlayerUnitsSpotted > 0)) {
		this->setBrainState(ENEMY_BRAIN_CAUTIOUS);
	}
}

void Guard::onLostSightOfPlayerUnit(ObjectIdType id) {
	this->numPlayerUnitsSpotted--;
	this->knownPlayers.remove(id);
}

void Guard::onAnimationEnded(std::string animName) {
	if (animName == UNIT_ANIMATION_CLIP_NAME_block) {
		this->SwitchActionState(UNIT_ACTION_STATE_BLOCK_IDLE);
	}
	else if (animName == UNIT_ANIMATION_CLIP_NAME_doingspecial) {
		this->SwitchActionState(UNIT_ACTION_STATE_POST_SPECIAL);
		this->performAttack();
	}
	else if (animName == UNIT_ANIMATION_CLIP_NAME_postspecial) {
		this->setBrainState(ENEMY_BRAIN_CAUTIOUS);
	}
}

void Guard::performAttack() {
	GameObject* targetObj = ENGINE->GetSceneGraph3D()->GetGameObjectById(this->targetId);
	if (targetObj != nullptr) {
		// Verify that the target is within reach
		glm::vec3 myPosition = this->gameObjectRef->GetTransform()->GetPositionWorld();
		glm::vec3 targetPosition = targetObj->GetTransform()->GetPositionWorld();
		float dist = glm::distance(targetPosition, myPosition);
		glm::vec3 forward = QuaternionForwardVector(this->gameObjectRef->GetTransform()->GetOrientationWorld());
		// Don't use glm's vector angle function because it never returns an angle greater than PI/2
		float angle = acos(glm::clamp(glm::dot(forward, targetPosition - myPosition), -1.0f, 1.0f));
		if ((dist <= ATTACK_RANGE) && (angle <= ATTACK_ANGLE)) {
			GridCell* cell = SINGLETONS->GetGridManager()->GetGrid()->GetCell(targetPosition);
			if (cell != nullptr) {
				int elevation = SINGLETONS->GetGridManager()->GetGrid()->GetElevationFromWorldY(myPosition.y);

				// Attack the intended target
				MessageChunk attackMessage = ENGINE->GetMessageHub()->GetOneFreeMessage();
				attackMessage->SetMessageType(MESSAGE_TYPE_UNIT_SPECIAL_HIT);
				attackMessage->messageData.iv1.x = cell->x;
				attackMessage->messageData.iv1.y = elevation;
				attackMessage->messageData.iv1.z = cell->z;
				attackMessage->messageData.fv1 = this->gameObjectRef->GetTransform()->GetPositionWorld();
				ENGINE->GetMessageHub()->SendMulticastMessage(attackMessage, this->GetObject()->GetId());

				AudioSource* audioSource = this->gameObjectRef->GetComponent<AudioSource>();
				if (audioSource != nullptr) {
					audioSource->Play("specialStart");
				}
			}
		}
	}
}
<|endoftext|>