<commit_before>// Copyright 2012 Cloudera Inc.
//
// 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 <boost/scoped_ptr.hpp>
#include <string>
#include <gtest/gtest.h>

#include "rpc/thrift-client.h"
#include "service/impala-server.h"
#include "testutil/in-process-servers.h"
#include "common/init.h"
#include "service/fe-support.h"
#include "util/impalad-metrics.h"
#include "util/time.h"

#include "common/names.h"

using namespace apache::hive::service::cli::thrift;
using namespace apache::thrift;
using namespace impala;

DECLARE_int32(idle_session_timeout);
DECLARE_int32(be_port);
DECLARE_int32(beeswax_port);

// TODO: When sleep(..) queries can be cancelled, write a test that confirms long-running
// queries are cancelled during session expiry.
// TODO: Come up with a short-running test that confirms a session will keep itself alive
// that doesn't depend upon being rescheduled in a timely fashion.

TEST(SessionTest, TestExpiry) {
  FLAGS_idle_session_timeout = 1;
  InProcessImpalaServer* impala = InProcessImpalaServer::StartWithEphemeralPorts();
  IntCounter* expired_metric =
      impala->metrics()->FindMetricForTesting<IntCounter>(
          ImpaladMetricKeys::NUM_SESSIONS_EXPIRED);
  DCHECK(expired_metric != NULL);
  IntGauge* beeswax_session_metric =
      impala->metrics()->FindMetricForTesting<IntGauge>(
          ImpaladMetricKeys::IMPALA_SERVER_NUM_OPEN_BEESWAX_SESSIONS);
  IntGauge* hs2_session_metric =
      impala->metrics()->FindMetricForTesting<IntGauge>(
          ImpaladMetricKeys::IMPALA_SERVER_NUM_OPEN_HS2_SESSIONS);
  EXPECT_EQ(expired_metric->value(), 0L);
  EXPECT_EQ(beeswax_session_metric->value(), 0L);

  scoped_ptr<ThriftClient<ImpalaServiceClient> > beeswax_clients[5];
  scoped_ptr<ThriftClient<ImpalaHiveServer2ServiceClient> > hs2_clients[5];

  // Create five Beeswax clients and five HS2 clients (each HS2 gets one session each)
  for (int i = 0; i < 5; ++i) {
    beeswax_clients[i].reset(new ThriftClient<ImpalaServiceClient>(
        "localhost", impala->beeswax_port()));
    EXPECT_TRUE(beeswax_clients[i]->Open().ok());

    hs2_clients[i].reset(new ThriftClient<ImpalaHiveServer2ServiceClient>(
        "localhost", impala->hs2_port()));
    EXPECT_TRUE(hs2_clients[i]->Open().ok());
    TOpenSessionResp response;
    TOpenSessionReq request;
    hs2_clients[i]->iface()->OpenSession(response, request);
  }

  int64_t start = UnixMillis();
  while (expired_metric->value() != 10 && UnixMillis() - start < 5000) {
    SleepForMs(100);
  }

  ASSERT_EQ(expired_metric->value(), 10L) << "Sessions did not expire within 5s";
  ASSERT_EQ(beeswax_session_metric->value(), 5L)
      << "Beeswax sessions unexpectedly closed after expiration";
  ASSERT_EQ(hs2_session_metric->value(), 5L)
      << "HiveServer2 sessions unexpectedly closed after expiration";

  TPingImpalaServiceResp resp;
  ASSERT_THROW({beeswax_clients[0]->iface()->PingImpalaService(resp);}, TException)
      << "Ping succeeded even after session expired";
}

int main(int argc, char** argv) {
  InitCommonRuntime(argc, argv, true);
  InitFeSupport();
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>IMPALA-2804: prevent destroying Thrift server before worker threads complete<commit_after>// Copyright 2012 Cloudera Inc.
//
// 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 <boost/scoped_ptr.hpp>
#include <string>
#include <gtest/gtest.h>

#include "rpc/thrift-client.h"
#include "service/impala-server.h"
#include "testutil/in-process-servers.h"
#include "common/init.h"
#include "service/fe-support.h"
#include "util/impalad-metrics.h"
#include "util/time.h"

#include "common/names.h"

using namespace apache::hive::service::cli::thrift;
using namespace apache::thrift;
using namespace impala;

DECLARE_int32(idle_session_timeout);
DECLARE_int32(be_port);
DECLARE_int32(beeswax_port);

// TODO: When sleep(..) queries can be cancelled, write a test that confirms long-running
// queries are cancelled during session expiry.
// TODO: Come up with a short-running test that confirms a session will keep itself alive
// that doesn't depend upon being rescheduled in a timely fashion.

TEST(SessionTest, TestExpiry) {
  FLAGS_idle_session_timeout = 1;
  InProcessImpalaServer* impala = InProcessImpalaServer::StartWithEphemeralPorts();
  IntCounter* expired_metric =
      impala->metrics()->FindMetricForTesting<IntCounter>(
          ImpaladMetricKeys::NUM_SESSIONS_EXPIRED);
  DCHECK(expired_metric != NULL);
  IntGauge* beeswax_session_metric =
      impala->metrics()->FindMetricForTesting<IntGauge>(
          ImpaladMetricKeys::IMPALA_SERVER_NUM_OPEN_BEESWAX_SESSIONS);
  IntGauge* hs2_session_metric =
      impala->metrics()->FindMetricForTesting<IntGauge>(
          ImpaladMetricKeys::IMPALA_SERVER_NUM_OPEN_HS2_SESSIONS);
  EXPECT_EQ(expired_metric->value(), 0L);
  EXPECT_EQ(beeswax_session_metric->value(), 0L);

  {
    scoped_ptr<ThriftClient<ImpalaServiceClient> > beeswax_clients[5];
    scoped_ptr<ThriftClient<ImpalaHiveServer2ServiceClient> > hs2_clients[5];

    // Create five Beeswax clients and five HS2 clients (each HS2 gets one session each)
    for (int i = 0; i < 5; ++i) {
      beeswax_clients[i].reset(new ThriftClient<ImpalaServiceClient>(
              "localhost", impala->beeswax_port()));
      EXPECT_TRUE(beeswax_clients[i]->Open().ok());

      hs2_clients[i].reset(new ThriftClient<ImpalaHiveServer2ServiceClient>(
              "localhost", impala->hs2_port()));
      EXPECT_TRUE(hs2_clients[i]->Open().ok());
      TOpenSessionResp response;
      TOpenSessionReq request;
      hs2_clients[i]->iface()->OpenSession(response, request);
    }

    int64_t start = UnixMillis();
    while (expired_metric->value() != 10 && UnixMillis() - start < 5000) {
      SleepForMs(100);
    }

    ASSERT_EQ(expired_metric->value(), 10L) << "Sessions did not expire within 5s";
    ASSERT_EQ(beeswax_session_metric->value(), 5L)
        << "Beeswax sessions unexpectedly closed after expiration";
    ASSERT_EQ(hs2_session_metric->value(), 5L)
        << "HiveServer2 sessions unexpectedly closed after expiration";

    TPingImpalaServiceResp resp;
    ASSERT_THROW({beeswax_clients[0]->iface()->PingImpalaService(resp);}, TException)
        << "Ping succeeded even after session expired";
  }
  // The TThreadedServer within 'impala' has no mechanism to join on its worker threads
  // (it looks like there's code that's meant to do this, but it doesn't appear to
  // work). Sleep to allow the threads closing the session to complete before tearing down
  // the server.
  SleepForMs(1000);
}

int main(int argc, char** argv) {
  InitCommonRuntime(argc, argv, true);
  InitFeSupport();
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*
	Copyright 2021 Jordi SUBIRANA

	Permission is hereby granted, free of charge, to any person obtaining a copy of
	this software and associated documentation files (the "Software"), to deal in
	the Software without restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
	Software, and to permit persons to whom the Software is furnished to do so, subject
	to the following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
	PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
	OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ATEMA_RENDERER_BUFFER_HPP
#define ATEMA_RENDERER_BUFFER_HPP

#include <Atema/Renderer/Config.hpp>
#include <Atema/Core/NonCopyable.hpp>
#include <Atema/Core/Pointer.hpp>
#include <Atema/Renderer/Enums.hpp>

namespace at
{
	class ATEMA_RENDERER_API Buffer : public NonCopyable
	{
	public:
		struct Settings
		{
			BufferUsage usage = BufferUsage::Vertex;
			size_t byteSize = 0;
		};

		virtual ~Buffer();

		static Ptr<Buffer> create(const Settings& settings);

		// For transfer buffers only
		virtual void* map(size_t byteOffset = 0, size_t byteSize = 0) = 0;
		virtual void unmap() = 0;

	protected:
		Buffer();
	};
}

#endif
<commit_msg>Renderer - Buffer - Added mappable option<commit_after>/*
	Copyright 2021 Jordi SUBIRANA

	Permission is hereby granted, free of charge, to any person obtaining a copy of
	this software and associated documentation files (the "Software"), to deal in
	the Software without restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
	Software, and to permit persons to whom the Software is furnished to do so, subject
	to the following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
	PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
	OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ATEMA_RENDERER_BUFFER_HPP
#define ATEMA_RENDERER_BUFFER_HPP

#include <Atema/Renderer/Config.hpp>
#include <Atema/Core/NonCopyable.hpp>
#include <Atema/Core/Pointer.hpp>
#include <Atema/Renderer/Enums.hpp>

namespace at
{
	class ATEMA_RENDERER_API Buffer : public NonCopyable
	{
	public:
		struct Settings
		{
			BufferUsage usage = BufferUsage::Vertex;
			size_t byteSize = 0;
			bool mappable = false;
		};

		virtual ~Buffer();

		static Ptr<Buffer> create(const Settings& settings);

		// For transfer buffers only
		virtual void* map(size_t byteOffset = 0, size_t byteSize = 0) = 0;
		virtual void unmap() = 0;

	protected:
		Buffer();
	};
}

#endif
<|endoftext|>


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

#ifndef IE_CORE_TYPEDPARAMETER_INL
#define IE_CORE_TYPEDPARAMETER_INL

#include "boost/static_assert.hpp"

#include "IECore/TypedParameter.h"
#include "IECore/CompoundObject.h"

namespace IECore
{

/////////////////////////////////////////////////////////////////////////////////////
// constructor stuff
/////////////////////////////////////////////////////////////////////////////////////

template<typename T>
static Parameter::PresetsContainer convertPresets( const typename TypedParameter<T>::PresetsContainer &p )
{
	Parameter::PresetsContainer result;
	for( typename TypedParameter<T>::PresetsContainer::const_iterator it=p.begin(); it!=p.end(); it++ )
	{
		result.push_back( typename Parameter::PresetsContainer::value_type( it->first, new ObjectType( it->second ) ) );
	}
	return result;
}

template<typename T>
static Parameter::PresetsContainer convertPresets( const typename TypedParameter<T>::ObjectPresetsContainer &p )
{
	Parameter::PresetsContainer result;
	for( typename TypedParameter<T>::ObjectPresetsContainer::const_iterator it=p.begin(); it!=p.end(); it++ )
	{
		result.push_back( typename Parameter::PresetsContainer::value_type( it->first, it->second ) );
	}
	return result;
}

template<typename T>
TypedParameter<T>::TypedParameter( const std::string &name, const std::string &description, const T &defaultValue,
	const PresetsContainer &presets, bool presetsOnly, ConstCompoundObjectPtr userData )
	:	Parameter( name, description, new ObjectType( defaultValue ), convertPresets<T>( presets ), presetsOnly, userData )
{
}

template<typename T>
TypedParameter<T>::TypedParameter( const std::string &name, const std::string &description, ObjectTypePtr defaultValue,
	const ObjectPresetsContainer &presets, bool presetsOnly, ConstCompoundObjectPtr userData )
	:	Parameter( name, description, defaultValue, convertPresets<T>( presets ), presetsOnly, userData )
{
}

/////////////////////////////////////////////////////////////////////////////////////
// runtimetyped stuff
/////////////////////////////////////////////////////////////////////////////////////

template <class T>
TypeId TypedParameter<T>::typeId() const
{
	return staticTypeId();
}

template <class T>
TypeId TypedParameter<T>::staticTypeId()
{
	BOOST_STATIC_ASSERT( sizeof(T) == 0 ); // this function must be specialised for each type!
	return InvalidTypeId;
}

template <class T>
std::string TypedParameter<T>::typeName() const
{
	return staticTypeName();
}

template <class T>
std::string TypedParameter<T>::staticTypeName()
{
	BOOST_STATIC_ASSERT( sizeof(T) == 0 ); // this function must be specialised for each type!
	return "";
}

template<class T>
bool TypedParameter<T>::isInstanceOf( TypeId typeId ) const
{
	if( typeId==staticTypeId() )
	{
		return true;
	}
	return Parameter::isInstanceOf( typeId );
}

template<class T>
bool TypedParameter<T>::isInstanceOf( const std::string &typeName ) const
{
	if( typeName==staticTypeName() )
	{
		return true;
	}
	return Parameter::isInstanceOf( typeName );
}

template<class T>
bool TypedParameter<T>::inheritsFrom( TypeId typeId )
{
	return Parameter::staticTypeId()==typeId ? true : Parameter::inheritsFrom( typeId );
}

template<class T>
bool TypedParameter<T>::inheritsFrom( const std::string &typeName )
{
	return Parameter::staticTypeName()==typeName ? true : Parameter::inheritsFrom( typeName );
}

/////////////////////////////////////////////////////////////////////////////////////
// other stuff
/////////////////////////////////////////////////////////////////////////////////////

template<typename T>
bool TypedParameter<T>::valueValid( ConstObjectPtr value, std::string *reason ) const
{
	if( !Parameter::valueValid( value, reason ) )
	{
		return false;
	}
	ConstObjectTypePtr tValue = runTimeCast<const ObjectType>( value );
	if( !tValue )
	{
		if( reason )
		{
			*reason = std::string( "Value is not an instance of \"" ) + ObjectType::staticTypeName() + "\"";
		}
		return false;
	}
	return true;
}

template<typename T>
const typename TypedParameter<T>::ValueType &TypedParameter<T>::typedDefaultValue() const
{
	return boost::static_pointer_cast<const ObjectType>( defaultValue() )->readable();
}

template<typename T>
typename TypedParameter<T>::ValueType &TypedParameter<T>::getTypedValue()
{
	ConstObjectTypePtr tValue = runTimeCast<const ObjectType>( getValue() );
	if( !tValue )
	{
		throw Exception( std::string( "Value is not an instance of \"" ) + ObjectType::staticTypeName() + "\"");
	}
	return boost::static_pointer_cast<ObjectType>( getValue() )->writable();
}

template<typename T>
const typename TypedParameter<T>::ValueType &TypedParameter<T>::getTypedValue() const
{
	ConstObjectTypePtr tValue = runTimeCast<const ObjectType>( getValue() );
	if( !tValue )
	{
		throw Exception( std::string( "Value is not an instance of \"" ) + ObjectType::staticTypeName() + "\"");
	}
	return boost::static_pointer_cast<const ObjectType>( getValue() )->readable();
}

template<typename T>
void TypedParameter<T>::setTypedValue( const T &value )
{
	setValue( new ObjectType( value ) );
}

/////////////////////////////////////////////////////////////////////////////////////
// specialisation and template instantiation
/////////////////////////////////////////////////////////////////////////////////////

#define IE_CORE_DEFINETYPEDPARAMETERSPECIALISATION( T, TNAME )						\
																					\
	template<>																		\
	TypeId TypedParameter<T>::staticTypeId()										\
	{																				\
		return TNAME ## TypeId;														\
	}																				\
																					\
	template<>																		\
	std::string TypedParameter<T>::staticTypeName()									\
	{																				\
		return # TNAME;																\
	}																				\
																					\
	template class TypedParameter<T>;

}

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

#ifndef IE_CORE_TYPEDPARAMETER_INL
#define IE_CORE_TYPEDPARAMETER_INL

#include "boost/static_assert.hpp"

#include "IECore/TypedParameter.h"
#include "IECore/CompoundObject.h"

namespace IECore
{

/////////////////////////////////////////////////////////////////////////////////////
// constructor stuff
/////////////////////////////////////////////////////////////////////////////////////

template<typename T>
static Parameter::PresetsContainer convertPresets( const typename TypedParameter<T>::PresetsContainer &p )
{
	Parameter::PresetsContainer result;
	for( typename TypedParameter<T>::PresetsContainer::const_iterator it=p.begin(); it!=p.end(); it++ )
	{
		result.push_back( typename Parameter::PresetsContainer::value_type( it->first, new (typename TypedParameter<T>::ObjectType)( it->second ) ) );
	}
	return result;
}

template<typename T>
static Parameter::PresetsContainer convertPresets( const typename TypedParameter<T>::ObjectPresetsContainer &p )
{
	Parameter::PresetsContainer result;
	for( typename TypedParameter<T>::ObjectPresetsContainer::const_iterator it=p.begin(); it!=p.end(); it++ )
	{
		result.push_back( typename Parameter::PresetsContainer::value_type( it->first, it->second ) );
	}
	return result;
}

template<typename T>
TypedParameter<T>::TypedParameter( const std::string &name, const std::string &description, const T &defaultValue,
	const PresetsContainer &presets, bool presetsOnly, ConstCompoundObjectPtr userData )
	:	Parameter( name, description, new ObjectType( defaultValue ), convertPresets<T>( presets ), presetsOnly, userData )
{
}

template<typename T>
TypedParameter<T>::TypedParameter( const std::string &name, const std::string &description, ObjectTypePtr defaultValue,
	const ObjectPresetsContainer &presets, bool presetsOnly, ConstCompoundObjectPtr userData )
	:	Parameter( name, description, defaultValue, convertPresets<T>( presets ), presetsOnly, userData )
{
}

/////////////////////////////////////////////////////////////////////////////////////
// runtimetyped stuff
/////////////////////////////////////////////////////////////////////////////////////

template <class T>
TypeId TypedParameter<T>::typeId() const
{
	return staticTypeId();
}

template <class T>
TypeId TypedParameter<T>::staticTypeId()
{
	BOOST_STATIC_ASSERT( sizeof(T) == 0 ); // this function must be specialised for each type!
	return InvalidTypeId;
}

template <class T>
std::string TypedParameter<T>::typeName() const
{
	return staticTypeName();
}

template <class T>
std::string TypedParameter<T>::staticTypeName()
{
	BOOST_STATIC_ASSERT( sizeof(T) == 0 ); // this function must be specialised for each type!
	return "";
}

template<class T>
bool TypedParameter<T>::isInstanceOf( TypeId typeId ) const
{
	if( typeId==staticTypeId() )
	{
		return true;
	}
	return Parameter::isInstanceOf( typeId );
}

template<class T>
bool TypedParameter<T>::isInstanceOf( const std::string &typeName ) const
{
	if( typeName==staticTypeName() )
	{
		return true;
	}
	return Parameter::isInstanceOf( typeName );
}

template<class T>
bool TypedParameter<T>::inheritsFrom( TypeId typeId )
{
	return Parameter::staticTypeId()==typeId ? true : Parameter::inheritsFrom( typeId );
}

template<class T>
bool TypedParameter<T>::inheritsFrom( const std::string &typeName )
{
	return Parameter::staticTypeName()==typeName ? true : Parameter::inheritsFrom( typeName );
}

/////////////////////////////////////////////////////////////////////////////////////
// other stuff
/////////////////////////////////////////////////////////////////////////////////////

template<typename T>
bool TypedParameter<T>::valueValid( ConstObjectPtr value, std::string *reason ) const
{
	if( !Parameter::valueValid( value, reason ) )
	{
		return false;
	}
	ConstObjectTypePtr tValue = runTimeCast<const ObjectType>( value );
	if( !tValue )
	{
		if( reason )
		{
			*reason = std::string( "Value is not an instance of \"" ) + ObjectType::staticTypeName() + "\"";
		}
		return false;
	}
	return true;
}

template<typename T>
const typename TypedParameter<T>::ValueType &TypedParameter<T>::typedDefaultValue() const
{
	return boost::static_pointer_cast<const ObjectType>( defaultValue() )->readable();
}

template<typename T>
typename TypedParameter<T>::ValueType &TypedParameter<T>::getTypedValue()
{
	ConstObjectTypePtr tValue = runTimeCast<const ObjectType>( getValue() );
	if( !tValue )
	{
		throw Exception( std::string( "Value is not an instance of \"" ) + ObjectType::staticTypeName() + "\"");
	}
	return boost::static_pointer_cast<ObjectType>( getValue() )->writable();
}

template<typename T>
const typename TypedParameter<T>::ValueType &TypedParameter<T>::getTypedValue() const
{
	ConstObjectTypePtr tValue = runTimeCast<const ObjectType>( getValue() );
	if( !tValue )
	{
		throw Exception( std::string( "Value is not an instance of \"" ) + ObjectType::staticTypeName() + "\"");
	}
	return boost::static_pointer_cast<const ObjectType>( getValue() )->readable();
}

template<typename T>
void TypedParameter<T>::setTypedValue( const T &value )
{
	setValue( new ObjectType( value ) );
}

/////////////////////////////////////////////////////////////////////////////////////
// specialisation and template instantiation
/////////////////////////////////////////////////////////////////////////////////////

#define IE_CORE_DEFINETYPEDPARAMETERSPECIALISATION( T, TNAME )						\
																					\
	template<>																		\
	TypeId TypedParameter<T>::staticTypeId()										\
	{																				\
		return TNAME ## TypeId;														\
	}																				\
																					\
	template<>																		\
	std::string TypedParameter<T>::staticTypeName()									\
	{																				\
		return # TNAME;																\
	}																				\
																					\
	template class TypedParameter<T>;

}

#endif // IE_CORE_TYPEDPARAMETER_INL
<|endoftext|>


<commit_before>#ifndef BMI_HXX
#define BMI_HXX

namespace bmi {

  const int BMI_SUCCESS = 0;
  const int BMI_FAILURE = 1;

  const int MAX_COMPONENT_NAME = 2048;
  const int MAX_VAR_NAME = 2048;
  const int MAX_UNITS_NAME = 2048;
  const int MAX_TYPE_NAME = 2048;

  class Bmi {
    public:
      // Model control functions.
      virtual void Initialize(std::string config_file) = 0;
      virtual void Update() = 0;
      virtual void UpdateUntil(double time) = 0;
      virtual void Finalize() = 0;

      // Model information functions.
      virtual std::string GetComponentName() = 0;
      virtual int GetInputItemCount() = 0;
      virtual int GetOutputItemCount() = 0;
      virtual std::vector<std::string> GetInputVarNames() = 0;
      virtual std::vector<std::string> GetOutputVarNames() = 0;

      // Variable information functions
      virtual int GetVarGrid(std::string name) = 0;
      virtual std::string GetVarType(std::string name) = 0;
      virtual std::string GetVarUnits(std::string name) = 0;
      virtual int GetVarItemsize(std::string name) = 0;
      virtual int GetVarNbytes(std::string name) = 0;
      virtual std::string GetVarLocation(std::string name) = 0;

      virtual double GetCurrentTime() = 0;
      virtual double GetStartTime() = 0;
      virtual double GetEndTime() = 0;
      virtual std::string GetTimeUnits() = 0;
      virtual double GetTimeStep() = 0;

      // Variable getters
      virtual void GetValue(std::string name, void *dest) = 0;
      virtual void *GetValuePtr(std::string name) = 0;
      virtual void GetValueAtIndices(std::string name, void *dest, int *inds, int count) = 0;

      // Variable setters
      virtual void SetValue(std::string name, void *src) = 0;
      virtual void SetValueAtIndices(std::string name, int *inds, int count, void *src) = 0;

      // Grid information functions
      virtual int GetGridRank(const int grid) = 0;
      virtual int GetGridSize(const int grid) = 0;
      virtual std::string GetGridType(const int grid) = 0;

      virtual void GetGridShape(const int grid, int *shape) = 0;
      virtual void GetGridSpacing(const int grid, double *spacing) = 0;
      virtual void GetGridOrigin(const int grid, double *origin) = 0;

      virtual void GetGridX(const int grid, double *x) = 0;
      virtual void GetGridY(const int grid, double *y) = 0;
      virtual void GetGridZ(const int grid, double *z) = 0;

      virtual int GetGridNodeCount(const int grid) = 0;
      virtual int GetGridEdgeCount(const int grid) = 0;
      virtual int GetGridFaceCount(const int grid) = 0;

      virtual void GetGridEdgeNodes(const int grid, int *edge_nodes) = 0;
      virtual void GetGridFaceEdges(const int grid, int *face_edges) = 0;
      virtual void GetGridFaceNodes(const int grid, int *face_nodes) = 0;
      virtual void GetGridNodesPerFace(const int grid, int *nodes_per_face) = 0;
  };
}

#endif
<commit_msg>include vector.h<commit_after>#ifndef BMI_HXX
#define BMI_HXX

#include <vector>

namespace bmi {

  const int BMI_SUCCESS = 0;
  const int BMI_FAILURE = 1;

  const int MAX_COMPONENT_NAME = 2048;
  const int MAX_VAR_NAME = 2048;
  const int MAX_UNITS_NAME = 2048;
  const int MAX_TYPE_NAME = 2048;

  class Bmi {
    public:
      // Model control functions.
      virtual void Initialize(std::string config_file) = 0;
      virtual void Update() = 0;
      virtual void UpdateUntil(double time) = 0;
      virtual void Finalize() = 0;

      // Model information functions.
      virtual std::string GetComponentName() = 0;
      virtual int GetInputItemCount() = 0;
      virtual int GetOutputItemCount() = 0;
      virtual std::vector<std::string> GetInputVarNames() = 0;
      virtual std::vector<std::string> GetOutputVarNames() = 0;

      // Variable information functions
      virtual int GetVarGrid(std::string name) = 0;
      virtual std::string GetVarType(std::string name) = 0;
      virtual std::string GetVarUnits(std::string name) = 0;
      virtual int GetVarItemsize(std::string name) = 0;
      virtual int GetVarNbytes(std::string name) = 0;
      virtual std::string GetVarLocation(std::string name) = 0;

      virtual double GetCurrentTime() = 0;
      virtual double GetStartTime() = 0;
      virtual double GetEndTime() = 0;
      virtual std::string GetTimeUnits() = 0;
      virtual double GetTimeStep() = 0;

      // Variable getters
      virtual void GetValue(std::string name, void *dest) = 0;
      virtual void *GetValuePtr(std::string name) = 0;
      virtual void GetValueAtIndices(std::string name, void *dest, int *inds, int count) = 0;

      // Variable setters
      virtual void SetValue(std::string name, void *src) = 0;
      virtual void SetValueAtIndices(std::string name, int *inds, int count, void *src) = 0;

      // Grid information functions
      virtual int GetGridRank(const int grid) = 0;
      virtual int GetGridSize(const int grid) = 0;
      virtual std::string GetGridType(const int grid) = 0;

      virtual void GetGridShape(const int grid, int *shape) = 0;
      virtual void GetGridSpacing(const int grid, double *spacing) = 0;
      virtual void GetGridOrigin(const int grid, double *origin) = 0;

      virtual void GetGridX(const int grid, double *x) = 0;
      virtual void GetGridY(const int grid, double *y) = 0;
      virtual void GetGridZ(const int grid, double *z) = 0;

      virtual int GetGridNodeCount(const int grid) = 0;
      virtual int GetGridEdgeCount(const int grid) = 0;
      virtual int GetGridFaceCount(const int grid) = 0;

      virtual void GetGridEdgeNodes(const int grid, int *edge_nodes) = 0;
      virtual void GetGridFaceEdges(const int grid, int *face_edges) = 0;
      virtual void GetGridFaceNodes(const int grid, int *face_nodes) = 0;
      virtual void GetGridNodesPerFace(const int grid, int *nodes_per_face) = 0;
  };
}

#endif
<|endoftext|>


<commit_before><commit_msg>[MODIF] EndGame now instantly quits the application and does not send stats data<commit_after><|endoftext|>


<commit_before>#ifndef CAFFE_CUDA_TIMER_HPP_
#define CAFFE_CUDA_TIMER_HPP_

#include "caffe/common.hpp"

namespace caffe {

class CudaTimer {

protected:
  cudaEvent_t start;
  cudaEvent_t stop;
  bool on;

public:
  CudaTimer() : on(false) {
    CUDA_CHECK(cudaEventCreate(&start));
    CUDA_CHECK(cudaEventCreate(&stop));
  }
  ~CudaTimer() {
    CUDA_CHECK(cudaEventDestroy(start));
    CUDA_CHECK(cudaEventDestroy(stop));
  }

  void Tic() {
    CUDA_CHECK(cudaEventRecord(start, 0));
    on = true;
  }

  float Toc() {
    float time;
    CHECK(on) << "Tic before Toc";
    CUDA_CHECK(cudaEventRecord(stop, 0));
    CUDA_CHECK(cudaEventSynchronize(start));
    CUDA_CHECK(cudaEventSynchronize(stop));
    CUDA_CHECK(cudaEventElapsedTime(&time, start, stop));
    on = false;
    return time;
  }
};

}  // namespace caffe

#endif // CAFFE_CUDA_TIMER_HPP_
<commit_msg>remove cuda_timer as is no longer needed<commit_after><|endoftext|>


<commit_before>/*
    Copyright 2011 Joe Hermaszewski. All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, are
    permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this list of
    conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright notice, this list
    of conditions and the following disclaimer in the documentation and/or other materials
    provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY Joe Hermaszewski "AS IS" AND ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Joe Hermaszewski OR
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    The views and conclusions contained in the software and documentation are those of the
    authors and should not be interpreted as representing official policies, either expressed
    or implied, of Joe Hermaszewski.
*/

#pragma once

#include <type_traits>
#include <joemath/config.hpp>

namespace NJoeMath
{
    template <typename Scalar, u32 Rows, u32 Columns>
    class CMatrix;

    template <typename T>
    struct is_matrix
    : public std::false_type
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_matrix <CMatrix<Scalar, Rows, Columns>>
    : public std::true_type
    { };

    template <typename T>
    struct is_square
    : public std::false_type
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_square <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<bool, Rows == Columns>
    { };

    template <typename T>
    struct is_vector
    : public std::false_type
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_vector <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<bool, (Rows == 1) || (Columns == 1)>
    { };

    template <typename T>
    struct is_vector3
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_vector3 <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<bool, is_vector<CMatrix<Scalar, Rows, Columns>>::value && ((Rows == 3) || (Columns == 3))>
    { };

    template <typename T>
    struct vector_size
    { };

    template<typename Scalar, u32 Rows, u32 Columns>
    struct vector_size <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<u32,  (Rows > Columns) ? Rows : Columns>
    { };
};
<commit_msg>[+] Added square matrix size check, and made is_vector3 return false by default<commit_after>/*
    Copyright 2011 Joe Hermaszewski. All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, are
    permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this list of
    conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright notice, this list
    of conditions and the following disclaimer in the documentation and/or other materials
    provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY Joe Hermaszewski "AS IS" AND ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Joe Hermaszewski OR
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    The views and conclusions contained in the software and documentation are those of the
    authors and should not be interpreted as representing official policies, either expressed
    or implied, of Joe Hermaszewski.
*/

#pragma once

#include <type_traits>
#include <joemath/config.hpp>

namespace NJoeMath
{
    template <typename Scalar, u32 Rows, u32 Columns>
    class CMatrix;

    template <typename T>
    struct is_matrix
    : public std::false_type
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_matrix <CMatrix<Scalar, Rows, Columns>>
    : public std::true_type
    { };

    template <typename T>
    struct is_square
    : public std::false_type
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_square <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<bool, Rows == Columns>
    { };

    template <typename T>
    struct square_matrix_size
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct square_matrix_size <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<u32, Rows>
    { };

    template <typename T>
    struct is_vector
    : public std::false_type
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_vector <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<bool, (Rows == 1) || (Columns == 1)>
    { };

    template <typename T>
    struct is_vector3
    : public std::false_type
    { };

    template <typename Scalar, u32 Rows, u32 Columns>
    struct is_vector3 <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<bool, is_vector<CMatrix<Scalar, Rows, Columns>>::value && ((Rows == 3) || (Columns == 3))>
    { };

    template <typename T>
    struct vector_size
    { };

    template<typename Scalar, u32 Rows, u32 Columns>
    struct vector_size <CMatrix<Scalar, Rows, Columns>>
    : public std::integral_constant<u32,  (Rows > Columns) ? Rows : Columns>
    { };
};
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
#ifndef MAPNIK_TEXT_LINE_HPP
#define MAPNIK_TEXT_LINE_HPP

//stl
#include <vector>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/config.hpp>

namespace mapnik
{

struct glyph_info;

// This class stores all glyphs of a line in left to right order.
// It can be used for rendering but no text processing (like line breaking)
// should be done!

class MAPNIK_DECL text_line : util::noncopyable
{
public:
    using glyph_vector = std::vector<glyph_info>;
    using const_iterator = glyph_vector::const_iterator;

    text_line(unsigned first_char, unsigned last_char);

    text_line( text_line && rhs);

    // Append glyph.
    void add_glyph(glyph_info && glyph, double scale_factor_);

    // Preallocate memory.
    void reserve(glyph_vector::size_type length);
    // Iterator to first glyph.
    const_iterator begin() const;
    // Iterator beyond last glyph.
    const_iterator end() const;

    // Width of all glyphs including character spacing.
    double width() const { return width_; }
    // Width of all glyphs without character spacing.
    double glyphs_width() const { return glyphs_width_; }
    // Real line height. For first line: max_char_height(), for all others: line_height().
    double height() const;

    // Height of the tallest glyph in this line.
    double max_char_height() const { return max_char_height_; }

    // Called for each font/style to update the maximum height of this line.
    void update_max_char_height(double max_char_height);

    // Line height including line spacing.
    double line_height() const { return line_height_; }

    // Is this object is the first line of a multi-line text?
    // Used to exclude linespacing from first line's height.
    void set_first_line(bool first_line);

    // Index of first UTF-16 char.
    unsigned first_char() const;
    // Index of last UTF-16 char.
    unsigned last_char() const;

    // Number of glyphs.
    unsigned size() const;

    unsigned space_count() const { return space_count_; }

private:
    glyph_vector glyphs_;
    double line_height_; // Includes line spacing (returned by freetype)
    double max_char_height_; // Max height of any glyphs in line - calculated by shaper
    double width_;
    double glyphs_width_;
    unsigned first_char_;
    unsigned last_char_;
    bool first_line_;
    unsigned space_count_;
};

} //namespace mapnik

#endif // MAPNIK_TEXT_LINE_HPP
<commit_msg>don't forward declare glyph_info in text_line.hpp<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
#ifndef MAPNIK_TEXT_LINE_HPP
#define MAPNIK_TEXT_LINE_HPP

//stl
#include <vector>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/config.hpp>
#include <mapnik/text/glyph_info.hpp>

namespace mapnik
{

// This class stores all glyphs of a line in left to right order.
// It can be used for rendering but no text processing (like line breaking)
// should be done!

class MAPNIK_DECL text_line : util::noncopyable
{
public:
    using glyph_vector = std::vector<glyph_info>;
    using const_iterator = glyph_vector::const_iterator;

    text_line(unsigned first_char, unsigned last_char);

    text_line( text_line && rhs);

    // Append glyph.
    void add_glyph(glyph_info && glyph, double scale_factor_);

    // Preallocate memory.
    void reserve(glyph_vector::size_type length);
    // Iterator to first glyph.
    const_iterator begin() const;
    // Iterator beyond last glyph.
    const_iterator end() const;

    // Width of all glyphs including character spacing.
    double width() const { return width_; }
    // Width of all glyphs without character spacing.
    double glyphs_width() const { return glyphs_width_; }
    // Real line height. For first line: max_char_height(), for all others: line_height().
    double height() const;

    // Height of the tallest glyph in this line.
    double max_char_height() const { return max_char_height_; }

    // Called for each font/style to update the maximum height of this line.
    void update_max_char_height(double max_char_height);

    // Line height including line spacing.
    double line_height() const { return line_height_; }

    // Is this object is the first line of a multi-line text?
    // Used to exclude linespacing from first line's height.
    void set_first_line(bool first_line);

    // Index of first UTF-16 char.
    unsigned first_char() const;
    // Index of last UTF-16 char.
    unsigned last_char() const;

    // Number of glyphs.
    unsigned size() const;

    unsigned space_count() const { return space_count_; }

private:
    glyph_vector glyphs_;
    double line_height_; // Includes line spacing (returned by freetype)
    double max_char_height_; // Max height of any glyphs in line - calculated by shaper
    double width_;
    double glyphs_width_;
    unsigned first_char_;
    unsigned last_char_;
    bool first_line_;
    unsigned space_count_;
};

} // namespace mapnik

#endif // MAPNIK_TEXT_LINE_HPP
<|endoftext|>


<commit_before>#pragma once

#include <distributions/special.hpp>
#include <distributions/random.hpp>
#include <distributions/random_fwd.hpp>

#include <vector>

namespace microscopes{
namespace hmm{

	distributions::rng_t rng;

	// A class for a vector of vectors, useful for representing pretty much everything we need for the beam sampler.
	// For instance, time series data can be stored as a vector of vectors, where each vector is one time series.
	// The transition matrix can also be stored as a vector of vectors, where each transition probability is one vector.
	template <typename T>
	class meta_vector {
	public:

		meta_vector(): data_() {}

		meta_vector(std::vector<size_t> size) : data_(size.size()) {
			for (int i = 0; i < data_.size(); i++) {
				data_[i] = std::vector<T>(size[i]);
			}
		}

		std::vector<T>& operator[](size_t i) {
			return data_[i];
		}

		std::vector<size_t> size() {
			std::vector<size_t> sizes(data_.size());
			for (std::vector<T> vec: data_) {
				sizes.push_back(vec.size());
			}
			return sizes;
		}

		T sum(size_t i) { // useful for resampling m, the number of tables serving a dish
			T result = (T)0;
			for(T t: data_[i]) {
				result += t;
			}
			return result;
		}
	protected:
		std::vector<std::vector<T> > data_;
	};

// Implementation of the beam sampler for the HDP-HMM, following van Gael 2008
	template <int N>
	class hmm {
	public:
		hmm(float gamma, float alpha0, float *H, meta_vector<size_t> data):
			gamma_(gamma),
			alpha0_(alpha0),
			H_(H),
			data_(data),
			u_(data.size())
		{}
	protected:

		// parameters
		const meta_vector<size_t> data_; // XXX: For now, the observation type is just a vector of vectors of ints. Later we can switch over to using recarrays
		meta_vector<size_t> s_; // the state sequence
		meta_vector<float> u_; // the slice sampling parameter for each time step in the series
		meta_vector<float> pi_; // the observed portion of the infinite transition matrix
		std::vector<float> beta_; // the stick lengths for the top-level DP draw

		// hyperparameters
		const float gamma_;
		const float alpha0_;
		const float H_[N]; // hyperparameters for a Dirichlet prior over observations. Will generalize this to other observation models later.

		// sampling functions. later we can integrate these into microscopes::kernels where appropriate.
		void sample_s() {}

		void sample_u() {
			size_t prev_state;
			std::uniform_real_distribution<float> sampler (0.0, 1.0);
			std::vector<size_t> sizes = u_.size();
			for (int i = 0; i < sizes.size(); i++) {
				for(int j = 0; j < sizes[i]; j++) {
					if (j == 0) {
						prev_state = 0;
					} else {
						prev_state = s_[i][j-1];
					}
					u_[i][j] = sampler(rng) / (pi_[prev_state][s_[i][j]]); // scale the uniform sample to be between 0 and pi_{s_{t-1}s_t}
				}
			}
		}

		void sample_pi() {}

		void sample_beta() {}
	};

} // namespace hmm
} // namespace microscopes<commit_msg>Changed indent from tab to two spaces<commit_after>#pragma once

#include <distributions/special.hpp>
#include <distributions/random.hpp>
#include <distributions/random_fwd.hpp>

#include <vector>

namespace microscopes{
namespace hmm{

	distributions::rng_t rng;

	// A class for a vector of vectors, useful for representing pretty much everything we need for the beam sampler.
	// For instance, time series data can be stored as a vector of vectors, where each vector is one time series.
	// The transition matrix can also be stored as a vector of vectors, where each transition probability is one vector.
	template <typename T>
	class meta_vector {
	public:

		meta_vector(): data_() {}

		meta_vector(std::vector<size_t> size) : data_(size.size()) {
			for (int i = 0; i < data_.size(); i++) {
				data_[i] = std::vector<T>(size[i]);
			}
		}

		std::vector<T>& operator[](size_t i) {
			return data_[i];
		}

		std::vector<size_t> size() {
			std::vector<size_t> sizes(data_.size());
			for (std::vector<T> vec: data_) {
				sizes.push_back(vec.size());
			}
			return sizes;
		}

		T sum(size_t i) { // useful for resampling m, the number of tables serving a dish
			T result = (T)0;
			for(T t: data_[i]) {
				result += t;
			}
			return result;
		}
	protected:
		std::vector<std::vector<T> > data_;
	};

// Implementation of the beam sampler for the HDP-HMM, following van Gael 2008
	template <int N>
	class hmm {
	public:
		hmm(float gamma, float alpha0, float *H, meta_vector<size_t> data):
			gamma_(gamma),
			alpha0_(alpha0),
			H_(H),
			data_(data),
			u_(data.size())
		{}
	protected:

		// parameters
		const meta_vector<size_t> data_; // XXX: For now, the observation type is just a vector of vectors of ints. Later we can switch over to using recarrays
		meta_vector<size_t> s_; // the state sequence
		meta_vector<float> u_; // the slice sampling parameter for each time step in the series
		meta_vector<float> pi_; // the observed portion of the infinite transition matrix
		std::vector<float> beta_; // the stick lengths for the top-level DP draw

		// hyperparameters
		const float gamma_;
		const float alpha0_;
		const float H_[N]; // hyperparameters for a Dirichlet prior over observations. Will generalize this to other observation models later.

		// sampling functions. later we can integrate these into microscopes::kernels where appropriate.
		void sample_s() {}

		void sample_u() {
			size_t prev_state;
			std::uniform_real_distribution<float> sampler (0.0, 1.0);
			std::vector<size_t> sizes = u_.size();
			for (int i = 0; i < sizes.size(); i++) {
				for(int j = 0; j < sizes[i]; j++) {
					if (j == 0) {
						prev_state = 0;
					} else {
						prev_state = s_[i][j-1];
					}
					u_[i][j] = sampler(rng) / (pi_[prev_state][s_[i][j]]); // scale the uniform sample to be between 0 and pi_{s_{t-1}s_t}
				}
			}
		}

		void sample_pi() {}

		void sample_beta() {}
	};

} // namespace hmm
} // namespace microscopes<|endoftext|>


<commit_before>#ifndef TOOLBOX_MARSHALL_JSON_HPP
#define TOOLBOX_MARSHALL_JSON_HPP

#include <json/json.hpp>
#include <toolbox/marshall/record.hpp>

namespace toolbox
{
namespace marshall
{
namespace json
{

namespace detail
{
struct json_serializer
{
    nlohmann::json j;
    nlohmann::json *current;
    nlohmann::json *previous;

    json_serializer() :
        j {},
        current {&j}
    {}

    json_serializer(const json_serializer &) = delete;
    void operator=(const json_serializer &) = delete;

    template<typename T> void enter(T &t)
    {
        previous = current;
        current = &(*current)[t.description.short_name];
    }

    template<typename T> void leave(T &t)
    {
        current = previous;
    }

    template<typename T>
    typename std::enable_if<std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        static_assert(std::rank<typename T::type>::value == 1, "can only serialize 1-dimensional array");

        auto arr = nlohmann::json::array();

        for (const auto &e : t.value)
            arr.push_back(e);

        (*current)[t.description.short_name] = arr;
    }

    template<typename T>
    typename std::enable_if<!std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        (*current)[t.description.short_name] = t.value;
    }
};

struct json_deserializer
{
    nlohmann::json &j;
    nlohmann::json *current;
    nlohmann::json *previous;

    json_deserializer(nlohmann::json &j) : j(j), current(&j) {}

    template<typename T> void enter(T &t)
    {
        previous = current;
        current = &(*current)[t.description.short_name];
    }

    template<typename T> void leave(T &t)
    {
        current = previous;
    }

    template<typename T>
    typename std::enable_if<std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        using array_type = typename T::type;
        using value_type = typename std::remove_extent<array_type>::type;

        static_assert(std::rank<typename T::type>::value == 1, "can only deserialize 1-dimensional array");

        for (auto i = 0u; i < std::extent<typename T::type>::value; i ++)
            t.value[i] = (*current)[t.description.short_name][i].template get<value_type>();
    }

    template<typename T>
    typename std::enable_if<!std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        t.value = (*current)[t.description.short_name];
    }

};

} // namespace detail

template<typename T>
nlohmann::json serialize(T& record)
{
    detail::json_serializer visitor{};
    record.visit(visitor);
    return visitor.j;
}

template<typename T>
void deserialize(nlohmann::json &j, T &record)
{
    detail::json_deserializer visitor {j};
    record.visit(visitor);
}

} // namespace json
} // namespace marshall
} // namespace toolbox

#endif // TOOLBOX_MARSHALL_JSON_HPP
<commit_msg>remove unused parameters<commit_after>#ifndef TOOLBOX_MARSHALL_JSON_HPP
#define TOOLBOX_MARSHALL_JSON_HPP

#include <json/json.hpp>
#include <toolbox/marshall/record.hpp>

namespace toolbox
{
namespace marshall
{
namespace json
{

namespace detail
{
struct json_serializer
{
    nlohmann::json j;
    nlohmann::json *current;
    nlohmann::json *previous;

    json_serializer() :
        j {},
        current {&j}
    {}

    json_serializer(const json_serializer &) = delete;
    void operator=(const json_serializer &) = delete;

    template<typename T> void enter(T &t)
    {
        previous = current;
        current = &(*current)[t.description.short_name];
    }

    template<typename T> void leave(T &)
    {
        current = previous;
    }

    template<typename T>
    typename std::enable_if<std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        static_assert(std::rank<typename T::type>::value == 1, "can only serialize 1-dimensional array");

        auto arr = nlohmann::json::array();

        for (const auto &e : t.value)
            arr.push_back(e);

        (*current)[t.description.short_name] = arr;
    }

    template<typename T>
    typename std::enable_if<!std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        (*current)[t.description.short_name] = t.value;
    }
};

struct json_deserializer
{
    nlohmann::json &j;
    nlohmann::json *current;
    nlohmann::json *previous;

    json_deserializer(nlohmann::json &j) : j(j), current(&j) {}

    template<typename T> void enter(T &t)
    {
        previous = current;
        current = &(*current)[t.description.short_name];
    }

    template<typename T> void leave(T &)
    {
        current = previous;
    }

    template<typename T>
    typename std::enable_if<std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        using array_type = typename T::type;
        using value_type = typename std::remove_extent<array_type>::type;

        static_assert(std::rank<typename T::type>::value == 1, "can only deserialize 1-dimensional array");

        for (auto i = 0u; i < std::extent<typename T::type>::value; i ++)
            t.value[i] = (*current)[t.description.short_name][i].template get<value_type>();
    }

    template<typename T>
    typename std::enable_if<!std::is_array<typename T::type>::value>::type
    visit(T &t)
    {
        t.value = (*current)[t.description.short_name];
    }

};

} // namespace detail

template<typename T>
nlohmann::json serialize(T& record)
{
    detail::json_serializer visitor{};
    record.visit(visitor);
    return visitor.j;
}

template<typename T>
void deserialize(nlohmann::json &j, T &record)
{
    detail::json_deserializer visitor {j};
    record.visit(visitor);
}

} // namespace json
} // namespace marshall
} // namespace toolbox

#endif // TOOLBOX_MARSHALL_JSON_HPP
<|endoftext|>


<commit_before>#pragma once

#include <assert.h>
#include <type_traits>

#include <tudocomp/ds/TextDSFlags.hpp>
#include <tudocomp/ds/CompressMode.hpp>
#include <tudocomp/ds/ArrayDS.hpp>

#include <tudocomp_stat/StatPhase.hpp>

namespace tdc {

/// Constructs the inverse suffix array using the suffix array.
template<typename sa_t>
class SparseISA : public Algorithm {
public:
    using iv_t = DynamicIntVector;
    using data_type = iv_t;

private:
    static inline size_t rank1(const BitVector& bv, size_t j) {
        //TODO: naive!
        size_t rank = 0;
        for(size_t i = 0; i < j; i++) {
            if(bv[i]) ++rank;
        }
        return rank;
    }

    const sa_t* m_sa;

    BitVector m_has_shortcut;
    iv_t m_shortcuts;

public:
    inline static Meta meta() {
        Meta m("isa", "sparse_isa");
        m.option("sa").templated<sa_t>("sa");
        m.option("t").dynamic(3);
        return m;
    }

    inline static ds::InputRestrictions restrictions() {
        return ds::InputRestrictions {};
    }

    template<typename textds_t>
    inline SparseISA(Env&& env, textds_t& tds, CompressMode cm)
            : Algorithm(std::move(env)) {

        // Suffix Array types must match
        static_assert(std::is_same<sa_t, typename textds_t::sa_type>(),
            "Suffix Array type mismatch!");

        // Require Suffix Array
        m_sa = &tds.require_sa(cm);

        const size_t n = m_sa->size();
        m_has_shortcut = BitVector(n);

        const size_t t = this->env().option("t").as_integer();

        // Construct
        {
            auto v = BitVector(n);
            for(size_t i = 0; i < n; i++) {
                if(!v[i]) {
                    // new cycle
                    v[i] = 1;
                    size_t j = (*m_sa)[i];
                    size_t k = 1;

                    while(j != i) {
                        if((k % t) == 0) {
                            m_has_shortcut[j] = 1;
                        }

                        v[j] = 1;
                        j = (*m_sa)[j];
                        ++k;
                    }

                    if(k > t) m_has_shortcut[i] = 1;
                }
            }

            m_shortcuts = DynamicIntVector(rank1(m_has_shortcut, n), 0, bits_for(n));
            for(size_t i = 0; i < n; i++) {
                if(v[i]) {
                    v[i] = 0;
                    size_t j = (*m_sa)[i];
                    while(v[j]) {
                        if(m_has_shortcut[j]) {
                            m_shortcuts[rank1(m_has_shortcut, j)] = i;
                            i = j;
                        }
                        v[j] = 0;
                        j = (*m_sa)[j];
                    }

                    if(m_has_shortcut[j]) {
                        m_shortcuts[rank1(m_has_shortcut, j)] = i;
                    }

                    i = j;
                }
            }
        }
    }

public:
    inline size_t operator[](size_t i) const {
        size_t j = i;
        bool s = true;

        while((*m_sa)[j] != i) {
            if(s && m_has_shortcut[j]) {
                j = m_shortcuts[rank1(m_has_shortcut, j)];
                s = false;
            } else {
                j = (*m_sa)[j];
            }
        }
        return j;
    }

    inline void compress() {
        // nothing to do, already sparse :-)
    }

    inline size_t size() const {
        return m_has_shortcut.size();
    }

    /// \brief Forces the data structure to relinquish its data storage.
    ///
    /// This is done by moving the ownership of the storage to the caller.
    /// After this operation, the data structure will behave as if it was
    /// empty, and may throw debug assertions on access.
    inline iv_t relinquish() {
        throw std::runtime_error("not supported"); //TODO: what to do?
    }

    /// \brief Creates a copy of the data structure's storage.
    inline iv_t copy() const {
        throw std::runtime_error("not supported"); //TODO: what to do?
    }
};

} //ns
<commit_msg>Use Rank data structure in Sparse ISA<commit_after>#pragma once

#include <assert.h>
#include <type_traits>

#include <tudocomp/ds/TextDSFlags.hpp>
#include <tudocomp/ds/CompressMode.hpp>
#include <tudocomp/ds/rank/Rank.hpp>

#include <tudocomp_stat/StatPhase.hpp>

namespace tdc {

/// Constructs the inverse suffix array using the suffix array.
template<typename sa_t>
class SparseISA : public Algorithm {
public:
    using iv_t = DynamicIntVector;
    using data_type = iv_t;

private:
    const sa_t* m_sa;

    BitVector m_has_shortcut;
    Rank      m_rank;

    iv_t m_shortcuts;

public:
    inline static Meta meta() {
        Meta m("isa", "sparse_isa");
        m.option("sa").templated<sa_t>("sa");
        m.option("t").dynamic(3);
        return m;
    }

    inline static ds::InputRestrictions restrictions() {
        return ds::InputRestrictions {};
    }

    template<typename textds_t>
    inline SparseISA(Env&& env, textds_t& tds, CompressMode cm)
            : Algorithm(std::move(env)) {

        // Suffix Array types must match
        static_assert(std::is_same<sa_t, typename textds_t::sa_type>(),
            "Suffix Array type mismatch!");

        // Require Suffix Array
        m_sa = &tds.require_sa(cm);

        const size_t n = m_sa->size();
        m_has_shortcut = BitVector(n);

        const size_t t = this->env().option("t").as_integer();

        // Construct
        {
            auto v = BitVector(n);
            for(size_t i = 0; i < n; i++) {
                if(!v[i]) {
                    // new cycle
                    v[i] = 1;
                    size_t j = (*m_sa)[i];
                    size_t k = 1;

                    while(j != i) {
                        if((k % t) == 0) {
                            m_has_shortcut[j] = 1;
                        }

                        v[j] = 1;
                        j = (*m_sa)[j];
                        ++k;
                    }

                    if(k > t) m_has_shortcut[i] = 1;
                }
            }

            m_rank = Rank(m_has_shortcut);
            m_shortcuts = DynamicIntVector(m_rank(n-1), 0, bits_for(n));

            for(size_t i = 0; i < n; i++) {
                if(v[i]) {
                    v[i] = 0;
                    size_t j = (*m_sa)[i];
                    while(v[j]) {
                        if(m_has_shortcut[j]) {
                            m_shortcuts[m_rank(j)-1] = i;
                            i = j;
                        }
                        v[j] = 0;
                        j = (*m_sa)[j];
                    }

                    if(m_has_shortcut[j]) {
                        m_shortcuts[m_rank(j)-1] = i;
                    }

                    i = j;
                }
            }
        }
    }

public:
    inline size_t operator[](size_t i) const {
        size_t j = i;
        bool s = true;

        while((*m_sa)[j] != i) {
            if(s && m_has_shortcut[j]) {
                j = m_shortcuts[m_rank(j)-1];
                s = false;
            } else {
                j = (*m_sa)[j];
            }
        }
        return j;
    }

    inline void compress() {
        // nothing to do, already sparse :-)
    }

    inline size_t size() const {
        return m_has_shortcut.size();
    }

    /// \brief Forces the data structure to relinquish its data storage.
    ///
    /// This is done by moving the ownership of the storage to the caller.
    /// After this operation, the data structure will behave as if it was
    /// empty, and may throw debug assertions on access.
    inline iv_t relinquish() {
        throw std::runtime_error("not supported"); //TODO: what to do?
    }

    /// \brief Creates a copy of the data structure's storage.
    inline iv_t copy() const {
        throw std::runtime_error("not supported"); //TODO: what to do?
    }
};

} //ns
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(n)

class Solution {
public:
    int rotatedDigits(int N) {
        enum State { INVALID, SAME, DIFF };
        vector<State> dp(N + 1);
        unordered_set<int> same = {0, 1, 8};
        unordered_set<int> diff = {2, 5, 6, 9};
        for (int i = 0; 10 * i <= N; ++i) {
            if (i == 0 ||
                dp[i] != INVALID) {
                for (const auto& j : same) {
                    if (i * 10 + j <= N) {
                        dp[i * 10 + j] = max(SAME, dp[i]);
                    }
                }
                for (const auto& j : diff) {
                    if (i * 10 + j <= N) {
                        dp[i * 10 + j] = DIFF;
                    }
                }
            }
        }
        return count(dp.cbegin(), dp.cend(), DIFF);
    }

};

// Time:  O(nlogn) = O(n), because O(logn) = O(32) by this input
// Space: O(logn) = O(1)
class Solution2 {
public:
    int rotatedDigits(int N) {
        int result = 0;
        for (int i = 0; i <= N; ++i){
            string s(to_string(i));
            unordered_set<char> lookup(s.begin(),s.end());
            if (lookup.count('3') ||
                lookup.count('4') ||
                lookup.count('7')) {
                continue;
            }
            if (lookup.count('2') ||
                lookup.count('5') ||
                lookup.count('6') ||
                lookup.count('9')) {
                ++result;
            }
        }
        return result;
    }
};
<commit_msg>Update rotated-digits.cpp<commit_after>// Time:  O(n)
// Space: O(n)

class Solution {
public:
    int rotatedDigits(int N) {
        enum State { INVALID, SAME, DIFF };
        vector<State> dp(N + 1);
        unordered_set<int> same = {0, 1, 8};
        unordered_set<int> diff = {2, 5, 6, 9};
        dp[0] = SAME;
        for (int i = 0; 10 * i <= N; ++i) {
            if (dp[i] != INVALID) {
                for (const auto& j : same) {
                    if (i * 10 + j <= N) {
                        dp[i * 10 + j] = max(SAME, dp[i]);
                    }
                }
                for (const auto& j : diff) {
                    if (i * 10 + j <= N) {
                        dp[i * 10 + j] = DIFF;
                    }
                }
            }
        }
        return count(dp.cbegin(), dp.cend(), DIFF);
    }

};

// Time:  O(nlogn) = O(n), because O(logn) = O(32) by this input
// Space: O(logn) = O(1)
class Solution2 {
public:
    int rotatedDigits(int N) {
        int result = 0;
        for (int i = 0; i <= N; ++i){
            string s(to_string(i));
            unordered_set<char> lookup(s.begin(),s.end());
            if (lookup.count('3') ||
                lookup.count('4') ||
                lookup.count('7')) {
                continue;
            }
            if (lookup.count('2') ||
                lookup.count('5') ||
                lookup.count('6') ||
                lookup.count('9')) {
                ++result;
            }
        }
        return result;
    }
};
<|endoftext|>


<commit_before>
#include "can_simple.hpp"
#include "odrive_main.h"

void CANSimple::handle_can_message(CAN_message_t& msg) {
    // This functional way of handling the messages is neat and is much cleaner from
    // a data security point of view, but it will require some tweaking to fix the syntax.
    //
    // auto func = callback_map.find(msg.id);
    // if(func != callback_map.end()){
    //     func->second(msg);
    // }

    //     Frame
    // nodeID | CMD
    // 4 bits | 7 bits
    auto nodeID = (msg.id >> 7 & 0x15);
    Axis* axis = nullptr;

    for (uint8_t i = 0; i < AXIS_COUNT; i++) {
        if (axes[i]->config_.can_node_id == nodeID) {
            axis = axes[i];
        }
    }
    if (axis != nullptr) {
        switch (msg.id & 0x7F) {
            case 0x010:
                move_to_pos_callback(axis, msg);
                break;
            case 0x011:
                set_pos_setpoint_callback(axis, msg);
                break;
            case 0x012:
                set_vel_setpoint_callback(axis, msg);
                break;
            case 0x013:
                set_current_setpoint_callback(axis, msg);
                break;
        }
    }
}

void CANSimple::estop_callback(){
    for(Axis* axis : axes){
        axis->error_ |= Axis::ERROR_ESTOP_REQUESTED;
    }
}

void CANSimple::move_to_pos_callback(Axis* axis, CAN_message_t& msg) {
    float pos = msg.buf[0];
    pos += msg.buf[1] << 8;
    pos += msg.buf[2] << 16;
    pos += msg.buf[3] << 24;

    axis->controller_.move_to_pos(pos);
}

void CANSimple::set_pos_setpoint_callback(Axis* axis, CAN_message_t& msg) {
    float pos = msg.buf[0];
    pos += msg.buf[1] << 8;
    pos += msg.buf[2] << 16;
    pos += msg.buf[3] << 24;

    float vel = msg.buf[4];
    vel += msg.buf[5] << 8;
    vel *= 0.1f;  // Factor of 10

    float current = msg.buf[6];
    current += (msg.buf[7] << 8);
    current *= 0.01f;  // Factor of 100

    axis->controller_.set_pos_setpoint(pos, vel, current);
}

void CANSimple::set_vel_setpoint_callback(Axis* axis, CAN_message_t& msg) {
    float vel = msg.buf[0];
    vel += msg.buf[1] << 8;
    vel += msg.buf[2] << 16;
    vel += msg.buf[3] << 24;
    vel *= 0.01f;

    float current = msg.buf[4];
    current += msg.buf[5] << 8;
    current += msg.buf[6] << 16;
    current += msg.buf[7] << 24;
    current *= 0.01f;

    axis->controller_.set_vel_setpoint(vel, current);
}

void CANSimple::set_current_setpoint_callback(Axis* axis, CAN_message_t& msg) {
    float current = msg.buf[0];
    current += msg.buf[1] << 8;
    current += msg.buf[2] << 16;
    current += msg.buf[3] << 24;
    current *= 0.01f;

    axis->controller_.set_current_setpoint(current);
}

void CANSimple::send_heartbeat(Axis* axis){
    CAN_message_t txmsg;
    txmsg.id = axis->config_.can_node_id << 7;
    txmsg.id += 0x1;
    txmsg.isExt = false;
    txmsg.len = 8;

    // Axis errors in 1st 32-bit value
    txmsg.buf[0] = axis->error_;
    txmsg.buf[1] = axis->error_ >> 8;
    txmsg.buf[2] = axis->error_ >> 16;
    txmsg.buf[3] = axis->error_ >> 24;

    // Current state of axis in 2nd 32-bit value
    txmsg.buf[4] = axis->current_state_;
    txmsg.buf[5] = axis->current_state_ >> 8;
    txmsg.buf[6] = axis->current_state_ >> 16;
    txmsg.buf[7] = axis->current_state_ >> 24;
}<commit_msg>Change message IDs so they don't collide with test messages<commit_after>
#include "can_simple.hpp"
#include "odrive_main.h"

void CANSimple::handle_can_message(CAN_message_t& msg) {
    // This functional way of handling the messages is neat and is much cleaner from
    // a data security point of view, but it will require some tweaking to fix the syntax.
    //
    // auto func = callback_map.find(msg.id);
    // if(func != callback_map.end()){
    //     func->second(msg);
    // }

    //     Frame
    // nodeID | CMD
    // 4 bits | 7 bits
    auto nodeID = (msg.id >> 7 & 0x15);
    Axis* axis = nullptr;

    for (uint8_t i = 0; i < AXIS_COUNT; i++) {
        if (axes[i]->config_.can_node_id == nodeID) {
            axis = axes[i];
        }
    }
    if (axis != nullptr) {
        switch (msg.id & 0x7F) {
            case 0x020:
                move_to_pos_callback(axis, msg);
                break;
            case 0x021:
                set_pos_setpoint_callback(axis, msg);
                break;
            case 0x022:
                set_vel_setpoint_callback(axis, msg);
                break;
            case 0x023:
                set_current_setpoint_callback(axis, msg);
                break;
        }
    }
}

void CANSimple::estop_callback(){
    for(Axis* axis : axes){
        axis->error_ |= Axis::ERROR_ESTOP_REQUESTED;
    }
}

void CANSimple::move_to_pos_callback(Axis* axis, CAN_message_t& msg) {
    float pos = msg.buf[0];
    pos += msg.buf[1] << 8;
    pos += msg.buf[2] << 16;
    pos += msg.buf[3] << 24;

    axis->controller_.move_to_pos(pos);
}

void CANSimple::set_pos_setpoint_callback(Axis* axis, CAN_message_t& msg) {
    float pos = msg.buf[0];
    pos += msg.buf[1] << 8;
    pos += msg.buf[2] << 16;
    pos += msg.buf[3] << 24;

    float vel = msg.buf[4];
    vel += msg.buf[5] << 8;
    vel *= 0.1f;  // Factor of 10

    float current = msg.buf[6];
    current += (msg.buf[7] << 8);
    current *= 0.01f;  // Factor of 100

    axis->controller_.set_pos_setpoint(pos, vel, current);
}

void CANSimple::set_vel_setpoint_callback(Axis* axis, CAN_message_t& msg) {
    float vel = msg.buf[0];
    vel += msg.buf[1] << 8;
    vel += msg.buf[2] << 16;
    vel += msg.buf[3] << 24;
    vel *= 0.01f;

    float current = msg.buf[4];
    current += msg.buf[5] << 8;
    current += msg.buf[6] << 16;
    current += msg.buf[7] << 24;
    current *= 0.01f;

    axis->controller_.set_vel_setpoint(vel, current);
}

void CANSimple::set_current_setpoint_callback(Axis* axis, CAN_message_t& msg) {
    float current = msg.buf[0];
    current += msg.buf[1] << 8;
    current += msg.buf[2] << 16;
    current += msg.buf[3] << 24;
    current *= 0.01f;

    axis->controller_.set_current_setpoint(current);
}

void CANSimple::send_heartbeat(Axis* axis){
    CAN_message_t txmsg;
    txmsg.id = axis->config_.can_node_id << 7;
    txmsg.id += 0x1;
    txmsg.isExt = false;
    txmsg.len = 8;

    // Axis errors in 1st 32-bit value
    txmsg.buf[0] = axis->error_;
    txmsg.buf[1] = axis->error_ >> 8;
    txmsg.buf[2] = axis->error_ >> 16;
    txmsg.buf[3] = axis->error_ >> 24;

    // Current state of axis in 2nd 32-bit value
    txmsg.buf[4] = axis->current_state_;
    txmsg.buf[5] = axis->current_state_ >> 8;
    txmsg.buf[6] = axis->current_state_ >> 16;
    txmsg.buf[7] = axis->current_state_ >> 24;
}<|endoftext|>