<commit_before>//===------------------------ memory_resource.cpp -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "experimental/memory_resource"

#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
#include "atomic"
#else
#include "mutex"
#endif

_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR

// memory_resource

//memory_resource::~memory_resource() {}

// new_delete_resource()

class _LIBCPP_TYPE_VIS_ONLY __new_delete_memory_resource_imp
    : public memory_resource
{
public:
    ~__new_delete_memory_resource_imp() = default;

protected:
    virtual void* do_allocate(size_t __size, size_t __align)
        { return __allocate(__size); }

    virtual void do_deallocate(void * __p, size_t, size_t)
        { __deallocate(__p); }

    virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
        { return &__other == this; }
};

// null_memory_resource()

class _LIBCPP_TYPE_VIS_ONLY __null_memory_resource_imp
    : public memory_resource
{
public:
    ~__null_memory_resource_imp() = default;

protected:
    virtual void* do_allocate(size_t, size_t) {
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
        throw std::bad_alloc();
#else
        abort();
#endif
    }
    virtual void do_deallocate(void *, size_t, size_t) {}
    virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
    { return &__other == this; }
};

union ResourceInitHelper {
  struct {
    __new_delete_memory_resource_imp new_delete_res;
    __null_memory_resource_imp       null_res;
  } resources;
  char dummy;
  _LIBCPP_CONSTEXPR_AFTER_CXX11 ResourceInitHelper() : resources() {}
  ~ResourceInitHelper() {}
};
// When compiled in C++14 this initialization should be a constant expression.
// Only in C++11 is "init_priority" needed to ensure initialization order.
ResourceInitHelper res_init __attribute__((init_priority (101)));

memory_resource * new_delete_resource() _NOEXCEPT {
    return &res_init.resources.new_delete_res;
}

memory_resource * null_memory_resource() _NOEXCEPT {
    return &res_init.resources.null_res;
}

// default_memory_resource()

static memory_resource *
__default_memory_resource(bool set = false, memory_resource * new_res = nullptr) _NOEXCEPT
{
#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
    static atomic<memory_resource*> __res =
        ATOMIC_VAR_INIT(&res_init.resources.new_delete_res);
    if (set) {
        new_res = new_res ? new_res : new_delete_resource();
        // TODO: Can a weaker ordering be used?
        return _VSTD::atomic_exchange_explicit(
            &__res, new_res, memory_order::memory_order_acq_rel);
    }
    else {
        return _VSTD::atomic_load_explicit(
            &__res, memory_order::memory_order_acquire);
    }
#else
    static memory_resource * res = &res_init.resources.new_delete_res;
    static mutex res_lock;
    if (set) {
        new_res = new_res ? new_res : new_delete_resource();
        lock_guard<mutex> guard(res_lock);
        memory_resource * old_res = res;
        res = new_res;
        return old_res;
    } else {
        lock_guard<mutex> guard(res_lock);
        return res;
    }
#endif
}

memory_resource * get_default_resource() _NOEXCEPT
{
    return __default_memory_resource();
}

memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT
{
    return __default_memory_resource(true, __new_res);
}

_LIBCPP_END_NAMESPACE_LFTS_PMR<commit_msg>Fix one more usage of _LIBCPP_HAS_NO_EXCEPTIONS<commit_after>//===------------------------ memory_resource.cpp -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "experimental/memory_resource"

#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
#include "atomic"
#else
#include "mutex"
#endif

_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR

// memory_resource

//memory_resource::~memory_resource() {}

// new_delete_resource()

class _LIBCPP_TYPE_VIS_ONLY __new_delete_memory_resource_imp
    : public memory_resource
{
public:
    ~__new_delete_memory_resource_imp() = default;

protected:
    virtual void* do_allocate(size_t __size, size_t __align)
        { return __allocate(__size); }

    virtual void do_deallocate(void * __p, size_t, size_t)
        { __deallocate(__p); }

    virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
        { return &__other == this; }
};

// null_memory_resource()

class _LIBCPP_TYPE_VIS_ONLY __null_memory_resource_imp
    : public memory_resource
{
public:
    ~__null_memory_resource_imp() = default;

protected:
    virtual void* do_allocate(size_t, size_t) {
#ifndef _LIBCPP_NO_EXCEPTIONS
        throw std::bad_alloc();
#else
        abort();
#endif
    }
    virtual void do_deallocate(void *, size_t, size_t) {}
    virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
    { return &__other == this; }
};

union ResourceInitHelper {
  struct {
    __new_delete_memory_resource_imp new_delete_res;
    __null_memory_resource_imp       null_res;
  } resources;
  char dummy;
  _LIBCPP_CONSTEXPR_AFTER_CXX11 ResourceInitHelper() : resources() {}
  ~ResourceInitHelper() {}
};
// When compiled in C++14 this initialization should be a constant expression.
// Only in C++11 is "init_priority" needed to ensure initialization order.
ResourceInitHelper res_init __attribute__((init_priority (101)));

memory_resource * new_delete_resource() _NOEXCEPT {
    return &res_init.resources.new_delete_res;
}

memory_resource * null_memory_resource() _NOEXCEPT {
    return &res_init.resources.null_res;
}

// default_memory_resource()

static memory_resource *
__default_memory_resource(bool set = false, memory_resource * new_res = nullptr) _NOEXCEPT
{
#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
    static atomic<memory_resource*> __res =
        ATOMIC_VAR_INIT(&res_init.resources.new_delete_res);
    if (set) {
        new_res = new_res ? new_res : new_delete_resource();
        // TODO: Can a weaker ordering be used?
        return _VSTD::atomic_exchange_explicit(
            &__res, new_res, memory_order::memory_order_acq_rel);
    }
    else {
        return _VSTD::atomic_load_explicit(
            &__res, memory_order::memory_order_acquire);
    }
#else
    static memory_resource * res = &res_init.resources.new_delete_res;
    static mutex res_lock;
    if (set) {
        new_res = new_res ? new_res : new_delete_resource();
        lock_guard<mutex> guard(res_lock);
        memory_resource * old_res = res;
        res = new_res;
        return old_res;
    } else {
        lock_guard<mutex> guard(res_lock);
        return res;
    }
#endif
}

memory_resource * get_default_resource() _NOEXCEPT
{
    return __default_memory_resource();
}

memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT
{
    return __default_memory_resource(true, __new_res);
}

_LIBCPP_END_NAMESPACE_LFTS_PMR<|endoftext|>


<commit_before>// Copyright (c) 2015, LAAS-CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core.
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

#include <hpp/model/device.hh>
#include <hpp/constraints/differentiable-function.hh>
#include <hpp/core/explicit-numerical-constraint.hh>

namespace hpp {
  namespace core {
    void complement (size_type size, const SizeIntervals_t& intervals,
		     SizeIntervals_t& result)
    {
      std::vector <bool> unionOfIntervals (size+1, false);
      for (SizeIntervals_t::const_iterator it = intervals.begin ();
	   it != intervals.end (); ++it) {
	for (size_type i=it->first; i < it->first + it->second; ++i) {
	  unionOfIntervals [i] = true;
	}
      }
      unionOfIntervals [size] = true;
      unsigned int state = 0;
      SizeInterval_t interval;
      for (size_type i=0; i <= (size_type) unionOfIntervals.size (); ++i) {
	if ((state == 0) && (unionOfIntervals [i] == false)) {
	  // start a new interval
	  state = 1;
	  interval.first = i;
	} else if ((state == 1) && unionOfIntervals [i] == true) {
	  // finish current interval
	  state = 0;
	  interval.second = i - interval.first;
	  result.push_back (interval);
	}
      }
    }

    HPP_PREDEF_CLASS (ImplicitFunction);
    typedef boost::shared_ptr <ImplicitFunction> ImplicitFunctionPtr_t;
    class ImplicitFunction : public DifferentiableFunction
    {
    public:
      static ImplicitFunctionPtr_t create
      (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
       const SizeIntervals_t& outputConf, const SizeIntervals_t& outputVelocity)
      {
	ImplicitFunction* ptr = new ImplicitFunction
	  (robot, function, outputConf, outputVelocity);
	return ImplicitFunctionPtr_t (ptr);
      }
      void solve (ConfigurationOut_t configuration, vectorIn_t rhs)
      {
	assert (rhs.size () == output_.size ());
	size_type index = 0;
	for (SizeIntervals_t::const_iterator it = inputConfIntervals_.begin ();
	     it != inputConfIntervals_.end (); ++it) {
	  input_.segment (index, it->second) =
	    configuration.segment (it->first, it->second);
	  index += it->second;
	}
	(*inputToOutput_) (output_, input_);
	index = 0;
	for (SizeIntervals_t::const_iterator it = outputConfIntervals_.begin ();
	     it != outputConfIntervals_.end (); ++it) {
	  configuration.segment (it->first, it->second) =
	    output_.segment (index, it->second) +
	    rhs.segment (index, it->second);
	  index += it->second;
	}
      }

    protected:
      ImplicitFunction (const DevicePtr_t& robot,
			const DifferentiableFunctionPtr_t& function,
			const SizeIntervals_t& outputConf,
			const SizeIntervals_t& outputVelocity)
	: DifferentiableFunction (robot->configSize (), robot->numberDof (),
				  function->outputSize (),
				  function->outputDerivativeSize ()),
	  robot_ (robot), inputToOutput_ (function), inputConfIntervals_ (),
	  inputDerivIntervals_ (), outputConfIntervals_ (outputConf),
	  outputDerivIntervals_ (outputVelocity)
      {
	// Check input consistency
	// Each configuration variable is either input or output
	assert (function->inputSize () + function->outputSize () ==
		robot->configSize ());
	// Each velocity variable is either input or output
	assert (function->inputDerivativeSize () +
		function->outputDerivativeSize () == robot->numberDof ());
	input_.resize (function->inputSize ());
	output_.resize (function->outputSize ());
	J_.resize (function->outputDerivativeSize (),
		   function->inputDerivativeSize ());
	size_type size = 0;
	// Sum of configuration output interval sizes equal function output size
	for (SizeIntervals_t::const_iterator it = outputConf.begin ();
	     it != outputConf.end (); ++it) {
	  size += it->second;
	}
	assert (size == function->outputSize ());
	// Sum of velocity output interval sizes equal function output
	// derivative size
	size = 0;
	for (SizeIntervals_t::const_iterator it = outputVelocity.begin ();
	     it != outputVelocity.end (); ++it) {
	  size += it->second;
	}
	assert (size == function->outputDerivativeSize ());
	// Conpute input intervals
	complement (robot->configSize (), outputConfIntervals_,
		    inputConfIntervals_);
	complement (robot->numberDof (), outputDerivIntervals_,
		    inputDerivIntervals_);
      }

      void impl_compute (vectorOut_t result, vectorIn_t argument) const
      {
	size_type index = 0;
	for (SizeIntervals_t::const_iterator it = outputConfIntervals_.begin ();
	     it != outputConfIntervals_.end (); ++it) {
	  result.segment (index, it->second) =
	    argument.segment (it->first, it->second);
	  index += it->second;
	}
	index = 0;
	for (SizeIntervals_t::const_iterator it = inputConfIntervals_.begin ();
	     it != inputConfIntervals_.end (); ++it) {
	  input_.segment (index, it->second) =
	    argument.segment (it->first, it->second);
	  index += it->second;
	}
	(*inputToOutput_) (output_, input_);
	result -= output_;
      }

      void impl_jacobian (matrixOut_t jacobian, vectorIn_t arg) const
      {
	jacobian.setZero ();
	size_type row = 0;
	for (SizeIntervals_t::const_iterator it=outputDerivIntervals_.begin ();
	     it != outputDerivIntervals_.end (); ++it) {
	  for (size_type col=it->first; col < it->first + it->second; ++col) {
	    jacobian (row, col) = 1;
	    ++row;
	  }
	}

	size_type index = 0;
	for (SizeIntervals_t::const_iterator it = inputConfIntervals_.begin ();
	     it != inputConfIntervals_.end (); ++it) {
	  input_.segment (index, it->second) =
	    arg.segment (it->first, it->second);
	  index += it->second;
	}
	inputToOutput_->jacobian (J_, input_);
	size_type col=0;
	size_type nbRows = inputToOutput_->outputDerivativeSize ();
	for (SizeIntervals_t::const_iterator it = inputDerivIntervals_.begin ();
	     it != inputDerivIntervals_.end (); ++it) {
	  jacobian.block (0, it->first, nbRows, it->second) =
	    - J_.block (0, col, nbRows, it->second);
	  col += it->second;
	}
      }

    private:
      DevicePtr_t robot_;
      DifferentiableFunctionPtr_t inputToOutput_;
      SizeIntervals_t inputConfIntervals_;
      SizeIntervals_t inputDerivIntervals_;
      SizeIntervals_t outputConfIntervals_;
      SizeIntervals_t outputDerivIntervals_;
      mutable vector_t input_;
      mutable vector_t output_;
      // Jacobian of explicit function
      mutable matrix_t J_;
    }; // class ImplicitFunction

    ExplicitNumericalConstraintPtr_t ExplicitNumericalConstraint::create
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity)
    {
      ExplicitNumericalConstraint* ptr = new ExplicitNumericalConstraint
	(robot, function, outputConf, outputVelocity);
      return ExplicitNumericalConstraintPtr_t (ptr);
    }

    ExplicitNumericalConstraintPtr_t ExplicitNumericalConstraint::create
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity, vectorIn_t rhs)
    {
      ExplicitNumericalConstraint* ptr = new ExplicitNumericalConstraint
	(robot, function, outputConf, outputVelocity, rhs);
      return ExplicitNumericalConstraintPtr_t (ptr);
    }

    ExplicitNumericalConstraintPtr_t ExplicitNumericalConstraint::createCopy
    (const ExplicitNumericalConstraintPtr_t& other)
    {
      ExplicitNumericalConstraint* ptr = new ExplicitNumericalConstraint
	(*other);
      ExplicitNumericalConstraintPtr_t shPtr (ptr);
      ExplicitNumericalConstraintWkPtr_t wkPtr (shPtr);
      ptr->init (wkPtr);
      return shPtr;
    }

    EquationPtr_t ExplicitNumericalConstraint::copy () const
    {
      return createCopy (weak_.lock ());
    }

    ExplicitNumericalConstraint::ExplicitNumericalConstraint
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity) :
      NumericalConstraint (ImplicitFunction::create
			   (robot, function, outputConf, outputVelocity),
			   Equality::create ())
    {
    }

    ExplicitNumericalConstraint::ExplicitNumericalConstraint
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity, vectorIn_t rhs) :
      NumericalConstraint (ImplicitFunction::create
			   (robot, function, outputConf, outputVelocity),
			   Equality::create (), rhs)
    {
    }

    ExplicitNumericalConstraint::ExplicitNumericalConstraint
    (const ExplicitNumericalConstraint& other) :
      NumericalConstraint (other), inputToOutput_ (other.inputToOutput_)
    {
    }

    void ExplicitNumericalConstraint::solve (ConfigurationOut_t configuration)
    {
      HPP_STATIC_CAST_REF_CHECK (ImplicitFunction, *(functionPtr ()));
      HPP_STATIC_PTR_CAST (ImplicitFunction, functionPtr ())->solve
	(configuration, rightHandSide ());
    }

  } // namespace core
} // namespace hpp
<commit_msg>Call init method in ExplicitNumericalConstraint::create.<commit_after>// Copyright (c) 2015, LAAS-CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core.
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

#include <hpp/model/device.hh>
#include <hpp/constraints/differentiable-function.hh>
#include <hpp/core/explicit-numerical-constraint.hh>

namespace hpp {
  namespace core {
    void complement (size_type size, const SizeIntervals_t& intervals,
		     SizeIntervals_t& result)
    {
      std::vector <bool> unionOfIntervals (size+1, false);
      for (SizeIntervals_t::const_iterator it = intervals.begin ();
	   it != intervals.end (); ++it) {
	for (size_type i=it->first; i < it->first + it->second; ++i) {
	  unionOfIntervals [i] = true;
	}
      }
      unionOfIntervals [size] = true;
      unsigned int state = 0;
      SizeInterval_t interval;
      for (size_type i=0; i <= (size_type) unionOfIntervals.size (); ++i) {
	if ((state == 0) && (unionOfIntervals [i] == false)) {
	  // start a new interval
	  state = 1;
	  interval.first = i;
	} else if ((state == 1) && unionOfIntervals [i] == true) {
	  // finish current interval
	  state = 0;
	  interval.second = i - interval.first;
	  result.push_back (interval);
	}
      }
    }

    HPP_PREDEF_CLASS (ImplicitFunction);
    typedef boost::shared_ptr <ImplicitFunction> ImplicitFunctionPtr_t;
    class ImplicitFunction : public DifferentiableFunction
    {
    public:
      static ImplicitFunctionPtr_t create
      (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
       const SizeIntervals_t& outputConf, const SizeIntervals_t& outputVelocity)
      {
	ImplicitFunction* ptr = new ImplicitFunction
	  (robot, function, outputConf, outputVelocity);
	return ImplicitFunctionPtr_t (ptr);
      }
      void solve (ConfigurationOut_t configuration, vectorIn_t rhs)
      {
	assert (rhs.size () == output_.size ());
	size_type index = 0;
	for (SizeIntervals_t::const_iterator it = inputConfIntervals_.begin ();
	     it != inputConfIntervals_.end (); ++it) {
	  input_.segment (index, it->second) =
	    configuration.segment (it->first, it->second);
	  index += it->second;
	}
	(*inputToOutput_) (output_, input_);
	index = 0;
	for (SizeIntervals_t::const_iterator it = outputConfIntervals_.begin ();
	     it != outputConfIntervals_.end (); ++it) {
	  configuration.segment (it->first, it->second) =
	    output_.segment (index, it->second) +
	    rhs.segment (index, it->second);
	  index += it->second;
	}
      }

    protected:
      ImplicitFunction (const DevicePtr_t& robot,
			const DifferentiableFunctionPtr_t& function,
			const SizeIntervals_t& outputConf,
			const SizeIntervals_t& outputVelocity)
	: DifferentiableFunction (robot->configSize (), robot->numberDof (),
				  function->outputSize (),
				  function->outputDerivativeSize ()),
	  robot_ (robot), inputToOutput_ (function), inputConfIntervals_ (),
	  inputDerivIntervals_ (), outputConfIntervals_ (outputConf),
	  outputDerivIntervals_ (outputVelocity)
      {
	// Check input consistency
	// Each configuration variable is either input or output
	assert (function->inputSize () + function->outputSize () ==
		robot->configSize ());
	// Each velocity variable is either input or output
	assert (function->inputDerivativeSize () +
		function->outputDerivativeSize () == robot->numberDof ());
	input_.resize (function->inputSize ());
	output_.resize (function->outputSize ());
	J_.resize (function->outputDerivativeSize (),
		   function->inputDerivativeSize ());
	size_type size = 0;
	// Sum of configuration output interval sizes equal function output size
	for (SizeIntervals_t::const_iterator it = outputConf.begin ();
	     it != outputConf.end (); ++it) {
	  size += it->second;
	}
	assert (size == function->outputSize ());
	// Sum of velocity output interval sizes equal function output
	// derivative size
	size = 0;
	for (SizeIntervals_t::const_iterator it = outputVelocity.begin ();
	     it != outputVelocity.end (); ++it) {
	  size += it->second;
	}
	assert (size == function->outputDerivativeSize ());
	// Conpute input intervals
	complement (robot->configSize (), outputConfIntervals_,
		    inputConfIntervals_);
	complement (robot->numberDof (), outputDerivIntervals_,
		    inputDerivIntervals_);
      }

      void impl_compute (vectorOut_t result, vectorIn_t argument) const
      {
	size_type index = 0;
	for (SizeIntervals_t::const_iterator it = outputConfIntervals_.begin ();
	     it != outputConfIntervals_.end (); ++it) {
	  result.segment (index, it->second) =
	    argument.segment (it->first, it->second);
	  index += it->second;
	}
	index = 0;
	for (SizeIntervals_t::const_iterator it = inputConfIntervals_.begin ();
	     it != inputConfIntervals_.end (); ++it) {
	  input_.segment (index, it->second) =
	    argument.segment (it->first, it->second);
	  index += it->second;
	}
	(*inputToOutput_) (output_, input_);
	result -= output_;
      }

      void impl_jacobian (matrixOut_t jacobian, vectorIn_t arg) const
      {
	jacobian.setZero ();
	size_type row = 0;
	for (SizeIntervals_t::const_iterator it=outputDerivIntervals_.begin ();
	     it != outputDerivIntervals_.end (); ++it) {
	  for (size_type col=it->first; col < it->first + it->second; ++col) {
	    jacobian (row, col) = 1;
	    ++row;
	  }
	}

	size_type index = 0;
	for (SizeIntervals_t::const_iterator it = inputConfIntervals_.begin ();
	     it != inputConfIntervals_.end (); ++it) {
	  input_.segment (index, it->second) =
	    arg.segment (it->first, it->second);
	  index += it->second;
	}
	inputToOutput_->jacobian (J_, input_);
	size_type col=0;
	size_type nbRows = inputToOutput_->outputDerivativeSize ();
	for (SizeIntervals_t::const_iterator it = inputDerivIntervals_.begin ();
	     it != inputDerivIntervals_.end (); ++it) {
	  jacobian.block (0, it->first, nbRows, it->second) =
	    - J_.block (0, col, nbRows, it->second);
	  col += it->second;
	}
      }

    private:
      DevicePtr_t robot_;
      DifferentiableFunctionPtr_t inputToOutput_;
      SizeIntervals_t inputConfIntervals_;
      SizeIntervals_t inputDerivIntervals_;
      SizeIntervals_t outputConfIntervals_;
      SizeIntervals_t outputDerivIntervals_;
      mutable vector_t input_;
      mutable vector_t output_;
      // Jacobian of explicit function
      mutable matrix_t J_;
    }; // class ImplicitFunction

    ExplicitNumericalConstraintPtr_t ExplicitNumericalConstraint::create
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity)
    {
      ExplicitNumericalConstraint* ptr = new ExplicitNumericalConstraint
	(robot, function, outputConf, outputVelocity);
      ExplicitNumericalConstraintPtr_t shPtr (ptr);
      ExplicitNumericalConstraintWkPtr_t wkPtr (shPtr);
      ptr->init (wkPtr);
      return shPtr;
    }

    ExplicitNumericalConstraintPtr_t ExplicitNumericalConstraint::create
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity, vectorIn_t rhs)
    {
      ExplicitNumericalConstraint* ptr = new ExplicitNumericalConstraint
	(robot, function, outputConf, outputVelocity, rhs);
      ExplicitNumericalConstraintPtr_t shPtr (ptr);
      ExplicitNumericalConstraintWkPtr_t wkPtr (shPtr);
      ptr->init (wkPtr);
      return shPtr;
    }

    ExplicitNumericalConstraintPtr_t ExplicitNumericalConstraint::createCopy
    (const ExplicitNumericalConstraintPtr_t& other)
    {
      ExplicitNumericalConstraint* ptr = new ExplicitNumericalConstraint
	(*other);
      ExplicitNumericalConstraintPtr_t shPtr (ptr);
      ExplicitNumericalConstraintWkPtr_t wkPtr (shPtr);
      ptr->init (wkPtr);
      return shPtr;
    }

    EquationPtr_t ExplicitNumericalConstraint::copy () const
    {
      return createCopy (weak_.lock ());
    }

    ExplicitNumericalConstraint::ExplicitNumericalConstraint
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity) :
      NumericalConstraint (ImplicitFunction::create
			   (robot, function, outputConf, outputVelocity),
			   Equality::create ())
    {
    }

    ExplicitNumericalConstraint::ExplicitNumericalConstraint
    (const DevicePtr_t& robot, const DifferentiableFunctionPtr_t& function,
     const SizeIntervals_t& outputConf,
     const SizeIntervals_t& outputVelocity, vectorIn_t rhs) :
      NumericalConstraint (ImplicitFunction::create
			   (robot, function, outputConf, outputVelocity),
			   Equality::create (), rhs)
    {
    }

    ExplicitNumericalConstraint::ExplicitNumericalConstraint
    (const ExplicitNumericalConstraint& other) :
      NumericalConstraint (other), inputToOutput_ (other.inputToOutput_)
    {
    }

    void ExplicitNumericalConstraint::solve (ConfigurationOut_t configuration)
    {
      HPP_STATIC_CAST_REF_CHECK (ImplicitFunction, *(functionPtr ()));
      HPP_STATIC_PTR_CAST (ImplicitFunction, functionPtr ())->solve
	(configuration, rightHandSide ());
    }

  } // namespace core
} // namespace hpp
<|endoftext|>


<commit_before>#include "BluPrivatePCH.h"

RenderHandler::RenderHandler(int32 width, int32 height, UBluEye* ui)
{
	this->Width = width;
	this->Height = height;
	this->parentUI = ui;
}

bool RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
{
	rect = CefRect(0, 0, Width, Height);
	return true;
}

void RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height)
{
	FUpdateTextureRegion2D *updateRegions = static_cast<FUpdateTextureRegion2D*>(FMemory::Malloc(sizeof(FUpdateTextureRegion2D) * dirtyRects.size()));

	int current = 0;
	for (auto dirtyRect : dirtyRects)
	{
		updateRegions[current].DestX = updateRegions[current].SrcX = dirtyRect.x;
		updateRegions[current].DestY = updateRegions[current].SrcY = dirtyRect.y;
		updateRegions[current].Height = dirtyRect.height;
		updateRegions[current].Width = dirtyRect.width;

		current++;
	}

	// Trigger our parent UIs Texture to update
	parentUI->TextureUpdate(buffer, updateRegions, dirtyRects.size());
}

bool BrowserClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message)
{

	FString data;
	FString name = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(0).ToString().c_str()));
	FString type = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(2).ToString().c_str()));
	FString data_type = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(3).ToString().c_str()));

	if (type == "js_event")
	{

		// Check the datatype

		if (data_type == "bool")
			data = message->GetArgumentList()->GetBool(1) ? TEXT("true") : TEXT("false");
		else if (data_type == "int")
			data = FString::FromInt(message->GetArgumentList()->GetInt(1));
		else if (data_type == "string")
			data = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(1).ToString().c_str()));
		else if (data_type == "double")
			data = FString::SanitizeFloat(message->GetArgumentList()->GetDouble(1));

		event_emitter->Broadcast(name, data);
	}

	return true;

}

//The path slashes have to be reversed to work with CEF
FString ReversePathSlashes(FString forwardPath)
{
	return forwardPath.Replace(TEXT("/"), TEXT("\\"));
}
FString UtilityBLUIDownloadsFolder()
{
	return ReversePathSlashes(FPaths::ConvertRelativePathToFull(FPaths::GameDir() + "Plugins/BLUI/Downloads/"));
}

void BrowserClient::SetEventEmitter(FScriptEvent* emitter)
{
	this->event_emitter = emitter;
}

void BrowserClient::OnBeforeDownload(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	const CefString & suggested_name,
	CefRefPtr<CefBeforeDownloadCallback> callback)
{
	UNREFERENCED_PARAMETER(browser);
	UNREFERENCED_PARAMETER(download_item);

	//We use this concatenation method to mix c_str with regular FString and then convert the result back to c_str
	FString downloadPath = UtilityBLUIDownloadsFolder() + FString(suggested_name.c_str());

	callback->Continue(*downloadPath, false);	//don't show the download dialog, just go for it

	UE_LOG(LogClass, Log, TEXT("Downloading file for path %s"), *downloadPath);
}

void BrowserClient::OnDownloadUpdated(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	CefRefPtr<CefDownloadItemCallback> callback)
{
	int percentage = download_item->GetPercentComplete();
	FString url = FString(download_item->GetFullPath().c_str());

	UE_LOG(LogClass, Log, TEXT("Download %s Updated: %d"), *url , percentage);

	blu->DownloadUpdated.Broadcast(url, percentage);

	if (percentage == 100 && download_item->IsComplete()) {
		UE_LOG(LogClass, Log, TEXT("Download %s Complete"), *url);
		blu->DownloadComplete.Broadcast(url);
	}

	//Example download cancel/pause etc, we just have to hijack this
	//callback->Cancel();
}

<commit_msg>Added changes from Shammah Branch<commit_after>#include "BluPrivatePCH.h"

RenderHandler::RenderHandler(int32 width, int32 height, UBluEye* ui)
{
	this->Width = width;
	this->Height = height;
	this->parentUI = ui;
}

bool RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
{
	if (IsRunningDedicatedServer())
	{
        	rect = CefRect(0, 0, 0, 0);
	}
	else
	{
	   	rect = CefRect(0, 0, width, height);
	}
	return true;
}

void RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height)
{
	FUpdateTextureRegion2D *updateRegions = static_cast<FUpdateTextureRegion2D*>(FMemory::Malloc(sizeof(FUpdateTextureRegion2D) * dirtyRects.size()));

	int current = 0;
	for (auto dirtyRect : dirtyRects)
	{
		updateRegions[current].DestX = updateRegions[current].SrcX = dirtyRect.x;
		updateRegions[current].DestY = updateRegions[current].SrcY = dirtyRect.y;
		updateRegions[current].Height = dirtyRect.height;
		updateRegions[current].Width = dirtyRect.width;

		current++;
	}

	// Trigger our parent UIs Texture to update
	parentUI->TextureUpdate(buffer, updateRegions, dirtyRects.size());
}

bool BrowserClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message)
{

	FString data;
	FString name = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(0).ToString().c_str()));
	FString type = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(2).ToString().c_str()));
	FString data_type = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(3).ToString().c_str()));

	if (type == "js_event")
	{

		// Check the datatype

		if (data_type == "bool")
			data = message->GetArgumentList()->GetBool(1) ? TEXT("true") : TEXT("false");
		else if (data_type == "int")
			data = FString::FromInt(message->GetArgumentList()->GetInt(1));
		else if (data_type == "string")
			data = FString(UTF8_TO_TCHAR(message->GetArgumentList()->GetString(1).ToString().c_str()));
		else if (data_type == "double")
			data = FString::SanitizeFloat(message->GetArgumentList()->GetDouble(1));

		event_emitter->Broadcast(name, data);
	}

	return true;

}

//The path slashes have to be reversed to work with CEF
FString ReversePathSlashes(FString forwardPath)
{
	return forwardPath.Replace(TEXT("/"), TEXT("\\"));
}
FString UtilityBLUIDownloadsFolder()
{
	return ReversePathSlashes(FPaths::ConvertRelativePathToFull(FPaths::GameDir() + "Plugins/BLUI/Downloads/"));
}

void BrowserClient::SetEventEmitter(FScriptEvent* emitter)
{
	this->event_emitter = emitter;
}

void BrowserClient::OnBeforeDownload(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	const CefString & suggested_name,
	CefRefPtr<CefBeforeDownloadCallback> callback)
{
	UNREFERENCED_PARAMETER(browser);
	UNREFERENCED_PARAMETER(download_item);

	//We use this concatenation method to mix c_str with regular FString and then convert the result back to c_str
	FString downloadPath = UtilityBLUIDownloadsFolder() + FString(suggested_name.c_str());

	callback->Continue(*downloadPath, false);	//don't show the download dialog, just go for it

	UE_LOG(LogClass, Log, TEXT("Downloading file for path %s"), *downloadPath);
}

void BrowserClient::OnDownloadUpdated(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefDownloadItem> download_item,
	CefRefPtr<CefDownloadItemCallback> callback)
{
	int percentage = download_item->GetPercentComplete();
	FString url = FString(download_item->GetFullPath().c_str());

	UE_LOG(LogClass, Log, TEXT("Download %s Updated: %d"), *url , percentage);

	blu->DownloadUpdated.Broadcast(url, percentage);

	if (percentage == 100 && download_item->IsComplete()) {
		UE_LOG(LogClass, Log, TEXT("Download %s Complete"), *url);
		blu->DownloadComplete.Broadcast(url);
	}

	//Example download cancel/pause etc, we just have to hijack this
	//callback->Cancel();
}

<|endoftext|>


<commit_before>
#include "quadCoderDriver_signed.hpp"

/* ROBOT PHYSICAL DEFINITIONS */  /*TODO: determine these values */
#define MOTOR_RATIO		((double)20)
//#define WHEEL_RADIUS		((double)5 / (double)MOTOR_RATIO)

//in meters
#define WHEEL_RADIUS		(double(.146) / double(2))
//unknown units
#define WHEEL_BASE		((double)28)

//there are 4 ticks per mark on the disk
#define NUMBERTICKS		double(800)
//#define NUMBERTICKS		double(400)

//this is det by delay within arduino code
#define SMAPLEDELAY		double(5e-3)
quadCoderDriver_signed::quadCoderDriver_signed()
{
	m_connected = false;
	ifname = ENCODER_IF_BOARD;
	ai.initLink(ENCODER_IF_BOARD);
	m_connected = true;
}

quadCoderDriver_signed::quadCoderDriver_signed(byte coder_name)
{
	m_connected = false;
	this->ifname = coder_name;
	ai.initLink(ifname);
	m_connected = true;
}

bool quadCoderDriver_signed::getEncoderState(new_encoder_pk_t& out)
{

	if(ai.sendCommand(ENCODER_GET_READING, NULL, 0))
	{
		return true;
	}

	byte retcmd = ENCODER_GET_READING;
	byte* data = NULL;

	if(ai.recvCommand(retcmd, data))
	{
		return true;
	}

	memcpy(&out, data, sizeof(new_encoder_pk_t));
	delete[] data;
	return false;
}

//in meters per second
bool quadCoderDriver_signed::getEncoderVel(double& vel_l, double& vel_r)
{
	new_encoder_pk_t out;

	if(getEncoderState(out))
	{
		return true;
	}

	double dtheta_l = ((out.dl / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) / SMAPLEDELAY;
	vel_l = dtheta_l * WHEEL_RADIUS;

	double dtheta_r = ((out.dr / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) / SMAPLEDELAY;
	vel_r = dtheta_r * WHEEL_RADIUS;

	return false;
}

/* Returns distance each wheel has traveled in meters since last reset */
bool quadCoderDriver_signed::getEncoderDist(double& dist_l, double& dist_r)
{
	new_encoder_pk_t out;

	if(getEncoderState(out))
	{
		return true;
	}

	dist_l = ((out.pl / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) * WHEEL_RADIUS;
	dist_r = ((out.pr / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) * WHEEL_RADIUS;

	return false;
}

bool quadCoderDriver_signed::resetCount()
{
	if(ai.sendCommand(ENCODER_RESET_COUNT, NULL, 0))
	{
		return true;
	}

	byte retcmd = ENCODER_GET_READING;
	byte* data = NULL;

	return ai.recvCommand(retcmd, data);
}
<commit_msg>wrong spelling<commit_after>
#include "quadCoderDriver_signed.hpp"

/* ROBOT PHYSICAL DEFINITIONS */  /*TODO: determine these values */
#define MOTOR_RATIO		((double)20)
//#define WHEEL_RADIUS		((double)5 / (double)MOTOR_RATIO)

//in meters
#define WHEEL_RADIUS		(double(.146) / double(2))
//unknown units
#define WHEEL_BASE		((double)28)

//there are 4 ticks per mark on the disk
#define NUMBERTICKS		double(800)
//#define NUMBERTICKS		double(400)

//this is det by delay within arduino code
#define SAMPLEDELAY		double(5e-3)
quadCoderDriver_signed::quadCoderDriver_signed()
{
	m_connected = false;
	ifname = ENCODER_IF_BOARD;
	ai.initLink(ENCODER_IF_BOARD);
	m_connected = true;
}

quadCoderDriver_signed::quadCoderDriver_signed(byte coder_name)
{
	m_connected = false;
	this->ifname = coder_name;
	ai.initLink(ifname);
	m_connected = true;
}

bool quadCoderDriver_signed::getEncoderState(new_encoder_pk_t& out)
{

	if(ai.sendCommand(ENCODER_GET_READING, NULL, 0))
	{
		return true;
	}

	byte retcmd = ENCODER_GET_READING;
	byte* data = NULL;

	if(ai.recvCommand(retcmd, data))
	{
		return true;
	}

	memcpy(&out, data, sizeof(new_encoder_pk_t));
	delete[] data;
	return false;
}

//in meters per second
bool quadCoderDriver_signed::getEncoderVel(double& vel_l, double& vel_r)
{
	new_encoder_pk_t out;

	if(getEncoderState(out))
	{
		return true;
	}

	double dtheta_l = ((out.dl / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) / SMAPLEDELAY;
	vel_l = dtheta_l * WHEEL_RADIUS;

	double dtheta_r = ((out.dr / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) / SMAPLEDELAY;
	vel_r = dtheta_r * WHEEL_RADIUS;

	return false;
}

/* Returns distance each wheel has traveled in meters since last reset */
bool quadCoderDriver_signed::getEncoderDist(double& dist_l, double& dist_r)
{
	new_encoder_pk_t out;

	if(getEncoderState(out))
	{
		return true;
	}

	dist_l = ((out.pl / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) * WHEEL_RADIUS;
	dist_r = ((out.pr / NUMBERTICKS * double(2)*M_PI) / MOTOR_RATIO) * WHEEL_RADIUS;

	return false;
}

bool quadCoderDriver_signed::resetCount()
{
	if(ai.sendCommand(ENCODER_RESET_COUNT, NULL, 0))
	{
		return true;
	}

	byte retcmd = ENCODER_GET_READING;
	byte* data = NULL;

	return ai.recvCommand(retcmd, data);
}
<|endoftext|>


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

#include "Camera.h"
#include "CollisionShape.h"
#include "CoreEvents.h"
#include "DebugRenderer.h"
#include "Engine.h"
#include "File.h"
#include "FileSystem.h"
#include "Font.h"
#include "Graphics.h"
#include "Input.h"
#include "Light.h"
#include "Material.h"
#include "Model.h"
#include "Octree.h"
#include "PhysicsWorld.h"
#include "Renderer.h"
#include "ResourceCache.h"
#include "RigidBody.h"
#include "StaticModel.h"
#include "Text.h"
#include "UI.h"
#include "Zone.h"

#include "Physics.h"

#include "DebugNew.h"

// Expands to this example's entry-point
DEFINE_APPLICATION_MAIN(Physics)

Physics::Physics(Context* context) :
    Sample(context),
    yaw_(0.0f),
    pitch_(0.0f),
    drawDebug_(false)
{
}

void Physics::Start()
{
    // Execute base class startup
    Sample::Start();

    // Create the scene content
    CreateScene();

    // Create the UI content
    CreateInstructions();

    // Setup the viewport for displaying the scene
    SetupViewport();

    // Hook up to the frame update and render post-update events
    SubscribeToEvents();
}

void Physics::CreateScene()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);

    // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
    // Create a physics simulation world with default parameters, which will update at 60fps. Like the Octree must
    // exist before creating drawable components, the PhysicsWorld must exist before creating physics components.
    // Finally, create a DebugRenderer component so that we can draw physics debug geometry
    scene_->CreateComponent<Octree>();
    scene_->CreateComponent<PhysicsWorld>();
    scene_->CreateComponent<DebugRenderer>();

    // Create a Zone component for ambient lighting & fog control
    Node* zoneNode = scene_->CreateChild("Zone");
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    zone->SetFogColor(Color(0.5f, 0.5f, 0.7f));
    zone->SetFogStart(100.0f);
    zone->SetFogEnd(300.0f);

    // Create a directional light to the world. Enable cascaded shadows on it
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetCastShadows(true);
    light->SetShadowBias(BiasParameters(0.0001f, 0.5f));
    // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance
    light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));

    {
        // Create a floor object, 100 x 100 world units. Adjust position so that the ground is at zero Y
        Node* floorNode = scene_->CreateChild("Floor");
        floorNode->SetPosition(Vector3(0.0f, -0.25f, 0.0f));
        floorNode->SetScale(Vector3(100.0f, 0.5f, 100.0f));
        StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
        floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));

        // Make the floor physical by adding RigidBody and CollisionShape components. The RigidBody's default
        // parameters make the object static (zero mass.) Note that a CollisionShape by itself will not participate
        // in the physics simulation
        RigidBody* body = floorNode->CreateComponent<RigidBody>();
        CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
        // Set a box shape of size 1 x 1 x 1 for collision. The shape will be scaled with the scene node scale, so the
        // rendering and physics representation sizes should match (the box model is also 1 x 1 x 1.)
        shape->SetBox(Vector3::ONE);
    }

    {
        // Create a pyramid of movable physics objects
        for (int y = 0; y < 8; ++y)
        {
            for (int x = -y; x <= y; ++x)
            {
                Node* boxNode = scene_->CreateChild("Box");
                boxNode->SetPosition(Vector3((float)x, -(float)y + 8.0f, 0.0f));
                StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
                boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
                boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneEnvMapSmall.xml"));
                boxObject->SetCastShadows(true);

                // Create RigidBody and CollisionShape components like above. Give the RigidBody mass to make it movable
                // and also adjust friction. The actual mass is not important; only the mass ratios between colliding
                // objects are significant
                RigidBody* body = boxNode->CreateComponent<RigidBody>();
                body->SetMass(1.0f);
                body->SetFriction(0.75f);
                CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
                shape->SetBox(Vector3::ONE);
            }
        }
    }

    // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside
    // the scene, because we want it to be unaffected by scene load/save
    cameraNode_ = new Node(context_);
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(300.0f);

    // Set an initial position for the camera scene node above the floor
    cameraNode_->SetPosition(Vector3(0.0f, 5.0f, -20.0f));
}

void Physics::CreateInstructions()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    UI* ui = GetSubsystem<UI>();

    // Construct new Text object, set string to display and font to use
    Text* instructionText = ui->GetRoot()->CreateChild<Text>();
    instructionText->SetText(
        "Use WASD keys and mouse to move\n"
        "LMB to spawn physics objects\n"
        "F5 to save scene, F7 to load\n"
        "Space to toggle physics debug geometry"
    );
    instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15);

    // Position the text relative to the screen center
    instructionText->SetHorizontalAlignment(HA_CENTER);
    instructionText->SetVerticalAlignment(VA_CENTER);
    instructionText->SetPosition(0, ui->GetRoot()->GetHeight() / 4);
}

void Physics::SetupViewport()
{
    Renderer* renderer = GetSubsystem<Renderer>();

    // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
    SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
    renderer->SetViewport(0, viewport);
}

void Physics::MoveCamera(float timeStep)
{
    // Do not move if the UI has a focused element (the console)
    if (GetSubsystem<UI>()->GetFocusElement())
        return;

    Input* input = GetSubsystem<Input>();

    // Movement speed as world units per second
    const float MOVE_SPEED = 20.0f;
    // Mouse sensitivity as degrees per pixel
    const float MOUSE_SENSITIVITY = 0.1f;

    // Use this frame's mouse motion to adjust camera node yaw and pitch. Clamp the pitch between -90 and 90 degrees
    IntVector2 mouseMove = input->GetMouseMove();
    yaw_ += MOUSE_SENSITIVITY * mouseMove.x_;
    pitch_ += MOUSE_SENSITIVITY * mouseMove.y_;
    pitch_ = Clamp(pitch_, -90.0f, 90.0f);

    // Construct new orientation for the camera scene node from yaw and pitch. Roll is fixed to zero
    cameraNode_->SetRotation(Quaternion(pitch_, yaw_, 0.0f));

    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
    if (input->GetKeyDown('W'))
        cameraNode_->TranslateRelative(Vector3::FORWARD * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('S'))
        cameraNode_->TranslateRelative(Vector3::BACK * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('A'))
        cameraNode_->TranslateRelative(Vector3::LEFT * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('D'))
        cameraNode_->TranslateRelative(Vector3::RIGHT * MOVE_SPEED * timeStep);

    // "Shoot" a physics object with left mousebutton
    if (input->GetMouseButtonPress(MOUSEB_LEFT))
        SpawnObject();

    // Toggle physics debug geometry with space
    if (input->GetKeyPress(KEY_SPACE))
        drawDebug_ = !drawDebug_;
}

void Physics::SpawnObject()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    // Create a smaller box at camera position
    Node* boxNode = scene_->CreateChild("SmallBox");
    boxNode->SetPosition(cameraNode_->GetPosition());
    boxNode->SetRotation(cameraNode_->GetRotation());
    boxNode->SetScale(0.25f);
    StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
    boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
    boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneEnvMapSmall.xml"));
    boxObject->SetCastShadows(true);

    // Create physics components, use a smaller mass also
    RigidBody* body = boxNode->CreateComponent<RigidBody>();
    body->SetMass(0.25f);
    body->SetFriction(0.75f);
    CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
    shape->SetBox(Vector3::ONE);

    const float OBJECT_VELOCITY = 10.0f;

    // Set initial velocity for the RigidBody based on camera forward vector. Add also a slight up component
    // to overcome gravity better
    body->SetLinearVelocity(cameraNode_->GetRotation() * Vector3(0.0f, 0.25f, 1.0f) * OBJECT_VELOCITY);
}

void Physics::SubscribeToEvents()
{
    // Subscribes HandleUpdate() method for processing update events
    SubscribeToEvent(E_UPDATE, HANDLER(Physics, HandleUpdate));

    // Subscribes HandlePostRenderUpdate() method for processing the post-render update event, during which we request
    // debug geometry
    SubscribeToEvent(E_POSTRENDERUPDATE, HANDLER(Physics, HandlePostRenderUpdate));
}

void Physics::HandleUpdate(StringHash eventType, VariantMap& eventData)
{
    // Event parameters are always defined inside a namespace corresponding to the event's name
    using namespace Update;

    // Take the frame time step, which is stored as a float
    float timeStep = eventData[P_TIMESTEP].GetFloat();

    // Move the camera, scale movement with time step
    MoveCamera(timeStep);

    // Check for loading/saving the scene. Save the scene to the file Data/Scenes/Physics.xml relative to the executable
    // directory
    Input* input = GetSubsystem<Input>();
    if (input->GetKeyPress(KEY_F5))
    {
        File saveFile(context_, GetSubsystem<FileSystem>()->GetProgramDir() + "Data/Scenes/Physics.xml", FILE_WRITE);
        scene_->SaveXML(saveFile);
    }
    if (input->GetKeyPress(KEY_F7))
    {
        File loadFile(context_, GetSubsystem<FileSystem>()->GetProgramDir() + "Data/Scenes/Physics.xml", FILE_READ);
        scene_->LoadXML(loadFile);
    }
}

void Physics::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
    // If draw debug mode is enabled, draw physics debug geometry. Use depth test to make the result easier to interpret
    if (drawDebug_)
        scene_->GetComponent<PhysicsWorld>()->DrawDebugGeometry(true);
}
<commit_msg>Larger plane in the Physics sample.<commit_after>//
// Copyright (c) 2008-2013 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "Camera.h"
#include "CollisionShape.h"
#include "CoreEvents.h"
#include "DebugRenderer.h"
#include "Engine.h"
#include "File.h"
#include "FileSystem.h"
#include "Font.h"
#include "Graphics.h"
#include "Input.h"
#include "Light.h"
#include "Material.h"
#include "Model.h"
#include "Octree.h"
#include "PhysicsWorld.h"
#include "Renderer.h"
#include "ResourceCache.h"
#include "RigidBody.h"
#include "StaticModel.h"
#include "Text.h"
#include "UI.h"
#include "Zone.h"

#include "Physics.h"

#include "DebugNew.h"

// Expands to this example's entry-point
DEFINE_APPLICATION_MAIN(Physics)

Physics::Physics(Context* context) :
    Sample(context),
    yaw_(0.0f),
    pitch_(0.0f),
    drawDebug_(false)
{
}

void Physics::Start()
{
    // Execute base class startup
    Sample::Start();

    // Create the scene content
    CreateScene();

    // Create the UI content
    CreateInstructions();

    // Setup the viewport for displaying the scene
    SetupViewport();

    // Hook up to the frame update and render post-update events
    SubscribeToEvents();
}

void Physics::CreateScene()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);

    // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
    // Create a physics simulation world with default parameters, which will update at 60fps. Like the Octree must
    // exist before creating drawable components, the PhysicsWorld must exist before creating physics components.
    // Finally, create a DebugRenderer component so that we can draw physics debug geometry
    scene_->CreateComponent<Octree>();
    scene_->CreateComponent<PhysicsWorld>();
    scene_->CreateComponent<DebugRenderer>();

    // Create a Zone component for ambient lighting & fog control
    Node* zoneNode = scene_->CreateChild("Zone");
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    zone->SetFogColor(Color(0.5f, 0.5f, 0.7f));
    zone->SetFogStart(100.0f);
    zone->SetFogEnd(300.0f);

    // Create a directional light to the world. Enable cascaded shadows on it
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetCastShadows(true);
    light->SetShadowBias(BiasParameters(0.0001f, 0.5f));
    // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance
    light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));

    {
        // Create a floor object, 500 x 500 world units. Adjust position so that the ground is at zero Y
        Node* floorNode = scene_->CreateChild("Floor");
        floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));
        floorNode->SetScale(Vector3(500.0f, 1.0f, 500.0f));
        StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
        floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));

        // Make the floor physical by adding RigidBody and CollisionShape components. The RigidBody's default
        // parameters make the object static (zero mass.) Note that a CollisionShape by itself will not participate
        // in the physics simulation
        RigidBody* body = floorNode->CreateComponent<RigidBody>();
        CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
        // Set a box shape of size 1 x 1 x 1 for collision. The shape will be scaled with the scene node scale, so the
        // rendering and physics representation sizes should match (the box model is also 1 x 1 x 1.)
        shape->SetBox(Vector3::ONE);
    }

    {
        // Create a pyramid of movable physics objects
        for (int y = 0; y < 8; ++y)
        {
            for (int x = -y; x <= y; ++x)
            {
                Node* boxNode = scene_->CreateChild("Box");
                boxNode->SetPosition(Vector3((float)x, -(float)y + 8.0f, 0.0f));
                StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
                boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
                boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneEnvMapSmall.xml"));
                boxObject->SetCastShadows(true);

                // Create RigidBody and CollisionShape components like above. Give the RigidBody mass to make it movable
                // and also adjust friction. The actual mass is not important; only the mass ratios between colliding
                // objects are significant
                RigidBody* body = boxNode->CreateComponent<RigidBody>();
                body->SetMass(1.0f);
                body->SetFriction(0.75f);
                CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
                shape->SetBox(Vector3::ONE);
            }
        }
    }

    // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside
    // the scene, because we want it to be unaffected by scene load/save
    cameraNode_ = new Node(context_);
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(300.0f);

    // Set an initial position for the camera scene node above the floor
    cameraNode_->SetPosition(Vector3(0.0f, 5.0f, -20.0f));
}

void Physics::CreateInstructions()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    UI* ui = GetSubsystem<UI>();

    // Construct new Text object, set string to display and font to use
    Text* instructionText = ui->GetRoot()->CreateChild<Text>();
    instructionText->SetText(
        "Use WASD keys and mouse to move\n"
        "LMB to spawn physics objects\n"
        "F5 to save scene, F7 to load\n"
        "Space to toggle physics debug geometry"
    );
    instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15);

    // Position the text relative to the screen center
    instructionText->SetHorizontalAlignment(HA_CENTER);
    instructionText->SetVerticalAlignment(VA_CENTER);
    instructionText->SetPosition(0, ui->GetRoot()->GetHeight() / 4);
}

void Physics::SetupViewport()
{
    Renderer* renderer = GetSubsystem<Renderer>();

    // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
    SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
    renderer->SetViewport(0, viewport);
}

void Physics::MoveCamera(float timeStep)
{
    // Do not move if the UI has a focused element (the console)
    if (GetSubsystem<UI>()->GetFocusElement())
        return;

    Input* input = GetSubsystem<Input>();

    // Movement speed as world units per second
    const float MOVE_SPEED = 20.0f;
    // Mouse sensitivity as degrees per pixel
    const float MOUSE_SENSITIVITY = 0.1f;

    // Use this frame's mouse motion to adjust camera node yaw and pitch. Clamp the pitch between -90 and 90 degrees
    IntVector2 mouseMove = input->GetMouseMove();
    yaw_ += MOUSE_SENSITIVITY * mouseMove.x_;
    pitch_ += MOUSE_SENSITIVITY * mouseMove.y_;
    pitch_ = Clamp(pitch_, -90.0f, 90.0f);

    // Construct new orientation for the camera scene node from yaw and pitch. Roll is fixed to zero
    cameraNode_->SetRotation(Quaternion(pitch_, yaw_, 0.0f));

    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
    if (input->GetKeyDown('W'))
        cameraNode_->TranslateRelative(Vector3::FORWARD * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('S'))
        cameraNode_->TranslateRelative(Vector3::BACK * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('A'))
        cameraNode_->TranslateRelative(Vector3::LEFT * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('D'))
        cameraNode_->TranslateRelative(Vector3::RIGHT * MOVE_SPEED * timeStep);

    // "Shoot" a physics object with left mousebutton
    if (input->GetMouseButtonPress(MOUSEB_LEFT))
        SpawnObject();

    // Toggle physics debug geometry with space
    if (input->GetKeyPress(KEY_SPACE))
        drawDebug_ = !drawDebug_;
}

void Physics::SpawnObject()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    // Create a smaller box at camera position
    Node* boxNode = scene_->CreateChild("SmallBox");
    boxNode->SetPosition(cameraNode_->GetPosition());
    boxNode->SetRotation(cameraNode_->GetRotation());
    boxNode->SetScale(0.25f);
    StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
    boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
    boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneEnvMapSmall.xml"));
    boxObject->SetCastShadows(true);

    // Create physics components, use a smaller mass also
    RigidBody* body = boxNode->CreateComponent<RigidBody>();
    body->SetMass(0.25f);
    body->SetFriction(0.75f);
    CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
    shape->SetBox(Vector3::ONE);

    const float OBJECT_VELOCITY = 10.0f;

    // Set initial velocity for the RigidBody based on camera forward vector. Add also a slight up component
    // to overcome gravity better
    body->SetLinearVelocity(cameraNode_->GetRotation() * Vector3(0.0f, 0.25f, 1.0f) * OBJECT_VELOCITY);
}

void Physics::SubscribeToEvents()
{
    // Subscribes HandleUpdate() method for processing update events
    SubscribeToEvent(E_UPDATE, HANDLER(Physics, HandleUpdate));

    // Subscribes HandlePostRenderUpdate() method for processing the post-render update event, during which we request
    // debug geometry
    SubscribeToEvent(E_POSTRENDERUPDATE, HANDLER(Physics, HandlePostRenderUpdate));
}

void Physics::HandleUpdate(StringHash eventType, VariantMap& eventData)
{
    // Event parameters are always defined inside a namespace corresponding to the event's name
    using namespace Update;

    // Take the frame time step, which is stored as a float
    float timeStep = eventData[P_TIMESTEP].GetFloat();

    // Move the camera, scale movement with time step
    MoveCamera(timeStep);

    // Check for loading/saving the scene. Save the scene to the file Data/Scenes/Physics.xml relative to the executable
    // directory
    Input* input = GetSubsystem<Input>();
    if (input->GetKeyPress(KEY_F5))
    {
        File saveFile(context_, GetSubsystem<FileSystem>()->GetProgramDir() + "Data/Scenes/Physics.xml", FILE_WRITE);
        scene_->SaveXML(saveFile);
    }
    if (input->GetKeyPress(KEY_F7))
    {
        File loadFile(context_, GetSubsystem<FileSystem>()->GetProgramDir() + "Data/Scenes/Physics.xml", FILE_READ);
        scene_->LoadXML(loadFile);
    }
}

void Physics::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
    // If draw debug mode is enabled, draw physics debug geometry. Use depth test to make the result easier to interpret
    if (drawDebug_)
        scene_->GetComponent<PhysicsWorld>()->DrawDebugGeometry(true);
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include "core/animation/TimingInput.h"

#include "bindings/v8/Dictionary.h"
#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/CSSToStyleMap.h"

namespace WebCore {

void TimingInput::setStartDelay(Timing& timing, double startDelay)
{
    if (std::isfinite(startDelay))
        timing.startDelay = startDelay;
    else
        timing.startDelay = Timing::defaults().startDelay;
}

void TimingInput::setEndDelay(Timing& timing, double endDelay)
{
    if (std::isfinite(endDelay))
        timing.endDelay = endDelay;
    else
        timing.endDelay = Timing::defaults().endDelay;
}

void TimingInput::setFillMode(Timing& timing, const String& fillMode)
{
    if (fillMode == "none") {
        timing.fillMode = Timing::FillModeNone;
    } else if (fillMode == "backwards") {
        timing.fillMode = Timing::FillModeBackwards;
    } else if (fillMode == "both") {
        timing.fillMode = Timing::FillModeBoth;
    } else if (fillMode == "forwards") {
        timing.fillMode = Timing::FillModeForwards;
    } else {
        timing.fillMode = Timing::defaults().fillMode;
    }
}

void TimingInput::setIterationStart(Timing& timing, double iterationStart)
{
    if (std::isfinite(iterationStart))
        timing.iterationStart = std::max<double>(iterationStart, 0);
    else
        timing.iterationStart = Timing::defaults().iterationStart;
}

void TimingInput::setIterationCount(Timing& timing, double iterationCount)
{
    if (!std::isnan(iterationCount))
        timing.iterationCount = std::max<double>(iterationCount, 0);
    else
        timing.iterationCount = Timing::defaults().iterationCount;
}

void TimingInput::setIterationDuration(Timing& timing, double iterationDuration)
{
    if (!std::isnan(iterationDuration) && iterationDuration >= 0)
        timing.iterationDuration = iterationDuration;
    else
        timing.iterationDuration = Timing::defaults().iterationDuration;
}

void TimingInput::setPlaybackRate(Timing& timing, double playbackRate)
{
    if (std::isfinite(playbackRate))
        timing.playbackRate = playbackRate;
    else
        timing.playbackRate = Timing::defaults().playbackRate;
}

void TimingInput::setPlaybackDirection(Timing& timing, const String& direction)
{
    if (direction == "reverse") {
        timing.direction = Timing::PlaybackDirectionReverse;
    } else if (direction == "alternate") {
        timing.direction = Timing::PlaybackDirectionAlternate;
    } else if (direction == "alternate-reverse") {
        timing.direction = Timing::PlaybackDirectionAlternateReverse;
    } else {
        timing.direction = Timing::defaults().direction;
    }
}

void TimingInput::setTimingFunction(Timing& timing, const String& timingFunctionString)
{
    RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString);
    if (timingFunctionValue) {
        RefPtr<TimingFunction> timingFunction = CSSToStyleMap::animationTimingFunction(timingFunctionValue.get(), false);
        if (timingFunction) {
            timing.timingFunction = timingFunction;
            return;
        }
    }
    timing.timingFunction = Timing::defaults().timingFunction;
}

Timing TimingInput::convert(const Dictionary& timingInputDictionary)
{
    Timing result;

    // FIXME: This method needs to be refactored to handle invalid
    // null, NaN, Infinity values better.
    // See: http://www.w3.org/TR/WebIDL/#es-double
    double startDelay = 0;
    timingInputDictionary.get("delay", startDelay);
    setStartDelay(result, startDelay);

    double endDelay = 0;
    timingInputDictionary.get("endDelay", endDelay);
    setEndDelay(result, endDelay);

    String fillMode;
    timingInputDictionary.get("fill", fillMode);
    setFillMode(result, fillMode);

    double iterationStart = 0;
    timingInputDictionary.get("iterationStart", iterationStart);
    setIterationStart(result, iterationStart);

    double iterationCount = 1;
    timingInputDictionary.get("iterations", iterationCount);
    setIterationCount(result, iterationCount);

    double iterationDuration
    if (timingInputDictionary.get("duration", iterationDuration)) {
        setIterationDuration(result, iterationDuration);
    }

    double playbackRate = 1;
    timingInputDictionary.get("playbackRate", playbackRate);
    setPlaybackRate(result, playbackRate);

    String direction;
    timingInputDictionary.get("direction", direction);
    setPlaybackDirection(result, direction);

    String timingFunctionString;
    timingInputDictionary.get("easing", timingFunctionString);
    setTimingFunction(result, timingFunctionString);

    result.assertValid();

    return result;
}

Timing TimingInput::convert(double duration)
{
    Timing result;
    setIterationDuration(result, duration);
    return result;
}

} // namespace WebCore
<commit_msg>Revert r169876 "Remove use of a V8 handle outside of bindings code in TimingInput.cpp."<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include "core/animation/TimingInput.h"

#include "bindings/v8/Dictionary.h"
#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/CSSToStyleMap.h"

namespace WebCore {

void TimingInput::setStartDelay(Timing& timing, double startDelay)
{
    if (std::isfinite(startDelay))
        timing.startDelay = startDelay;
    else
        timing.startDelay = Timing::defaults().startDelay;
}

void TimingInput::setEndDelay(Timing& timing, double endDelay)
{
    if (std::isfinite(endDelay))
        timing.endDelay = endDelay;
    else
        timing.endDelay = Timing::defaults().endDelay;
}

void TimingInput::setFillMode(Timing& timing, const String& fillMode)
{
    if (fillMode == "none") {
        timing.fillMode = Timing::FillModeNone;
    } else if (fillMode == "backwards") {
        timing.fillMode = Timing::FillModeBackwards;
    } else if (fillMode == "both") {
        timing.fillMode = Timing::FillModeBoth;
    } else if (fillMode == "forwards") {
        timing.fillMode = Timing::FillModeForwards;
    } else {
        timing.fillMode = Timing::defaults().fillMode;
    }
}

void TimingInput::setIterationStart(Timing& timing, double iterationStart)
{
    if (std::isfinite(iterationStart))
        timing.iterationStart = std::max<double>(iterationStart, 0);
    else
        timing.iterationStart = Timing::defaults().iterationStart;
}

void TimingInput::setIterationCount(Timing& timing, double iterationCount)
{
    if (!std::isnan(iterationCount))
        timing.iterationCount = std::max<double>(iterationCount, 0);
    else
        timing.iterationCount = Timing::defaults().iterationCount;
}

void TimingInput::setIterationDuration(Timing& timing, double iterationDuration)
{
    if (!std::isnan(iterationDuration) && iterationDuration >= 0)
        timing.iterationDuration = iterationDuration;
    else
        timing.iterationDuration = Timing::defaults().iterationDuration;
}

void TimingInput::setPlaybackRate(Timing& timing, double playbackRate)
{
    if (std::isfinite(playbackRate))
        timing.playbackRate = playbackRate;
    else
        timing.playbackRate = Timing::defaults().playbackRate;
}

void TimingInput::setPlaybackDirection(Timing& timing, const String& direction)
{
    if (direction == "reverse") {
        timing.direction = Timing::PlaybackDirectionReverse;
    } else if (direction == "alternate") {
        timing.direction = Timing::PlaybackDirectionAlternate;
    } else if (direction == "alternate-reverse") {
        timing.direction = Timing::PlaybackDirectionAlternateReverse;
    } else {
        timing.direction = Timing::defaults().direction;
    }
}

void TimingInput::setTimingFunction(Timing& timing, const String& timingFunctionString)
{
    RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString);
    if (timingFunctionValue) {
        RefPtr<TimingFunction> timingFunction = CSSToStyleMap::animationTimingFunction(timingFunctionValue.get(), false);
        if (timingFunction) {
            timing.timingFunction = timingFunction;
            return;
        }
    }
    timing.timingFunction = Timing::defaults().timingFunction;
}

Timing TimingInput::convert(const Dictionary& timingInputDictionary)
{
    Timing result;

    // FIXME: This method needs to be refactored to handle invalid
    // null, NaN, Infinity values better.
    // See: http://www.w3.org/TR/WebIDL/#es-double
    double startDelay = 0;
    timingInputDictionary.get("delay", startDelay);
    setStartDelay(result, startDelay);

    double endDelay = 0;
    timingInputDictionary.get("endDelay", endDelay);
    setEndDelay(result, endDelay);

    String fillMode;
    timingInputDictionary.get("fill", fillMode);
    setFillMode(result, fillMode);

    double iterationStart = 0;
    timingInputDictionary.get("iterationStart", iterationStart);
    setIterationStart(result, iterationStart);

    double iterationCount = 1;
    timingInputDictionary.get("iterations", iterationCount);
    setIterationCount(result, iterationCount);

    v8::Local<v8::Value> iterationDurationValue;
    if (timingInputDictionary.get("duration", iterationDurationValue)) {
        double iterationDuration = iterationDurationValue->NumberValue();
        setIterationDuration(result, iterationDuration);
    }

    double playbackRate = 1;
    timingInputDictionary.get("playbackRate", playbackRate);
    setPlaybackRate(result, playbackRate);

    String direction;
    timingInputDictionary.get("direction", direction);
    setPlaybackDirection(result, direction);

    String timingFunctionString;
    timingInputDictionary.get("easing", timingFunctionString);
    setTimingFunction(result, timingFunctionString);

    result.assertValid();

    return result;
}

Timing TimingInput::convert(double duration)
{
    Timing result;
    setIterationDuration(result, duration);
    return result;
}

} // namespace WebCore
<|endoftext|>


<commit_before>#pragma once
#ifndef FORWARDER_HPP
# define FORWARDER_HPP

#include <cassert>

#include <cstddef>

#include <cstdint>

#include <type_traits>

#include <utility>

#include <new>

namespace generic
{

template<typename F>
class forwarder;

template<typename R, typename ...A>
class forwarder<R (A...)>
{
public:
  forwarder() = default;

  forwarder(forwarder const&) = default;

  template<typename T>
  forwarder(T&& f) : stub_(handler<T>::stub)
  {
    static_assert(sizeof(T) <= sizeof(store_),
      "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
    new (&store_) handler<T>(::std::forward<T>(f));
  }

  forwarder& operator=(forwarder const&) = default;

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder& operator=(T&& f)
  {
    static_assert(sizeof(T) <= sizeof(store_), "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
    new (&store_) handler<T>(::std::forward<T>(f));

    stub_ = handler<T>::stub;

    return *this;
  }

  R operator() (A... args) const
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward<A>(args)...);
  }

private:
  template<typename T>
  struct handler
  {
    handler(T&& f) noexcept : f_(::std::forward<T>(f))
    {
    }

    static R stub(void const* ptr, A&&... args)
    {
      return static_cast<handler<T> const*>(ptr)->
        f_(::std::forward<A>(args)...);
    }

    T f_;
  };

#if defined(__clang__)
  using max_align_type = long double;
#elif defined(__GNUC__)
  using max_align_type = ::max_align_t;
#else
  using max_align_type = ::std::max_align_t;
#endif

  alignas(max_align_type) ::std::uintptr_t store_;

  R (*stub_)(void const*, A&&...){};
};

}

#endif // FORWARDER_HPP
<commit_msg>some fixes<commit_after>#pragma once
#ifndef FORWARDER_HPP
# define FORWARDER_HPP

#include <cassert>

#include <cstddef>

#include <cstdint>

#include <type_traits>

#include <utility>

#include <new>

namespace generic
{

template<typename F>
class forwarder;

template<typename R, typename ...A>
class forwarder<R (A...)>
{
public:
  forwarder() = default;

  forwarder(forwarder const&) = default;

  template<typename T>
  forwarder(T&& f) : stub_(handler<T>::stub)
  {
    static_assert(sizeof(T) <= sizeof(store_),
      "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
    new (&store_) handler<T>(::std::forward<T>(f));
  }

  forwarder& operator=(forwarder const&) = default;

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder& operator=(T&& f)
  {
    static_assert(sizeof(T) <= sizeof(store_), "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
    new (&store_) handler<T>(::std::forward<T>(f));

    stub_ = handler<T>::stub;

    return *this;
  }

  R operator() (A... args) const
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward<A>(args)...);
  }

private:
  template<typename T>
  struct handler
  {
    handler(T&& f) noexcept : f_(::std::forward<T>(f))
    {
    }

    static R stub(void const* ptr, A&&... args)
    {
      return static_cast<handler<T> const*>(ptr)->
        f_(::std::forward<A>(args)...);
    }

    T f_;
  };

  R (*stub_)(void const*, A&&...){};

#if defined(__clang__)
  using max_align_type = long double;
#elif defined(__GNUC__)
  using max_align_type = ::max_align_t;
#else
  using max_align_type = ::std::max_align_t;
#endif

  alignas(max_align_type) ::std::uintptr_t store_;
};

}

#endif // FORWARDER_HPP
<|endoftext|>


<commit_before>#include <boost/algorithm/string.hpp>
#include "SysUtil.h"
#include "lib/mace.h"
#include "lib/SysUtil.h"

#include "services/ReplayTree/ReplayTree-init.h"
#include "services/RandTree/RandTree-init.h"
#include "services/GenericTreeMulticast/GenericTreeMulticast-init.h"
#include "services/GenericTreeMulticast/DeferredGenericTreeMulticast-init.h"
#include "services/SignedMulticast/SignedMulticast-init.h"
#include "services/SignedMulticast/DeferredSignedMulticast-init.h"
#include "services/Pastry/Pastry-init.h"
#include "services/Bamboo/Bamboo-init.h"
#include "services/Bamboo/DeferredBamboo-init.h"
#include "services/ScribeMS/ScribeMS-init.h"
#include "services/ScribeMS/Scribe-init.h"
#include "services/ScribeMS/DeferredScribeMS-init.h"
#include "services/GenericOverlayRoute/CacheRecursiveOverlayRoute-init.h"
#include "services/GenericOverlayRoute/RecursiveOverlayRoute.h"
#include "services/GenericOverlayRoute/RecursiveOverlayRoute-init.h"
#include "TcpTransport.h"
#include "TcpTransport-init.h"
#include "UdpTransport.h"
#include "UdpTransport-init.h"
#include "services/Transport/DeferredRouteTransportWrapper.h"
#include "services/Transport/DeferredRouteTransportWrapper-init.h"
#include "services/Transport/RouteTransportWrapper.h"
#include "services/Transport/RouteTransportWrapper-init.h"

/* Variables */
MaceKey myip;  //This is always the IP address
MaceKey mygroup; // This is the local group_id.

/* Calculate moving average of latency */
int gotten = 0;   // number of pkts received
double avg_lat = 0.0;  // the average latency of received pkts
std::vector<double> arr_lat;
std::map<int,double> arr_crit;
typedef std::set<std::string> ip_list;
std::map<int,ip_list> arr_crit_list;

pthread_mutex_t deliverMutex;

class MyHandler : public ReceiveDataHandler {
  public:
  MyHandler() : uid(NumberGen::Instance(NumberGen::HANDLER_UID)->GetVal())
  {}

  const int uid;

  /* source, dest(=group_id), msg, uid */
  void deliver(const MaceKey& source, const MaceKey& dest, const std::string& msg, registration_uid_t serviceUid)
  {
    double delay = 0.0;
    int msg_id = 0;

    ScopedLock sl(deliverMutex);

    if (msg.size() > sizeof(double))
    {

      std::vector<std::string> strs;
      std::string s = msg;
      boost::split(strs, s, boost::is_any_of(","));

      assert(strs.size() > 2 );

      //std::cout << "Message process.." << std::endl;

      msg_id = (int) boost::lexical_cast<uint64_t>(strs[0]);
      delay = ((double)TimeUtil::timeu() - boost::lexical_cast<uint64_t>(strs[1]))/1000000;

      if (delay > 1000.0)
      {
        //printf("exception: weird time sent detected in app: %llu %llu\n", TimeUtil::timeu(), boost::lexical_cast<uint64_t>(msg.data()));
      }
      else
      {
        // calculate critical delay
        assert(msg_id >= 0);
      }
      std::ostringstream os;
      os << "* Message [ "<< strs[0] << " ] from : "<< strs[2] << "  Channel : " << serviceUid << "  Delay : " << delay << " Sent: " << strs[1] << " Now: " << TimeUtil::timeu() << " (source: " << source << " dest: " << dest << " )" << std::endl;
      std::cout << os.str();
    }
    return;
  }
};

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

  pthread_mutex_init(&deliverMutex, 0);

  /* Add required params */
  params::addRequired("MACE_PORT", "Port to use for connections. Allow a gap of 10 between processes");
  params::addRequired("BOOTSTRAP_NODES", "Addresses of nodes to add. e.g. IPV4/1.1.1.1:port IPV4/2.2.2.2 ... (be aware of uppercases!)");
  params::addRequired("ALL_NODES", "Addresses of nodes to add. e.g. IPV4/1.1.1.1:port IPV4/2.2.2.2 ... (be aware of uppercases!)");
  params::addRequired("NUM_THREADS", "Number of transport threads.");
  params::addRequired("IP_INTERVAL", "If multiple transport used, number of intervals between IP needs to be specified.");
  params::addRequired("DELAY", "Delay for time.");
  params::addRequired("PERIOD", "Wait time to send message periodically.");
  params::loadparams(argc, argv);

  Log::configure();

  Log::autoAddAll();

  /* Get parameters */
  myip = MaceKey(ipv4, Util::getMaceAddr());
  mygroup = MaceKey(sha160, myip.toString());
  int delay = params::get("DELAY", 1000000);
  int period = params::get("PERIOD", 6000000);
  int num_threads = params::get("NUM_THREADS", 1);
  int ip_interval = params::get("IP_INTERVAL", 1);
  int num_messages = params::get("NUM_MESSAGES", 10);
  double current_time = params::get<double>("CURRENT", 0);

  printf("* myip: %s\n", myip.toString().c_str());
  printf("* mygroup: %s\n", mygroup.toString().c_str());
  printf("* delay: %d\n", delay);
  printf("* period: %d\n", period);
  printf("* num_threads: %d\n", num_threads);
  printf("* ip_interval: %d\n", ip_interval);
  printf("* current_time: %.4f\n", current_time);

  /* Get nodeset and create subgroups */
  NodeSet bootGroups = params::get<NodeSet>("BOOTSTRAP_NODES");  // ipv4
  NodeSet allGroups = params::get<NodeSet>("ALL_NODES");  // ipv4

  std::list<ServiceClass*> thingsToExit;

  /* Create services */
  MyHandler* appHandler;

  TransportServiceClass *ntcp = &(TcpTransport_namespace::new_TcpTransport_TransportEx(num_threads));
  TransportServiceClass *udp = &(UdpTransport_namespace::new_UdpTransport_Transport());  // 1

  RouteServiceClass* rtw = &(DeferredRouteTransportWrapper_namespace::new_DeferredRouteTransportWrapper_Route(*ntcp));  // 1
  //RouteServiceClass* rtw = &(RouteTransportWrapper_namespace::new_RouteTransportWrapper_Route(*ntcp));  // 1
  OverlayRouterServiceClass* bamboo = &(Bamboo_namespace::new_Bamboo_OverlayRouter(*rtw, *udp));  // 1
  OverlayRouterServiceClass* dbamboo = &(DeferredBamboo_namespace::new_DeferredBamboo_OverlayRouter(*bamboo));  // 1
  RouteServiceClass* ror = &(RecursiveOverlayRoute_namespace::new_RecursiveOverlayRoute_Route(*ntcp, *dbamboo));  // 1
  ScribeTreeServiceClass *scribe = &(ScribeMS_namespace::new_ScribeMS_ScribeTree(*bamboo, *ror));  // 1
  TreeServiceClass *dscribe = &(DeferredScribeMS_namespace::new_DeferredScribeMS_Tree(*scribe));  // 1
  RouteServiceClass* cror = &(CacheRecursiveOverlayRoute_namespace::new_CacheRecursiveOverlayRoute_Route(*bamboo, *ntcp, 30));
  DeferredHierarchicalMulticastServiceClass* gtm = &(GenericTreeMulticast_namespace::new_GenericTreeMulticast_DeferredHierarchicalMulticast(*cror, *dscribe));
  HierarchicalMulticastServiceClass* dgtm = &(DeferredGenericTreeMulticast_namespace::new_DeferredGenericTreeMulticast_HierarchicalMulticast(*gtm));
  MulticastServiceClass* sm = &(SignedMulticast_namespace::new_SignedMulticast_Multicast(*dgtm, delay));
  MulticastServiceClass* dsm = &(DeferredSignedMulticast_namespace::new_DeferredSignedMulticast_Multicast(*sm));
  thingsToExit.push_back(dsm);

//  sm->maceInit();
//  sm->registerHandler(*appHandler, appHandler->uid);
  dsm->maceInit();
  dsm->registerHandler(*appHandler, appHandler->uid);

  /* Now register services */

  /* Now handle groups */
  ASSERT(!allGroups.empty());

  /* Joining overlay */
  std::cout << "* AllGroups listed are : " << allGroups << std::endl;;

  uint64_t sleepJoinO = (uint64_t)current_time * 1000000 + 5000000 - TimeUtil::timeu();
  std::cout << "* Waiting until 5 seconds into run to joinOverlay... ( " << sleepJoinO << " micros left)" << std::endl;
  SysUtil::sleepu(sleepJoinO);

  bamboo->joinOverlay(bootGroups);

  uint64_t sleepJoinG = (uint64_t)current_time * 1000000 + 25000000 - TimeUtil::timeu();
  std::cout << "* Waiting until 25 seconds into run to joinGroup... ( " << sleepJoinG << " micros left)" << std::endl;
  SysUtil::sleepu(sleepJoinG);

  std::cout << "* Creating/joining self-group " << mygroup << std::endl;
  dynamic_cast<GroupServiceClass*>(scribe)->createGroup(mygroup, appHandler->uid);  // create self group

  for (NodeSet::const_iterator j = allGroups.begin();j != allGroups.end(); j++) {
    std::cout << "* Joining group " << (*j) << std::endl;
    dynamic_cast<GroupServiceClass*>(scribe)->joinGroup(MaceKey(sha160, (*j).toString()), appHandler->uid);
  }

  std::cout << "* Done in joining" << std::endl;

  uint64_t sleepMessage = (uint64_t)current_time * 1000000 + 45000000 - TimeUtil::timeu();

  std::cout << "* Waiting until 45 seconds into run to start messaging... ( " << sleepMessage << " left)" << std::endl;

  SysUtil::sleepu(sleepMessage);

  std::cout << "* Messaging..." << std::endl;

  /* Basically, it will keep sending to their groups. */
  int msg_id = 0;
  while(num_messages-->0)
  {
    std::cout << "* Sending message [ "<<msg_id<<" ] " << std::endl;
    std::stringstream s;
    s << msg_id << "," << TimeUtil::timeu() << "," << myip.toString().c_str();
//    sm->multicast(mygroup, s.str(), appHandler->uid);
    dsm->multicast(mygroup, s.str(), appHandler->uid);
    msg_id++;
    SysUtil::sleepu(period);
  }

  SysUtil::sleepu(5000000);

  std::cout << "* Halting." << std::endl;

  // All done.
  for(std::list<ServiceClass*>::iterator ex = thingsToExit.begin(); ex != thingsToExit.end(); ex++) {
    (*ex)->maceExit();
  }
  Scheduler::haltScheduler();

  return 0;

}
<commit_msg>appHandler uninitialized bug fixed<commit_after>#include <boost/algorithm/string.hpp>
#include "SysUtil.h"
#include "lib/mace.h"
#include "lib/SysUtil.h"

#include "services/ReplayTree/ReplayTree-init.h"
#include "services/RandTree/RandTree-init.h"
#include "services/GenericTreeMulticast/GenericTreeMulticast-init.h"
#include "services/GenericTreeMulticast/DeferredGenericTreeMulticast-init.h"
#include "services/SignedMulticast/SignedMulticast-init.h"
#include "services/SignedMulticast/DeferredSignedMulticast-init.h"
#include "services/Pastry/Pastry-init.h"
#include "services/Bamboo/Bamboo-init.h"
#include "services/Bamboo/DeferredBamboo-init.h"
#include "services/ScribeMS/ScribeMS-init.h"
#include "services/ScribeMS/Scribe-init.h"
#include "services/ScribeMS/DeferredScribeMS-init.h"
#include "services/GenericOverlayRoute/CacheRecursiveOverlayRoute-init.h"
#include "services/GenericOverlayRoute/RecursiveOverlayRoute.h"
#include "services/GenericOverlayRoute/RecursiveOverlayRoute-init.h"
#include "TcpTransport.h"
#include "TcpTransport-init.h"
#include "UdpTransport.h"
#include "UdpTransport-init.h"
#include "services/Transport/DeferredRouteTransportWrapper.h"
#include "services/Transport/DeferredRouteTransportWrapper-init.h"
#include "services/Transport/RouteTransportWrapper.h"
#include "services/Transport/RouteTransportWrapper-init.h"

/* Variables */
MaceKey myip;  //This is always the IP address
MaceKey mygroup; // This is the local group_id.

/* Calculate moving average of latency */
int gotten = 0;   // number of pkts received
double avg_lat = 0.0;  // the average latency of received pkts
std::vector<double> arr_lat;
std::map<int,double> arr_crit;
typedef std::set<std::string> ip_list;
std::map<int,ip_list> arr_crit_list;

pthread_mutex_t deliverMutex;

class MyHandler : public ReceiveDataHandler {
  public:
  MyHandler() : uid(NumberGen::Instance(NumberGen::HANDLER_UID)->GetVal())
  {}

  const int uid;

  /* source, dest(=group_id), msg, uid */
  void deliver(const MaceKey& source, const MaceKey& dest, const std::string& msg, registration_uid_t serviceUid)
  {
    double delay = 0.0;
    int msg_id = 0;

    ScopedLock sl(deliverMutex);

    if (msg.size() > sizeof(double))
    {

      std::vector<std::string> strs;
      std::string s = msg;
      boost::split(strs, s, boost::is_any_of(","));

      assert(strs.size() > 2 );

      //std::cout << "Message process.." << std::endl;

      msg_id = (int) boost::lexical_cast<uint64_t>(strs[0]);
      delay = ((double)TimeUtil::timeu() - boost::lexical_cast<uint64_t>(strs[1]))/1000000;

      if (delay > 1000.0)
      {
        //printf("exception: weird time sent detected in app: %llu %llu\n", TimeUtil::timeu(), boost::lexical_cast<uint64_t>(msg.data()));
      }
      else
      {
        // calculate critical delay
        assert(msg_id >= 0);
      }
      std::ostringstream os;
      os << "* Message [ "<< strs[0] << " ] from : "<< strs[2] << "  Channel : " << serviceUid << "  Delay : " << delay << " Sent: " << strs[1] << " Now: " << TimeUtil::timeu() << " (source: " << source << " dest: " << dest << " )" << std::endl;
      std::cout << os.str();
    }
    return;
  }
};

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

  pthread_mutex_init(&deliverMutex, 0);

  /* Add required params */
  params::addRequired("MACE_PORT", "Port to use for connections. Allow a gap of 10 between processes");
  params::addRequired("BOOTSTRAP_NODES", "Addresses of nodes to add. e.g. IPV4/1.1.1.1:port IPV4/2.2.2.2 ... (be aware of uppercases!)");
  params::addRequired("ALL_NODES", "Addresses of nodes to add. e.g. IPV4/1.1.1.1:port IPV4/2.2.2.2 ... (be aware of uppercases!)");
  params::addRequired("NUM_THREADS", "Number of transport threads.");
  params::addRequired("IP_INTERVAL", "If multiple transport used, number of intervals between IP needs to be specified.");
  params::addRequired("DELAY", "Delay for time.");
  params::addRequired("PERIOD", "Wait time to send message periodically.");
  params::loadparams(argc, argv);

  Log::configure();

  Log::autoAddAll();

  /* Get parameters */
  myip = MaceKey(ipv4, Util::getMaceAddr());
  mygroup = MaceKey(sha160, myip.toString());
  int delay = params::get("DELAY", 1000000);
  int period = params::get("PERIOD", 6000000);
  int num_threads = params::get("NUM_THREADS", 1);
  int ip_interval = params::get("IP_INTERVAL", 1);
  int num_messages = params::get("NUM_MESSAGES", 10);
  double current_time = params::get<double>("CURRENT", 0);

  printf("* myip: %s\n", myip.toString().c_str());
  printf("* mygroup: %s\n", mygroup.toString().c_str());
  printf("* delay: %d\n", delay);
  printf("* period: %d\n", period);
  printf("* num_threads: %d\n", num_threads);
  printf("* ip_interval: %d\n", ip_interval);
  printf("* current_time: %.4f\n", current_time);

  /* Get nodeset and create subgroups */
  NodeSet bootGroups = params::get<NodeSet>("BOOTSTRAP_NODES");  // ipv4
  NodeSet allGroups = params::get<NodeSet>("ALL_NODES");  // ipv4

  std::list<ServiceClass*> thingsToExit;

  /* Create services */
  MyHandler* appHandler;

  appHandler = new MyHandler();

  TransportServiceClass *ntcp = &(TcpTransport_namespace::new_TcpTransport_TransportEx(num_threads));
  TransportServiceClass *udp = &(UdpTransport_namespace::new_UdpTransport_Transport());  // 1

  RouteServiceClass* rtw = &(DeferredRouteTransportWrapper_namespace::new_DeferredRouteTransportWrapper_Route(*ntcp));  // 1
  //RouteServiceClass* rtw = &(RouteTransportWrapper_namespace::new_RouteTransportWrapper_Route(*ntcp));  // 1
  OverlayRouterServiceClass* bamboo = &(Bamboo_namespace::new_Bamboo_OverlayRouter(*rtw, *udp));  // 1
  OverlayRouterServiceClass* dbamboo = &(DeferredBamboo_namespace::new_DeferredBamboo_OverlayRouter(*bamboo));  // 1
  RouteServiceClass* ror = &(RecursiveOverlayRoute_namespace::new_RecursiveOverlayRoute_Route(*ntcp, *dbamboo));  // 1
  ScribeTreeServiceClass *scribe = &(ScribeMS_namespace::new_ScribeMS_ScribeTree(*bamboo, *ror));  // 1
  TreeServiceClass *dscribe = &(DeferredScribeMS_namespace::new_DeferredScribeMS_Tree(*scribe));  // 1
  RouteServiceClass* cror = &(CacheRecursiveOverlayRoute_namespace::new_CacheRecursiveOverlayRoute_Route(*bamboo, *ntcp, 30));
  DeferredHierarchicalMulticastServiceClass* gtm = &(GenericTreeMulticast_namespace::new_GenericTreeMulticast_DeferredHierarchicalMulticast(*cror, *dscribe));
  HierarchicalMulticastServiceClass* dgtm = &(DeferredGenericTreeMulticast_namespace::new_DeferredGenericTreeMulticast_HierarchicalMulticast(*gtm));
  MulticastServiceClass* sm = &(SignedMulticast_namespace::new_SignedMulticast_Multicast(*dgtm, delay));
  MulticastServiceClass* dsm = &(DeferredSignedMulticast_namespace::new_DeferredSignedMulticast_Multicast(*sm));
  thingsToExit.push_back(dsm);

//  sm->maceInit();
//  sm->registerHandler(*appHandler, appHandler->uid);
  dsm->maceInit();
  dsm->registerHandler(*appHandler, appHandler->uid);

  /* Now register services */

  /* Now handle groups */
  ASSERT(!allGroups.empty());

  /* Joining overlay */
  std::cout << "* AllGroups listed are : " << allGroups << std::endl;;

  uint64_t sleepJoinO = (uint64_t)current_time * 1000000 + 5000000 - TimeUtil::timeu();
  std::cout << "* Waiting until 5 seconds into run to joinOverlay... ( " << sleepJoinO << " micros left)" << std::endl;
  SysUtil::sleepu(sleepJoinO);

  bamboo->joinOverlay(bootGroups);

  uint64_t sleepJoinG = (uint64_t)current_time * 1000000 + 25000000 - TimeUtil::timeu();
  std::cout << "* Waiting until 25 seconds into run to joinGroup... ( " << sleepJoinG << " micros left)" << std::endl;
  SysUtil::sleepu(sleepJoinG);

  std::cout << "* Creating/joining self-group " << mygroup << std::endl;
  dynamic_cast<GroupServiceClass*>(scribe)->createGroup(mygroup, appHandler->uid);  // create self group

  for (NodeSet::const_iterator j = allGroups.begin();j != allGroups.end(); j++) {
    std::cout << "* Joining group " << (*j) << std::endl;
    dynamic_cast<GroupServiceClass*>(scribe)->joinGroup(MaceKey(sha160, (*j).toString()), appHandler->uid);
  }

  std::cout << "* Done in joining" << std::endl;

  uint64_t sleepMessage = (uint64_t)current_time * 1000000 + 45000000 - TimeUtil::timeu();

  std::cout << "* Waiting until 45 seconds into run to start messaging... ( " << sleepMessage << " left)" << std::endl;

  SysUtil::sleepu(sleepMessage);

  std::cout << "* Messaging..." << std::endl;

  /* Basically, it will keep sending to their groups. */
  int msg_id = 0;
  while(num_messages-->0)
  {
    std::cout << "* Sending message [ "<<msg_id<<" ] " << std::endl;
    std::stringstream s;
    s << msg_id << "," << TimeUtil::timeu() << "," << myip.toString().c_str();
//    sm->multicast(mygroup, s.str(), appHandler->uid);
    dsm->multicast(mygroup, s.str(), appHandler->uid);
    msg_id++;
    SysUtil::sleepu(period);
  }

  SysUtil::sleepu(5000000);

  std::cout << "* Halting." << std::endl;

  // All done.
  for(std::list<ServiceClass*>::iterator ex = thingsToExit.begin(); ex != thingsToExit.end(); ex++) {
    (*ex)->maceExit();
  }
  Scheduler::haltScheduler();

  return 0;

}
<|endoftext|>