<commit_before>#pragma once

#include <cstddef>
#include <memory>
#include <functional>
#include <ratio>
#include <iterator>
#include <initializer_list>

#include <circular_iterator.hpp>

namespace helene
{
template <class T,
          std::size_t Size,
          template <class, class, std::size_t> class StoragePolicy>
class sliding_window
    : public StoragePolicy<sliding_window<T, Size, StoragePolicy>, T, Size>
{
    typedef StoragePolicy<sliding_window<T, Size, StoragePolicy>, T, Size>
        storage_policy;

public:
    static const std::size_t size = Size;

    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
    typedef circular_iterator<T*> iterator;
    typedef circular_iterator<const T*> const_iterator;

public:
    sliding_window()
        : storage_policy(),
          head_(storage_policy::begin(),
                storage_policy::end(),
                storage_policy::begin())
    {
    }

    template <class Iterator>
    sliding_window(Iterator first, Iterator last) : sliding_window()
    {
        for(; first != last; ++first, ++head_)
        {
            *head_ = *first;
        }
    }

    sliding_window(std::initializer_list<T> il)
        : sliding_window(il.begin(), il.end())
    {
    }

    void
    push_back(const T& value)
    {
        *head_ = value;
        ++head_;
    }

    void
    push_back(const T& value, size_type n)
    {
        std::fill_n(head_, n, value);
        head_ += n;
    }

    void
    push_front(const T& value)
    {
        --head_;
        *head_ = value;
    }

    void
    push_front(const T& value, size_type n)
    {
        std::fill_n(std::make_reverse_iterator(head_), n, value);
        head_ -= n;
    }

    reference
    front()
    {
        return *head_;
    }

    const_reference
    front() const
    {
        return *head_;
    }

    reference
    back()
    {
        return *(head_ + Size - 1);
    }

    const_reference
    back() const
    {
        return *(head_ + Size - 1);
    }

    reference operator[](size_type n)
    {
        return head_[n];
    }

    const_reference operator[](size_type n) const
    {
        return head_[n];
    }

    iterator
    begin()
    {
        return head_;
    }

    iterator
    end()
    {
        return head_ + Size;
    }

private:
    iterator head_;
};

template <class Derived, class T, std::size_t Size>
class stack_storage
{
public:
    stack_storage() : buffer_{}
    {
    }

    stack_storage(const stack_storage& other)
    {
        std::copy(std::begin(other.buffer_),
                  std::end(other.buffer_),
                  std::begin(buffer_));
    }

    stack_storage&
    operator=(const stack_storage& other)
    {
        std::copy(std::begin(other.buffer_),
                  std::end(other.buffer_),
                  std::begin(buffer_));
    }

public:
    T*
    begin()
    {
        return buffer_;
    }

    T*
    end()
    {
        return buffer_ + Size;
    }

protected:
    T buffer_[Size];
};

template <class Derived, class T, std::size_t Size>
class static_heap_storage
{
public:
    static_heap_storage() : buffer_(new T[Size]{})
    {
    }

    static_heap_storage(const static_heap_storage& other)
        : static_heap_storage()
    {
        std::copy(
            other.buffer_.get(), other.buffer_.get() + Size, buffer_.get());
    }

    static_heap_storage(static_heap_storage&&) = default;

    static_heap_storage&
    operator=(const static_heap_storage& other)
    {
        auto temp = other;
        swap(*this, temp);
        return *this;
    }

    static_heap_storage& operator=(static_heap_storage&&) = default;

    void
    swap(static_heap_storage& other)
    {
        std::swap(buffer_, other.buffer_);
    }

public:
    T*
    begin()
    {
        return buffer_.get();
    }

    T*
    end()
    {
        return buffer_.get() + Size;
    }

protected:
    std::unique_ptr<T[]> buffer_;
};

template <class T, std::size_t Size>
using stack_sliding_window = sliding_window<T, Size, stack_storage>;

template <class T, std::size_t Size>
using static_heap_sliding_window = sliding_window<T, Size, static_heap_storage>;

namespace detail
{
struct runtime_ratio
{
    runtime_ratio() : num(1), den(1)
    {
    }

    template <std::intmax_t Num, std::intmax_t Denom>
    constexpr runtime_ratio(std::ratio<Num, Denom>) : num(Num), den(Denom)
    {
    }

    std::intmax_t num;
    std::intmax_t den;
};

template <class Numeric>
Numeric operator*(const runtime_ratio& lhs, Numeric rhs)
{
    return rhs * static_cast<Numeric>(lhs.num) / static_cast<Numeric>(lhs.den);
}

template <class Numeric>
Numeric operator*(Numeric lhs, const runtime_ratio& rhs)
{
    return rhs * lhs;
}

template <class Numeric>
Numeric
operator/(Numeric lhs, const runtime_ratio& rhs)
{
    return lhs * static_cast<Numeric>(rhs.den) / static_cast<Numeric>(rhs.num);
}
} // namespace detail

template <class KeyType,
          class ValueType,
          std::size_t Size,
          class Compare = std::less<KeyType>>
class sliding_window_map
{
public:
    typedef std::ptrdiff_t difference_type;

public:
    sliding_window_map() : sliding_buffer_(), precision_(), origin_()
    {
    }

    template <std::intmax_t Num, std::intmax_t Denom>
    sliding_window_map(std::ratio<Num, Denom>)
        : sliding_buffer_(), precision_(std::ratio<Num, Denom>()), origin_()
    {
    }

    sliding_window_map(KeyType origin)
        : sliding_buffer_(), precision_(), origin_(origin / precision_)
    {
    }

    std::pair<KeyType, KeyType>
    window() const
    {
        return std::make_pair(origin_, origin_ + Size * precision_);
    }

    ////////////////////////////////////////////////////////////////////////////
    // map like interface
    ValueType&
    at(KeyType k)
    {
        const auto index = index_of_key(k);
        const Compare c;
        if(c(index, 0) || (!c(index, Size)))
        {
            throw std::out_of_range("Key outside of current window");
        }

        return sliding_buffer_[index];
    }

    ValueType& operator[](KeyType k)
    {
        return sliding_buffer_[(k - origin_) / precision_];
    }

    void
    insert_or_assign(KeyType k, const ValueType& v)
    {
        const auto index = index_of_key(k);
        const Compare c;

        if(c(index, 0))
        {
            // below current window
            sliding_buffer_.push_front(ValueType(), -index);
            sliding_buffer_.front() = v;
            origin_ += index * precision_;
        }
        else if(!c(index, Size))
        {
            // above current window
            sliding_buffer_.push_back(ValueType(), index - Size + 1);
            sliding_buffer_.back() = v;
            origin_ += (index - Size + 1) * precision_;
        }
        else
        {
            // within current window
            sliding_buffer_[index] = v;
        }
    }

private:
    difference_type
    index_of_key(KeyType k)
    {
        return (k - origin_ * precision_) / precision_;
    }

private:
    static_heap_sliding_window<ValueType, Size> sliding_buffer_;
    detail::runtime_ratio precision_;
    difference_type origin_;
};
} // namespace helene
<commit_msg>Add full constructor, taking origin and precision. 	modified:   include/sliding_window.hpp<commit_after>#pragma once

#include <cstddef>
#include <memory>
#include <functional>
#include <ratio>
#include <iterator>
#include <initializer_list>

#include <circular_iterator.hpp>

namespace helene
{
template <class T,
          std::size_t Size,
          template <class, class, std::size_t> class StoragePolicy>
class sliding_window
    : public StoragePolicy<sliding_window<T, Size, StoragePolicy>, T, Size>
{
    typedef StoragePolicy<sliding_window<T, Size, StoragePolicy>, T, Size>
        storage_policy;

public:
    static const std::size_t size = Size;

    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
    typedef circular_iterator<T*> iterator;
    typedef circular_iterator<const T*> const_iterator;

public:
    sliding_window()
        : storage_policy(),
          head_(storage_policy::begin(),
                storage_policy::end(),
                storage_policy::begin())
    {
    }

    template <class Iterator>
    sliding_window(Iterator first, Iterator last) : sliding_window()
    {
        for(; first != last; ++first, ++head_)
        {
            *head_ = *first;
        }
    }

    sliding_window(std::initializer_list<T> il)
        : sliding_window(il.begin(), il.end())
    {
    }

    void
    push_back(const T& value)
    {
        *head_ = value;
        ++head_;
    }

    void
    push_back(const T& value, size_type n)
    {
        std::fill_n(head_, n, value);
        head_ += n;
    }

    void
    push_front(const T& value)
    {
        --head_;
        *head_ = value;
    }

    void
    push_front(const T& value, size_type n)
    {
        std::fill_n(std::make_reverse_iterator(head_), n, value);
        head_ -= n;
    }

    reference
    front()
    {
        return *head_;
    }

    const_reference
    front() const
    {
        return *head_;
    }

    reference
    back()
    {
        return *(head_ + Size - 1);
    }

    const_reference
    back() const
    {
        return *(head_ + Size - 1);
    }

    reference operator[](size_type n)
    {
        return head_[n];
    }

    const_reference operator[](size_type n) const
    {
        return head_[n];
    }

    iterator
    begin()
    {
        return head_;
    }

    iterator
    end()
    {
        return head_ + Size;
    }

private:
    iterator head_;
};

template <class Derived, class T, std::size_t Size>
class stack_storage
{
public:
    stack_storage() : buffer_{}
    {
    }

    stack_storage(const stack_storage& other)
    {
        std::copy(std::begin(other.buffer_),
                  std::end(other.buffer_),
                  std::begin(buffer_));
    }

    stack_storage&
    operator=(const stack_storage& other)
    {
        std::copy(std::begin(other.buffer_),
                  std::end(other.buffer_),
                  std::begin(buffer_));
    }

public:
    T*
    begin()
    {
        return buffer_;
    }

    T*
    end()
    {
        return buffer_ + Size;
    }

protected:
    T buffer_[Size];
};

template <class Derived, class T, std::size_t Size>
class static_heap_storage
{
public:
    static_heap_storage() : buffer_(new T[Size]{})
    {
    }

    static_heap_storage(const static_heap_storage& other)
        : static_heap_storage()
    {
        std::copy(
            other.buffer_.get(), other.buffer_.get() + Size, buffer_.get());
    }

    static_heap_storage(static_heap_storage&&) = default;

    static_heap_storage&
    operator=(const static_heap_storage& other)
    {
        auto temp = other;
        swap(*this, temp);
        return *this;
    }

    static_heap_storage& operator=(static_heap_storage&&) = default;

    void
    swap(static_heap_storage& other)
    {
        std::swap(buffer_, other.buffer_);
    }

public:
    T*
    begin()
    {
        return buffer_.get();
    }

    T*
    end()
    {
        return buffer_.get() + Size;
    }

protected:
    std::unique_ptr<T[]> buffer_;
};

template <class T, std::size_t Size>
using stack_sliding_window = sliding_window<T, Size, stack_storage>;

template <class T, std::size_t Size>
using static_heap_sliding_window = sliding_window<T, Size, static_heap_storage>;

namespace detail
{
struct runtime_ratio
{
    runtime_ratio() : num(1), den(1)
    {
    }

    template <std::intmax_t Num, std::intmax_t Denom>
    constexpr runtime_ratio(std::ratio<Num, Denom>) : num(Num), den(Denom)
    {
    }

    std::intmax_t num;
    std::intmax_t den;
};

template <class Numeric>
Numeric operator*(const runtime_ratio& lhs, Numeric rhs)
{
    return rhs * static_cast<Numeric>(lhs.num) / static_cast<Numeric>(lhs.den);
}

template <class Numeric>
Numeric operator*(Numeric lhs, const runtime_ratio& rhs)
{
    return rhs * lhs;
}

template <class Numeric>
Numeric
operator/(Numeric lhs, const runtime_ratio& rhs)
{
    return lhs * static_cast<Numeric>(rhs.den) / static_cast<Numeric>(rhs.num);
}
} // namespace detail

template <class KeyType,
          class ValueType,
          std::size_t Size,
          class Compare = std::less<KeyType>>
class sliding_window_map
{
public:
    typedef std::ptrdiff_t difference_type;

public:
    sliding_window_map() : sliding_buffer_(), precision_(), origin_()
    {
    }

    template <std::intmax_t Num, std::intmax_t Denom>
    sliding_window_map(std::ratio<Num, Denom>)
        : sliding_buffer_(), precision_(std::ratio<Num, Denom>()), origin_()
    {
    }

    sliding_window_map(KeyType origin)
        : sliding_buffer_(), precision_(), origin_(origin / precision_)
    {
    }

    template <std::intmax_t Num, std::intmax_t Denom>
    sliding_window_map(KeyType origin, std::ratio<Num, Denom>)
        : sliding_buffer_(),
          precision_(std::ratio<Num, Denom>()),
          origin_(origin / precision_)
    {
    }

    std::pair<KeyType, KeyType>
    window() const
    {
        return std::make_pair(origin_, origin_ + Size * precision_);
    }

    ////////////////////////////////////////////////////////////////////////////
    // map like interface
    ValueType&
    at(KeyType k)
    {
        const auto index = index_of_key(k);
        const Compare c;
        if(c(index, 0) || (!c(index, Size)))
        {
            throw std::out_of_range("Key outside of current window");
        }

        return sliding_buffer_[index];
    }

    ValueType& operator[](KeyType k)
    {
        return sliding_buffer_[(k - origin_) / precision_];
    }

    void
    insert_or_assign(KeyType k, const ValueType& v)
    {
        const auto index = index_of_key(k);
        const Compare c;

        if(c(index, 0))
        {
            // below current window
            sliding_buffer_.push_front(ValueType(), -index);
            sliding_buffer_.front() = v;
            origin_ += index * precision_;
        }
        else if(!c(index, Size))
        {
            // above current window
            sliding_buffer_.push_back(ValueType(), index - Size + 1);
            sliding_buffer_.back() = v;
            origin_ += (index - Size + 1) * precision_;
        }
        else
        {
            // within current window
            sliding_buffer_[index] = v;
        }
    }

private:
    difference_type
    index_of_key(KeyType k)
    {
        return (k - origin_ * precision_) / precision_;
    }

private:
    static_heap_sliding_window<ValueType, Size> sliding_buffer_;
    detail::runtime_ratio precision_;
    difference_type origin_;
};
} // namespace helene
<|endoftext|>


<commit_before>/*
* VMMLib - Vector & Matrix Math Lib
*
* @author Stefan Eilemann
*
* @license revised BSD license, check LICENSE
*/

#ifndef __VMML__FRUSTUM__HPP__
#define __VMML__FRUSTUM__HPP__

#include <vmmlib/vmmlib_config.hpp>
#include <vmmlib/matrix.hpp>

#include <cmath>

// - declaration -

namespace vmml
{

template< typename T >
class frustum
{
public:
    VMMLIB_ALIGN( T array[6] );

    // contructors
    frustum(); // warning: components NOT initialised ( for performance )
    frustum( const T left, const T right, const T bottom, const T top,
             const T near_plane, const T far_plane );

    template< typename U >
    frustum( const frustum< U >& source_ );

    //the pointer 'values' must be a valid 6 component c array of the resp. type
    template< typename U >
    frustum( const U* values );

    ~frustum();

    const frustum& operator=( const frustum& source_ );
    template< typename U >
    void operator=( const frustum< U >& source_ );

    void set( const T _left, const T _right, const T _bottom,
        const T _top, const T _near, const T _far );

    // set the frustum using the same parameters as gluPerspective.
    void set_perspective( T field_of_view_y, T aspect_ratio, T near_plane_,
        T far_plane );

    matrix< 4, 4, T > compute_matrix() const;
    matrix< 4, 4, T > compute_ortho_matrix() const;

    void compute_matrix( matrix< 4, 4, T >& matrix_ ) const;
    void compute_ortho_matrix( matrix< 4, 4, T >& matrix_ ) const;
    void apply_jitter( const vector< 2, T >& jitter_ );

    // 'move' the frustum. this function changes the near_plane, and adjusts the
    // other parameters in a way that the 'perspective pyramid' stays the same.
    void adjust_near( const T near_plane );

    inline T& left();
    inline const T& left() const;

    inline T& right();
    inline const T& right() const;

    inline T& bottom();
    inline const T& bottom() const;

    inline T& top();
    inline const T& top() const;

    inline T& near_plane();
    inline const T& near_plane() const;

    inline T& far_plane();
    inline const T& far_plane() const;

    inline T get_width() const;
    inline T get_height() const;

    friend std::ostream& operator << ( std::ostream& os, const frustum& frustum_ )
    {
        const std::ios::fmtflags flags = os.flags();
        const int                prec  = os.precision();

        os.setf( std::ios::right, std::ios::adjustfield );
        os.precision( 5 );
        os << "[" << std::setw(10) << frustum_.left() << " "
           << std::setw(10) << frustum_.right()  << " "
           << std::setw(10) << frustum_.bottom() << " "
           << std::setw(10) << frustum_.top()    << " "
           << std::setw(10) << frustum_.near_plane()   << " "
           << std::setw(10) << frustum_.far_plane()    << "]";
        os.precision( prec );
        os.setf( flags );
        return os;
    };

    static const frustum DEFAULT;
};

#ifndef VMMLIB_NO_TYPEDEFS
typedef frustum< float >  frustumf;
typedef frustum< double > frustumd;
#endif

} // namespace vmml

// - implementation - //

namespace vmml
{

template< typename T >
const frustum< T > frustum< T >::DEFAULT( static_cast< T >( -1.0 ),
                                          static_cast< T >( 1.0 ),
                                          static_cast< T >( -1.0 ),
                                          static_cast< T >( 1.0 ),
                                          static_cast< T >( 0.1 ),
                                          static_cast< T >( 100.0 ) );

template < typename T >
frustum< T >::frustum()
{}

template < typename T >
frustum<T>::frustum( const T _left, const T _right, const T _bottom,
                     const T _top, const T _near, const T _far )
{
    set( _left, _right, _bottom, _top, _near, _far );
}

template < typename T >
template< typename U >
frustum< T >::frustum( const frustum< U >& source_ )
{
    (*this) = source_;
}

template < typename T >
template< typename U >
frustum< T >::frustum( const U* values )
{
    assert( values &&
            "frustum: Nullpointer argument as source for initialisation!" );
    left()      = static_cast< T > ( values[0] );
    right()     = static_cast< T > ( values[1] );
    bottom()    = static_cast< T > ( values[2] );
    top()       = static_cast< T > ( values[3] );
    near_plane() = static_cast< T > ( values[4] );
    far_plane()  = static_cast< T > ( values[5] );
}

template < typename T >
frustum< T >::~frustum()
{}

template< typename T >
const frustum< T >&
frustum< T >::operator=( const frustum& source_ )
{
    memcpy( array, source_.array, 6 * sizeof( T ) );
    return *this;
}

template< typename T >
template< typename U >
void
frustum< T >::operator=( const frustum< U >& source_ )
{
    for( size_t index = 0; index < 6; ++index )
    {
        array[ index ] = static_cast< T >( source_.array[ index ] );
    }
}

template < typename T >
void
frustum< T >::set( const T _left, const T _right, const T _bottom,
    const T _top, const T _near, const T _far )
{
    left()      = _left;
    right()     = _right;
    bottom()    = _bottom;
    top()       = _top;
    near_plane() = _near;
    far_plane()  = _far;
}

// 'move' the frustum. this function changes the near_plane, and adjusts the
// other parameters in a way that the 'perspective pyramid' stays the same.
template < typename T >
void
frustum<T>::adjust_near( const T new_near )
{
	if( new_near == near_plane() )
		return;

	const T ratio = new_near / near_plane();
	right()     *= ratio;
	left()      *= ratio;
	top()       *= ratio;
	bottom()    *= ratio;
	near_plane()  = new_near;
}

// set the frustum using the same parameters as gluPerspective.
template < typename T >
void
frustum<T>::set_perspective( T fov_y, T aspect_ratio, T near_plane_,
    T far_plane_ )
{
    near_plane() = near_plane_;
    far_plane()   = far_plane_;

    top()       = tan( 0.5 * fov_y * M_PI / 180.0 ) * 0.5;
    bottom()    = - top();

    left()      = bottom() * aspect_ratio;
    right()     = top() * aspect_ratio;
}

template < typename T >
matrix< 4, 4, T >
frustum<T>::compute_matrix() const
{
    matrix< 4, 4, T > matrix_;
    compute_matrix( matrix_ );
    return matrix_;
}

template < typename T >
void
frustum<T>::compute_matrix( matrix< 4, 4, T >& M ) const
{
    M( 0,0 ) = 2.0 * near_plane() / ( right() - left() );
    M( 0,1 ) = 0.0;
    M( 0,2 ) = ( right() + left() ) / ( right() - left() );
    M( 0,3 ) = 0.0;

    M( 1,0 ) = 0.0;
    M( 1,1 ) = 2.0 * near_plane() / ( top() - bottom() );
    M( 1,2 ) = ( top() + bottom() ) / ( top() - bottom() );
    M( 1,3 ) = 0.0;

    M( 2,0 ) = 0.0;
    M( 2,1 ) = 0.0;
    // NOTE: Some glfrustum man pages say wrongly '(far + near) / (far - near)'
    M( 2,2 ) = -( far_plane() + near_plane() ) / ( far_plane() - near_plane() );
    M( 2,3 ) = -2.0 * far_plane() * near_plane() / ( far_plane() - near_plane() );

    M( 3,0 ) = 0.0;
    M( 3,1 ) = 0.0;
    M( 3,2 ) = -1.0;
    M( 3,3 ) =  0.0;
}

template < typename T >
matrix< 4, 4, T >
frustum< T >::compute_ortho_matrix() const
{
    matrix< 4, 4, T > matrix_;
    compute_ortho_matrix( matrix_ );
    return matrix_;
}

template < typename T >
void
frustum< T >::compute_ortho_matrix( matrix< 4, 4, T >& M ) const
{
    M( 0,0 ) = 2.0 / ( right() - left() );
    M( 0,1 ) = 0.0;
    M( 0,2 ) = 0.0;
    M( 0,3 ) = -( right() + left() ) / ( right() - left() );

    M( 1,0 ) = 0.0;
    M( 1,1 ) = 2.0 / ( top() - bottom() );
    M( 1,2 ) = 0.0f;
    M( 1,3 ) = -( top() + bottom() ) / ( top() - bottom() );

    M( 2,0 ) = 0.0;
    M( 2,1 ) = 0.0;
    M( 2,2 ) = -2.0 / ( far_plane() - near_plane() );
    M( 2,3 ) = -( far_plane() + near_plane() ) / ( far_plane() - near_plane() );

    M( 3,0 ) = 0.0;
    M( 3,1 ) = 0.0;
    M( 3,2 ) = 0.0;
    M( 3,3 ) = 1.0f;
}

template < typename T >
void
frustum< T >::apply_jitter( const vector< 2, T >& jitter_ )
{
    left()   = left() + jitter_.x();
    right()  = right() + jitter_.x();
    bottom() = bottom() + jitter_.y();
    top()    = top() + jitter_.y();
}

template< typename T >
inline T&
frustum< T >::left()
{
    return array[ 0 ];
}

template< typename T >
inline const T&
frustum< T >::left() const
{
    return array[ 0 ];
}

template< typename T >
inline T&
frustum< T >::right()
{
    return array[ 1 ];
}

template< typename T >
inline const T&
frustum< T >::right() const
{
    return array[ 1 ];
}

template< typename T >
inline T&
frustum< T >::bottom()
{
    return array[ 2 ];
}

template< typename T >
inline const T&
frustum< T >::bottom() const
{
    return array[ 2 ];
}

template< typename T >
inline T&
frustum< T >::top()
{
    return array[ 3 ];
}

template< typename T >
inline const T&
frustum< T >::top() const
{
    return array[ 3 ];
}

template< typename T >
inline T&
frustum< T >::near_plane()
{
    return array[ 4 ];
}

template< typename T >
inline const T&
frustum< T >::near_plane() const
{
    return array[ 4 ];
}

template< typename T >
inline T&
frustum< T >::far_plane()
{
    return array[ 5 ];
}

template< typename T >
inline const T&
frustum< T >::far_plane() const
{
    return array[ 5 ];
}

template< typename T > inline T frustum< T >::get_width() const
{
    return fabs( right() - left( ));
}

template< typename T > inline T frustum< T >::get_height() const
{
    return fabs( top() - bottom( ));
}

} //namespace vmml

#endif

<commit_msg>Cosmetics<commit_after>/*
* VMMLib - Vector & Matrix Math Lib
*
* @author Stefan Eilemann
*
* @license revised BSD license, check LICENSE
*/

#ifndef __VMML__FRUSTUM__HPP__
#define __VMML__FRUSTUM__HPP__

#include <vmmlib/vmmlib_config.hpp>
#include <vmmlib/matrix.hpp>

#include <cmath>

// - declaration -

namespace vmml
{

template< typename T >
class frustum
{
public:
    VMMLIB_ALIGN( T array[6] );

    // contructors
    frustum(); // warning: components NOT initialised ( for performance )
    frustum( const T left, const T right, const T bottom, const T top,
             const T near_plane, const T far_plane );

    template< typename U >
    frustum( const frustum< U >& source_ );

    //the pointer 'values' must be a valid 6 component c array of the resp. type
    template< typename U >
    frustum( const U* values );

    ~frustum();

    const frustum& operator=( const frustum& source_ );
    template< typename U >
    void operator=( const frustum< U >& source_ );

    void set( const T _left, const T _right, const T _bottom,
        const T _top, const T _near, const T _far );

    // set the frustum using the same parameters as gluPerspective.
    void set_perspective( T field_of_view_y, T aspect_ratio, T near_plane_,
        T far_plane );

    matrix< 4, 4, T > compute_matrix() const;
    matrix< 4, 4, T > compute_ortho_matrix() const;

    void compute_matrix( matrix< 4, 4, T >& matrix_ ) const;
    void compute_ortho_matrix( matrix< 4, 4, T >& matrix_ ) const;
    void apply_jitter( const vector< 2, T >& jitter_ );

    // 'move' the frustum. this function changes the near_plane, and adjusts the
    // other parameters in a way that the 'perspective pyramid' stays the same.
    void adjust_near( const T near_plane );

    inline T& left();
    inline const T& left() const;

    inline T& right();
    inline const T& right() const;

    inline T& bottom();
    inline const T& bottom() const;

    inline T& top();
    inline const T& top() const;

    inline T& near_plane();
    inline const T& near_plane() const;

    inline T& far_plane();
    inline const T& far_plane() const;

    inline T get_width() const;
    inline T get_height() const;

    friend std::ostream& operator << ( std::ostream& os, const frustum& frustum_ )
    {
        const std::ios::fmtflags flags = os.flags();
        const int                prec  = os.precision();

        os.setf( std::ios::right, std::ios::adjustfield );
        os.precision( 5 );
        os << "[" << std::setw(10) << frustum_.left() << " "
           << std::setw(10) << frustum_.right()  << " "
           << std::setw(10) << frustum_.bottom() << " "
           << std::setw(10) << frustum_.top()    << " "
           << std::setw(10) << frustum_.near_plane()   << " "
           << std::setw(10) << frustum_.far_plane()    << "]";
        os.precision( prec );
        os.setf( flags );
        return os;
    };

    static const frustum DEFAULT;
};

#ifndef VMMLIB_NO_TYPEDEFS
typedef frustum< float >  frustumf;
typedef frustum< double > frustumd;
#endif

} // namespace vmml

// - implementation - //

namespace vmml
{

template< typename T >
const frustum< T > frustum< T >::DEFAULT( static_cast< T >( -1.0 ),
                                          static_cast< T >( 1.0 ),
                                          static_cast< T >( -1.0 ),
                                          static_cast< T >( 1.0 ),
                                          static_cast< T >( 0.1 ),
                                          static_cast< T >( 100.0 ) );

template < typename T >
frustum< T >::frustum()
{}

template < typename T >
frustum<T>::frustum( const T _left, const T _right, const T _bottom,
                     const T _top, const T _near, const T _far )
{
    set( _left, _right, _bottom, _top, _near, _far );
}

template < typename T >
template< typename U >
frustum< T >::frustum( const frustum< U >& source_ )
{
    (*this) = source_;
}

template < typename T >
template< typename U >
frustum< T >::frustum( const U* values )
{
    assert( values &&
            "frustum: Nullpointer argument as source for initialisation!" );
    left()      = static_cast< T > ( values[0] );
    right()     = static_cast< T > ( values[1] );
    bottom()    = static_cast< T > ( values[2] );
    top()       = static_cast< T > ( values[3] );
    near_plane() = static_cast< T > ( values[4] );
    far_plane()  = static_cast< T > ( values[5] );
}

template < typename T >
frustum< T >::~frustum()
{}

template< typename T >
const frustum< T >&
frustum< T >::operator=( const frustum& source_ )
{
    memcpy( array, source_.array, 6 * sizeof( T ) );
    return *this;
}

template< typename T > template< typename U >
void frustum< T >::operator = ( const frustum< U >& source_ )
{
    for( size_t index = 0; index < 6; ++index )
    {
        array[ index ] = static_cast< T >( source_.array[ index ] );
    }
}

template < typename T >
void
frustum< T >::set( const T _left, const T _right, const T _bottom,
    const T _top, const T _near, const T _far )
{
    left()      = _left;
    right()     = _right;
    bottom()    = _bottom;
    top()       = _top;
    near_plane() = _near;
    far_plane()  = _far;
}

// 'move' the frustum. this function changes the near_plane, and adjusts the
// other parameters in a way that the 'perspective pyramid' stays the same.
template < typename T >
void
frustum<T>::adjust_near( const T new_near )
{
	if( new_near == near_plane() )
		return;

	const T ratio = new_near / near_plane();
	right()     *= ratio;
	left()      *= ratio;
	top()       *= ratio;
	bottom()    *= ratio;
	near_plane()  = new_near;
}

// set the frustum using the same parameters as gluPerspective.
template < typename T >
void
frustum<T>::set_perspective( T fov_y, T aspect_ratio, T near_plane_,
    T far_plane_ )
{
    near_plane() = near_plane_;
    far_plane()   = far_plane_;

    top()       = tan( 0.5 * fov_y * M_PI / 180.0 ) * 0.5;
    bottom()    = - top();

    left()      = bottom() * aspect_ratio;
    right()     = top() * aspect_ratio;
}

template < typename T >
matrix< 4, 4, T >
frustum<T>::compute_matrix() const
{
    matrix< 4, 4, T > matrix_;
    compute_matrix( matrix_ );
    return matrix_;
}

template < typename T >
void
frustum<T>::compute_matrix( matrix< 4, 4, T >& M ) const
{
    M( 0,0 ) = 2.0 * near_plane() / ( right() - left() );
    M( 0,1 ) = 0.0;
    M( 0,2 ) = ( right() + left() ) / ( right() - left() );
    M( 0,3 ) = 0.0;

    M( 1,0 ) = 0.0;
    M( 1,1 ) = 2.0 * near_plane() / ( top() - bottom() );
    M( 1,2 ) = ( top() + bottom() ) / ( top() - bottom() );
    M( 1,3 ) = 0.0;

    M( 2,0 ) = 0.0;
    M( 2,1 ) = 0.0;
    // NOTE: Some glfrustum man pages say wrongly '(far + near) / (far - near)'
    M( 2,2 ) = -( far_plane() + near_plane() ) / ( far_plane() - near_plane() );
    M( 2,3 ) = -2.0 * far_plane() * near_plane() / ( far_plane() - near_plane() );

    M( 3,0 ) = 0.0;
    M( 3,1 ) = 0.0;
    M( 3,2 ) = -1.0;
    M( 3,3 ) =  0.0;
}

template < typename T >
matrix< 4, 4, T >
frustum< T >::compute_ortho_matrix() const
{
    matrix< 4, 4, T > matrix_;
    compute_ortho_matrix( matrix_ );
    return matrix_;
}

template < typename T >
void
frustum< T >::compute_ortho_matrix( matrix< 4, 4, T >& M ) const
{
    M( 0,0 ) = 2.0 / ( right() - left() );
    M( 0,1 ) = 0.0;
    M( 0,2 ) = 0.0;
    M( 0,3 ) = -( right() + left() ) / ( right() - left() );

    M( 1,0 ) = 0.0;
    M( 1,1 ) = 2.0 / ( top() - bottom() );
    M( 1,2 ) = 0.0f;
    M( 1,3 ) = -( top() + bottom() ) / ( top() - bottom() );

    M( 2,0 ) = 0.0;
    M( 2,1 ) = 0.0;
    M( 2,2 ) = -2.0 / ( far_plane() - near_plane() );
    M( 2,3 ) = -( far_plane() + near_plane() ) / ( far_plane() - near_plane() );

    M( 3,0 ) = 0.0;
    M( 3,1 ) = 0.0;
    M( 3,2 ) = 0.0;
    M( 3,3 ) = 1.0f;
}

template < typename T >
void frustum< T >::apply_jitter( const vector< 2, T >& jitter_ )
{
    left()   = left() + jitter_.x();
    right()  = right() + jitter_.x();
    bottom() = bottom() + jitter_.y();
    top()    = top() + jitter_.y();
}

template< typename T >
inline T& frustum< T >::left()
{
    return array[ 0 ];
}

template< typename T >
inline const T& frustum< T >::left() const
{
    return array[ 0 ];
}

template< typename T >
inline T& frustum< T >::right()
{
    return array[ 1 ];
}

template< typename T >
inline const T& frustum< T >::right() const
{
    return array[ 1 ];
}

template< typename T >
inline T& frustum< T >::bottom()
{
    return array[ 2 ];
}

template< typename T >
inline const T& frustum< T >::bottom() const
{
    return array[ 2 ];
}

template< typename T >
inline T& frustum< T >::top()
{
    return array[ 3 ];
}

template< typename T >
inline const T& frustum< T >::top() const
{
    return array[ 3 ];
}

template< typename T >
inline T& frustum< T >::near_plane()
{
    return array[ 4 ];
}

template< typename T >
inline const T& frustum< T >::near_plane() const
{
    return array[ 4 ];
}

template< typename T >
inline T& frustum< T >::far_plane()
{
    return array[ 5 ];
}

template< typename T >
inline const T& frustum< T >::far_plane() const
{
    return array[ 5 ];
}

template< typename T > inline T frustum< T >::get_width() const
{
    return fabs( right() - left( ));
}

template< typename T > inline T frustum< T >::get_height() const
{
    return fabs( top() - bottom( ));
}

} //namespace vmml

#endif

<|endoftext|>


<commit_before>// Project specific
#include <Manager/FrequencyAffectedObjectManager.hpp>
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <EntityComponent/EntityHandler.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/RigidBodyComponent.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/PlatformPatrolComponent.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <Doremi/Core/Include/PlayerHandler.hpp>
#include <Doremi/Core/Include/Helper/ProximityChecker.hpp>
#include <Doremi/Core/Include/FrequencyBufferHandler.hpp>

#include <DirectXMath.h>
// Third party

// Standard
#include <iostream>
#include <algorithm>
using namespace std;

namespace Doremi
{
    namespace Core
    {
        FrequencyAffectedObjectManager::FrequencyAffectedObjectManager(const DoremiEngine::Core::SharedContext& p_sharedContext)
            : Manager(p_sharedContext, "FrequencyAffectedObjectManager")
        {
            m_frequencyNormalizer = 1000.0f;
        }

        FrequencyAffectedObjectManager::~FrequencyAffectedObjectManager() {}

        void FrequencyAffectedObjectManager::Update(double p_dt)
        {
            // First get the playermap from player handler
            std::map<uint32_t, Player*> t_playerMap = PlayerHandler::GetInstance()->GetPlayerMap();

            for(auto playerID = t_playerMap.begin(); playerID != t_playerMap.end(); playerID++)
            {
                // Get the players current frequency
                float t_currentFrequency = playerID->second->m_frequencyBufferHandler->GetFrequencyForFrame() / 1000.0f;
                t_currentFrequency = std::min(t_currentFrequency, 1.0f);
                std::cout << t_currentFrequency << endl;
                // Loop through all entities
                const size_t length = EntityHandler::GetInstance().GetLastEntityIndex();
                // Loop over all entities to perform various functions on enteties that have sound components
                for(size_t j = 0; j < length; j++)
                {
                    // Check if entity will be affected by the frequencyanalyser.
                    if(EntityHandler::GetInstance().HasComponents(j, (int)ComponentType::FrequencyAffected))
                    {
                        // Code for other frequency affected objects here

                        // Update the platformpatrollers. First by making it move towards start position.
                        if(EntityHandler::GetInstance().HasComponents(j, (int)ComponentType::PlatFormPatrolComponent))
                        {
                            if(ProximityChecker::GetInstance().CheckProximityToEntity(playerID->second->m_playerEntityID, j))
                            {
                                UpdatePlatformPatrollerFrequencyMovement(j, t_currentFrequency);
                            }
                            else
                            {
                                UpdatePlatformPatrollerFrequencyMovement(j, 0);
                            }
                        }
                    }
                }
            }
        }
        void FrequencyAffectedObjectManager::UpdatePlatformPatrollerMoveTowardsStartPosistion(int p_entityID)
        {
            using namespace DirectX;
            PlatformPatrolComponent* t_platformPatrolComp = EntityHandler::GetInstance().GetComponentFromStorage<PlatformPatrolComponent>(p_entityID);
            TransformComponent* t_transformComponent = EntityHandler::GetInstance().GetComponentFromStorage<TransformComponent>(p_entityID);

            // First apply the "want to move to starting position"
            XMFLOAT3 t_moveTowardsStartPosition;
            XMStoreFloat3(&t_moveTowardsStartPosition,
                          XMVector3Normalize(XMLoadFloat3(&t_platformPatrolComp->startPosition) - XMLoadFloat3(&t_transformComponent->position)));

            m_sharedContext.GetPhysicsModule().GetRigidBodyManager().MoveKinematicActor(p_entityID, XMFLOAT3(t_moveTowardsStartPosition.x * 0.01,
                                                                                t_moveTowardsStartPosition.y * 0.01,
                                                                                t_moveTowardsStartPosition.z * 0.01));
        }

        void FrequencyAffectedObjectManager::UpdatePlatformPatrollerFrequencyMovement(int p_entityID, float p_currentFrequency)
        {
            using namespace DirectX;
            PlatformPatrolComponent* t_platformPatrolComp = EntityHandler::GetInstance().GetComponentFromStorage<PlatformPatrolComponent>(p_entityID);
            TransformComponent* t_transformComponent = EntityHandler::GetInstance().GetComponentFromStorage<TransformComponent>(p_entityID);
            XMFLOAT3 t_desiredPosition;

            // Get the vector between the two points
            XMVECTOR t_direction = XMLoadFloat3(&t_platformPatrolComp->endPosition) - XMLoadFloat3(&t_platformPatrolComp->startPosition);

            // Calculate the desiredposition if frequency is held steady: take the vector between start and end. multiply with frequencyvalue 0 to 1.
            // And add the start position
            XMStoreFloat3(&t_desiredPosition, p_currentFrequency * t_direction + XMLoadFloat3(&t_platformPatrolComp->startPosition));

            // Get the direction again. This is from desired position to actual position. So we know what way to move
            XMVECTOR t_newDirection = XMLoadFloat3(&t_desiredPosition) - XMLoadFloat3(&t_transformComponent->position);

            // Get the distance between desired and actual position of the platform
            XMFLOAT3 t_distanceBetweenDesiredAndActualPosition;
            XMStoreFloat3(&t_distanceBetweenDesiredAndActualPosition, XMVector3Length(t_newDirection));

            // Get the normalized Vector between the to maximumpoints Then we move along that vector using the distance between desired and actual
            // position Removed desired to actual. Now steady Movespeed
            XMFLOAT3 t_normalizedDirection;
            XMFLOAT3 t_velocityVector;
            // If statement so that it doesnt "miss" the start position and wobbles around it. Same with end position
            if(t_distanceBetweenDesiredAndActualPosition.x > 0.4)
            {
                XMStoreFloat3(&t_velocityVector, XMVector3Normalize(t_newDirection) /** t_distanceBetweenDesiredAndActualPosition.x */ * 0.3);
                m_sharedContext.GetPhysicsModule().GetRigidBodyManager().MoveKinematicActor(p_entityID,
                                                                                t_velocityVector); // TODOLH This removes the update
            }
            else
            {
                // Do nothing
            }

            // Set the velocity of the platform to the vector we just calculated
        }
    }
}
<commit_msg>Removed a spamming cout<commit_after>// Project specific
#include <Manager/FrequencyAffectedObjectManager.hpp>
#include <DoremiEngine/Physics/Include/PhysicsModule.hpp>
#include <EntityComponent/EntityHandler.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/RigidBodyComponent.hpp>
#include <EntityComponent/Components/TransformComponent.hpp>
#include <EntityComponent/Components/PlatformPatrolComponent.hpp>
#include <DoremiEngine/Physics/Include/RigidBodyManager.hpp>
#include <Doremi/Core/Include/PlayerHandler.hpp>
#include <Doremi/Core/Include/Helper/ProximityChecker.hpp>
#include <Doremi/Core/Include/FrequencyBufferHandler.hpp>

#include <DirectXMath.h>
// Third party

// Standard
#include <iostream>
#include <algorithm>
using namespace std;

namespace Doremi
{
    namespace Core
    {
        FrequencyAffectedObjectManager::FrequencyAffectedObjectManager(const DoremiEngine::Core::SharedContext& p_sharedContext)
            : Manager(p_sharedContext, "FrequencyAffectedObjectManager")
        {
            m_frequencyNormalizer = 1000.0f;
        }

        FrequencyAffectedObjectManager::~FrequencyAffectedObjectManager() {}

        void FrequencyAffectedObjectManager::Update(double p_dt)
        {
            // First get the playermap from player handler
            std::map<uint32_t, Player*> t_playerMap = PlayerHandler::GetInstance()->GetPlayerMap();

            for(auto playerID = t_playerMap.begin(); playerID != t_playerMap.end(); playerID++)
            {
                // Get the players current frequency
                float t_currentFrequency = playerID->second->m_frequencyBufferHandler->GetFrequencyForFrame() / 1000.0f;
                t_currentFrequency = std::min(t_currentFrequency, 1.0f);
                // Loop through all entities
                const size_t length = EntityHandler::GetInstance().GetLastEntityIndex();
                // Loop over all entities to perform various functions on enteties that have sound components
                for(size_t j = 0; j < length; j++)
                {
                    // Check if entity will be affected by the frequencyanalyser.
                    if(EntityHandler::GetInstance().HasComponents(j, (int)ComponentType::FrequencyAffected))
                    {
                        // Code for other frequency affected objects here

                        // Update the platformpatrollers. First by making it move towards start position.
                        if(EntityHandler::GetInstance().HasComponents(j, (int)ComponentType::PlatFormPatrolComponent))
                        {
                            if(ProximityChecker::GetInstance().CheckProximityToEntity(playerID->second->m_playerEntityID, j))
                            {
                                UpdatePlatformPatrollerFrequencyMovement(j, t_currentFrequency);
                            }
                            else
                            {
                                UpdatePlatformPatrollerFrequencyMovement(j, 0);
                            }
                        }
                    }
                }
            }
        }
        void FrequencyAffectedObjectManager::UpdatePlatformPatrollerMoveTowardsStartPosistion(int p_entityID)
        {
            using namespace DirectX;
            PlatformPatrolComponent* t_platformPatrolComp = EntityHandler::GetInstance().GetComponentFromStorage<PlatformPatrolComponent>(p_entityID);
            TransformComponent* t_transformComponent = EntityHandler::GetInstance().GetComponentFromStorage<TransformComponent>(p_entityID);

            // First apply the "want to move to starting position"
            XMFLOAT3 t_moveTowardsStartPosition;
            XMStoreFloat3(&t_moveTowardsStartPosition,
                          XMVector3Normalize(XMLoadFloat3(&t_platformPatrolComp->startPosition) - XMLoadFloat3(&t_transformComponent->position)));

            m_sharedContext.GetPhysicsModule().GetRigidBodyManager().MoveKinematicActor(p_entityID, XMFLOAT3(t_moveTowardsStartPosition.x * 0.01,
                                                                                t_moveTowardsStartPosition.y * 0.01,
                                                                                t_moveTowardsStartPosition.z * 0.01));
        }

        void FrequencyAffectedObjectManager::UpdatePlatformPatrollerFrequencyMovement(int p_entityID, float p_currentFrequency)
        {
            using namespace DirectX;
            PlatformPatrolComponent* t_platformPatrolComp = EntityHandler::GetInstance().GetComponentFromStorage<PlatformPatrolComponent>(p_entityID);
            TransformComponent* t_transformComponent = EntityHandler::GetInstance().GetComponentFromStorage<TransformComponent>(p_entityID);
            XMFLOAT3 t_desiredPosition;

            // Get the vector between the two points
            XMVECTOR t_direction = XMLoadFloat3(&t_platformPatrolComp->endPosition) - XMLoadFloat3(&t_platformPatrolComp->startPosition);

            // Calculate the desiredposition if frequency is held steady: take the vector between start and end. multiply with frequencyvalue 0 to 1.
            // And add the start position
            XMStoreFloat3(&t_desiredPosition, p_currentFrequency * t_direction + XMLoadFloat3(&t_platformPatrolComp->startPosition));

            // Get the direction again. This is from desired position to actual position. So we know what way to move
            XMVECTOR t_newDirection = XMLoadFloat3(&t_desiredPosition) - XMLoadFloat3(&t_transformComponent->position);

            // Get the distance between desired and actual position of the platform
            XMFLOAT3 t_distanceBetweenDesiredAndActualPosition;
            XMStoreFloat3(&t_distanceBetweenDesiredAndActualPosition, XMVector3Length(t_newDirection));

            // Get the normalized Vector between the to maximumpoints Then we move along that vector using the distance between desired and actual
            // position Removed desired to actual. Now steady Movespeed
            XMFLOAT3 t_normalizedDirection;
            XMFLOAT3 t_velocityVector;
            // If statement so that it doesnt "miss" the start position and wobbles around it. Same with end position
            if(t_distanceBetweenDesiredAndActualPosition.x > 0.4)
            {
                XMStoreFloat3(&t_velocityVector, XMVector3Normalize(t_newDirection) /** t_distanceBetweenDesiredAndActualPosition.x */ * 0.3);
                m_sharedContext.GetPhysicsModule().GetRigidBodyManager().MoveKinematicActor(p_entityID,
                                                                                t_velocityVector); // TODOLH This removes the update
            }
            else
            {
                // Do nothing
            }

            // Set the velocity of the platform to the vector we just calculated
        }
    }
}
<|endoftext|>


<commit_before>//// License: Apache 2.0. See LICENSE file in root directory.
//// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#include "camera-age.h"
#include <string>

namespace librealsense {
namespace algo {
namespace camera_age {
namespace l500 {

work_week::work_week( std::time_t & t )
{
    auto time = std::localtime( t );
    int year = time->tm_year + 1900;  // The tm_year field contains the number of years
                                      // since 1900, we add 1900 to get current year
    int ww = time->tm_yday / 7;       // The tm_yday field contains the number of days sine 1st
                                      // of January, we divide by 7 to get current work week
    ww++;  // We add 1 because work weeks start at 1 and not 0 (ex. 1st of January will return
           // ww 0, but it ww 1)
    return work_week( year, ww );
}

unsigned work_week::get_year() const
{
    return man_year;
}

unsigned work_week::get_work_week() const
{
    return man_ww;
}

unsigned work_week::operator-( const work_week & ww ) const
{
    return ( ( this->get_year() - ww.get_year() ) * 52 )  // There are 52 weeks in a year
         + ( this->get_work_week() - ww.get_work_week() );
}
// The Serial Number format is PYWWXXXX:
// P  Site Name(ex.F for Fabrinet)
// Y  Year(ex.9 for 2019, "0" for 2020, , "1" for 2021  ..etc)
// WW  Work Week
// XXXX  Sequential number
work_week get_manufature_work_week( const std::string & serial )
{
    unsigned Y = serial[1] - '0';  // Converts char to int, '0'-> 0, '1'-> 1, ...
    unsigned man_year = 0;
    // using Y from serial number to get manufactoring year
    if( Y == 9 )
        man_year = 2019;
    else
        man_year = 2020 + Y;
    // using WW from serial number to get manufactoring work week
    unsigned man_ww = ( ( serial[2] - '0' ) * 10 ) + ( serial[3] - '0' );
    return work_week( man_year, man_ww );
}

unsigned get_work_weeks_since( const work_week & start )
{
    auto t = ( std::time( nullptr ) );
    work_week now( t );
    unsigned age = now - start;
    return age;
}

}  // namespace l500
}  // namespace camera_age
}  // namespace algo
}  // namespace librealsense<commit_msg>added serial number checks<commit_after>//// License: Apache 2.0. See LICENSE file in root directory.
//// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#include "camera-age.h"
#include <string>

namespace librealsense {
namespace algo {
namespace camera_age {
namespace l500 {

work_week::work_week( std::time_t & t )
{
    auto time = std::localtime( t );
    int year = time->tm_year + 1900;  // The tm_year field contains the number of years
                                      // since 1900, we add 1900 to get current year
    int ww = time->tm_yday / 7;       // The tm_yday field contains the number of days sine 1st
                                      // of January, we divide by 7 to get current work week
    ww++;  // We add 1 because work weeks start at 1 and not 0 (ex. 1st of January will return
           // ww 0, but it ww 1)
    return work_week( year, ww );
}

unsigned work_week::get_year() const
{
    return man_year;
}

unsigned work_week::get_work_week() const
{
    return man_ww;
}

unsigned work_week::operator-( const work_week & ww ) const
{
    return ( ( this->get_year() - ww.get_year() ) * 52 )  // There are 52 weeks in a year
         + ( this->get_work_week() - ww.get_work_week() );
}
// The Serial Number format is PYWWXXXX:
// P  Site Name(ex.F for Fabrinet)
// Y  Year(ex.9 for 2019, "0" for 2020, , "1" for 2021  ..etc)
// WW  Work Week
// XXXX  Sequential number
work_week get_manufature_work_week( const std::string & serial )
{
    if( serial.size() != 8 )
        throw invalid_value_exception( "invalid serial number: " + serial + " is of invalid size" );
    unsigned Y = serial[1] - '0';  // Converts char to int, '0'-> 0, '1'-> 1, ...
    unsigned man_year = 0;
    // using Y from serial number to get manufactoring year
    if( Y == 9 )
        man_year = 2019;
    else if( Y >= 0 && Y <= 8 )
        man_year = 2020 + Y;
    else
        throw invalid_value_exception( "invalid serial number: " + serial + " has invalid year" );
    // using WW from serial number to get manufactoring work week
    unsigned WW_tens = serial[2] - '0';
    unsigned WW_singles = serial[3] - '0';
    if( WW_tens > 9 || WW_tens < 0 || WW_singles > 9 || WW_singles < 0 )
        throw invalid_value_exception( "invalid serial number: " + serial
                                       + " has invalid work week" );
    unsigned man_ww = ( (WW_tens)*10 ) + WW_singles;
    return work_week( man_year, man_ww );
}

unsigned get_work_weeks_since( const work_week & start )
{
    auto t = ( std::time( nullptr ) );
    work_week now( t );
    unsigned age = now - start;
    return age;
}

}  // namespace l500
}  // namespace camera_age
}  // namespace algo
}  // namespace librealsense<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
//  Copyright (c) 2009-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is licensed under the Apache License, Version 2.0 (the
//  "License"); you may not use this file except in compliance with the
//  License. You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// __END_LICENSE__

#include <asp/Sessions/RPC/RPCMapTransform.h>
#include <vw/Image/MaskViews.h>
#include <vw/Cartography.h>

using namespace vw;

namespace asp {

  RPCMapTransform::RPCMapTransform( RPCModel const& rpc,
                                    cartography::GeoReference const& image_georef,
                                    cartography::GeoReference const& dem_georef,
                                    boost::shared_ptr<DiskImageResource> dem_rsrc ) :
    m_rpc(rpc), m_image_georef(image_georef), m_dem_georef(dem_georef),
    m_dem(dem_rsrc) {
    using namespace vw;
    using namespace vw::cartography;

    if ( dem_rsrc->has_nodata_read() )
      m_point_cloud =
        geo_transform(
          geodetic_to_cartesian(
            dem_to_geodetic( create_mask( m_dem, dem_rsrc->nodata_read()),
                             m_dem_georef ), m_dem_georef.datum() ),
          m_dem_georef, m_image_georef,
          ValueEdgeExtension<Vector3>( Vector3() ),
          BicubicInterpolation());
    else
      m_point_cloud =
        geo_transform(
          geodetic_to_cartesian(
            dem_to_geodetic( m_dem, m_dem_georef ),
            m_dem_georef.datum() ),
          m_dem_georef, m_image_georef,
          ValueEdgeExtension<Vector3>( Vector3() ),
          BicubicInterpolation());
  }

  vw::Vector2
  RPCMapTransform::reverse(const vw::Vector2 &p) const {

    Vector3 xyz =
      m_cache_size.contains( p ) ?
      m_point_cloud_cache(p.x() - m_cache_size.min().x(),
                          p.y() - m_cache_size.min().y()):
      m_point_cloud(p.x(),p.y());

    return m_rpc.point_to_pixel(xyz);
  }

  // This function will be called whenever we start to apply the
  // transform in a tile. It computes and caches the point cloud at
  // each pixel in the tile, to be used later when we iterate over
  // pixels.
  vw::BBox2i
  RPCMapTransform::reverse_bbox( vw::BBox2i const& bbox ) const {
    cache_dem( bbox );
    return vw::TransformBase<RPCMapTransform>::reverse_bbox( bbox );
  }

  void
  RPCMapTransform::cache_dem( vw::BBox2i const& bbox ) const {
    m_point_cloud_cache = crop( m_point_cloud, bbox );
    m_cache_size = bbox;
  }
}
<commit_msg>RPC: Must interpolate if at a non-integer location<commit_after>// __BEGIN_LICENSE__
//  Copyright (c) 2009-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is licensed under the Apache License, Version 2.0 (the
//  "License"); you may not use this file except in compliance with the
//  License. You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// __END_LICENSE__

#include <asp/Sessions/RPC/RPCMapTransform.h>
#include <vw/Image/MaskViews.h>
#include <vw/Cartography.h>

using namespace vw;

namespace asp {

  RPCMapTransform::RPCMapTransform( RPCModel const& rpc,
                                    cartography::GeoReference const& image_georef,
                                    cartography::GeoReference const& dem_georef,
                                    boost::shared_ptr<DiskImageResource> dem_rsrc ) :
    m_rpc(rpc), m_image_georef(image_georef), m_dem_georef(dem_georef),
    m_dem(dem_rsrc) {
    using namespace vw;
    using namespace vw::cartography;

    if ( dem_rsrc->has_nodata_read() )
      m_point_cloud =
        geo_transform(
          geodetic_to_cartesian(
            dem_to_geodetic( create_mask( m_dem, dem_rsrc->nodata_read()),
                             m_dem_georef ), m_dem_georef.datum() ),
          m_dem_georef, m_image_georef,
          ValueEdgeExtension<Vector3>( Vector3() ),
          BicubicInterpolation());
    else
      m_point_cloud =
        geo_transform(
          geodetic_to_cartesian(
            dem_to_geodetic( m_dem, m_dem_georef ),
            m_dem_georef.datum() ),
          m_dem_georef, m_image_georef,
          ValueEdgeExtension<Vector3>( Vector3() ),
          BicubicInterpolation());
  }

  vw::Vector2
  RPCMapTransform::reverse(const vw::Vector2 &p) const {

    // If possible, we will interpolate into the cached point cloud
    ImageViewRef<Vector3> interp_point_cloud =
      interpolate(m_point_cloud_cache, BicubicInterpolation(), ZeroEdgeExtension());

    BBox2i shrank_bbox = m_cache_size;
    shrank_bbox.expand(-BicubicInterpolation::pixel_buffer); // Avoid interpolating close to edges
    Vector3 xyz =
      shrank_bbox.contains( p ) ?
      interp_point_cloud(p.x() - m_cache_size.min().x(),
                         p.y() - m_cache_size.min().y()):
      m_point_cloud(p.x(),p.y());

    return m_rpc.point_to_pixel(xyz);
  }

  // This function will be called whenever we start to apply the
  // transform in a tile. It computes and caches the point cloud at
  // each pixel in the tile, to be used later when we iterate over
  // pixels.
  vw::BBox2i
  RPCMapTransform::reverse_bbox( vw::BBox2i const& bbox ) const {
    cache_dem( bbox );
    return vw::TransformBase<RPCMapTransform>::reverse_bbox( bbox );
  }

  void
  RPCMapTransform::cache_dem( vw::BBox2i const& bbox ) const {
    m_cache_size = bbox;
    m_cache_size.expand(BicubicInterpolation::pixel_buffer); // For bicubic interpolation later
    m_point_cloud_cache = crop( m_point_cloud, m_cache_size );
  }
}
<|endoftext|>


<commit_before>/**
 * @file HoughCircle_Demo.cpp
 * @brief Demo code for Hough Transform
 * @author OpenCV team
 */

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;

namespace
{
    // windows and trackbars name
    const std::string windowName = "Hough Circle Detection Demo";
    const std::string cannyThresholdTrackbarName = "Canny threshold";
    const std::string accumulatorThresholdTrackbarName = "Accumulator Threshold";

    // initial and max values of the parameters of interests.
    const int cannyThresholdInitialValue = 200;
    const int accumulatorThresholdInitialValue = 50;
    const int maxAccumulatorThreshold = 200;
    const int maxCannyThreshold = 255;

    void HoughDetection(const Mat& src_gray, const Mat& src_display, int cannyThreshold, int accumulatorThreshold)
    {
        // will hold the results of the detection
        std::vector<Vec3f> circles;
        // runs the actual detection
        HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8, cannyThreshold, accumulatorThreshold, 0, 0 );

        // clone the colour, input image for displaying purposes
        Mat display = src_display.clone();
        for( size_t i = 0; i < circles.size(); i++ )
        {
            Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
            int radius = cvRound(circles[i][2]);
            // circle center
            circle( display, center, 3, Scalar(0,255,0), -1, 8, 0 );
            // circle outline
            circle( display, center, radius, Scalar(0,0,255), 3, 8, 0 );
        }

        // shows the results
        imshow( windowName, display);
    }
}

int main(int, char** argv)
{
    Mat src, src_gray;

    // Read the image
    src = imread( argv[1], 1 );

    if( !src.data )
    {
        std::cerr<<"Invalid input image\n";
        std::cout<<"Usage : tutorial_HoughCircle_Demo <path_to_input_image>\n";
        return -1;
    }

    // Convert it to gray
    cvtColor( src, src_gray, COLOR_BGR2GRAY );

    // Reduce the noise so we avoid false circle detection
    GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );

    //declare and initialize both parameters that are subjects to change
    int cannyThreshold = cannyThresholdInitialValue;
    int accumulatorThreshold = accumulatorThresholdInitialValue;

    // create the main window, and attach the trackbars
    namedWindow( windowName, WINDOW_AUTOSIZE );
    createTrackbar(cannyThresholdTrackbarName, windowName, &cannyThreshold,maxCannyThreshold);
    createTrackbar(accumulatorThresholdTrackbarName, windowName, &accumulatorThreshold, maxAccumulatorThreshold);

    // infinite loop to display
    // and refresh the content of the output image
    // until the user presses q or Q
    int key = 0;
    while(key != 'q' && key != 'Q')
    {
        // those paramaters cannot be =0
        // so we must check here
        cannyThreshold = std::max(cannyThreshold, 1);
        accumulatorThreshold = std::max(accumulatorThreshold, 1);

        //runs the detection, and update the display
        HoughDetection(src_gray, src, cannyThreshold, accumulatorThreshold);

        // get user key
        key = waitKey(10);
    }

    return 0;
}
<commit_msg>fix exception being thrown when no arguments are passed<commit_after>/**
 * @file HoughCircle_Demo.cpp
 * @brief Demo code for Hough Transform
 * @author OpenCV team
 */

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;

namespace
{
    // windows and trackbars name
    const std::string windowName = "Hough Circle Detection Demo";
    const std::string cannyThresholdTrackbarName = "Canny threshold";
    const std::string accumulatorThresholdTrackbarName = "Accumulator Threshold";
    const std::string usage = "Usage : tutorial_HoughCircle_Demo <path_to_input_image>\n";

    // initial and max values of the parameters of interests.
    const int cannyThresholdInitialValue = 200;
    const int accumulatorThresholdInitialValue = 50;
    const int maxAccumulatorThreshold = 200;
    const int maxCannyThreshold = 255;

    void HoughDetection(const Mat& src_gray, const Mat& src_display, int cannyThreshold, int accumulatorThreshold)
    {
        // will hold the results of the detection
        std::vector<Vec3f> circles;
        // runs the actual detection
        HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8, cannyThreshold, accumulatorThreshold, 0, 0 );

        // clone the colour, input image for displaying purposes
        Mat display = src_display.clone();
        for( size_t i = 0; i < circles.size(); i++ )
        {
            Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
            int radius = cvRound(circles[i][2]);
            // circle center
            circle( display, center, 3, Scalar(0,255,0), -1, 8, 0 );
            // circle outline
            circle( display, center, radius, Scalar(0,0,255), 3, 8, 0 );
        }

        // shows the results
        imshow( windowName, display);
    }
}

int main(int argc, char** argv)
{
    Mat src, src_gray;

    if (argc < 2)
    {
        std::cerr<<"No input image specified\n";
        std::cout<<usage;
        return -1;
    }

    // Read the image
    src = imread( argv[1], 1 );

    if( !src.data )
    {
        std::cerr<<"Invalid input image\n";
        std::cout<<usage;
        return -1;
    }

    // Convert it to gray
    cvtColor( src, src_gray, COLOR_BGR2GRAY );

    // Reduce the noise so we avoid false circle detection
    GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );

    //declare and initialize both parameters that are subjects to change
    int cannyThreshold = cannyThresholdInitialValue;
    int accumulatorThreshold = accumulatorThresholdInitialValue;

    // create the main window, and attach the trackbars
    namedWindow( windowName, WINDOW_AUTOSIZE );
    createTrackbar(cannyThresholdTrackbarName, windowName, &cannyThreshold,maxCannyThreshold);
    createTrackbar(accumulatorThresholdTrackbarName, windowName, &accumulatorThreshold, maxAccumulatorThreshold);

    // infinite loop to display
    // and refresh the content of the output image
    // until the user presses q or Q
    int key = 0;
    while(key != 'q' && key != 'Q')
    {
        // those paramaters cannot be =0
        // so we must check here
        cannyThreshold = std::max(cannyThreshold, 1);
        accumulatorThreshold = std::max(accumulatorThreshold, 1);

        //runs the detection, and update the display
        HoughDetection(src_gray, src, cannyThreshold, accumulatorThreshold);

        // get user key
        key = waitKey(10);
    }

    return 0;
}
<|endoftext|>


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

#include "channel.h"

#include <stdio.h>
#include <sys/mman.h>

#include <cstdint>
#include <iostream>

#include "lib/ghost.h"

namespace ghost {

// static
ghost_msg Message::kEmpty = {
    .type = 0,
    .length = 0,
    .seqnum = 0,
};

LocalChannel::LocalChannel(int elems, int node, CpuList cpulist)
    : Channel(), elems_(elems), node_(node) {
  fd_ = Ghost::CreateQueue(elems_, node_, 0, map_size_);
  CHECK_GT(fd_, 0);

  header_ = static_cast<ghost_queue_header*>(
      mmap(nullptr, map_size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
  CHECK_NE(header_, MAP_FAILED);
  elems_ = header_->nelems;

  if (!cpulist.Empty()) {
    CHECK_ZERO(Ghost::ConfigQueueWakeup(fd_, cpulist, /*flags=*/0));
  }
};

LocalChannel::~LocalChannel() {
  munmap(header_, map_size_);
  close(fd_);
}

bool LocalChannel::AssociateTask(Gtid gtid, int barrier, int* status) const {
  return Ghost::AssociateQueue(
      fd_, GHOST_TASK, gtid.id(), barrier, 0, status) == 0;
}

void LocalChannel::Consume(const Message& msg) {
  ghost_ring* r = reinterpret_cast<ghost_ring*>(
      reinterpret_cast<char*>(header_) + header_->start);
  const int slot_size = sizeof(ghost_msg);

  uint32_t tail = r->tail.load(std::memory_order_acquire);

  // static_cast<uint32_t> to ensure that msg.length() is properly rounded up.
  // Otherwise if 'msg.length() + slot_size >= 65536' we'll end up only using
  // least significant 16-bits.
  tail += roundup2(static_cast<uint32_t>(msg.length()), slot_size) / slot_size;
  r->tail.store(tail, std::memory_order_release);
}

Message LocalChannel::Peek() const {
  ghost_ring* r = reinterpret_cast<ghost_ring*>(
      reinterpret_cast<char*>(header_) + header_->start);
  uint32_t tidx;

  const uint32_t nelems = header_->nelems;

  const uint32_t tail = r->tail.load(std::memory_order_acquire);
  const uint32_t head = r->head.load(std::memory_order_acquire);

  if (tail == head) return Message();  // Empty message.

  const uint32_t overflow = r->overflow.load(std::memory_order_acquire);
  CHECK_EQ(overflow, 0);

  tidx = tail & (nelems - 1);
  return Message(&r->msgs[tidx]);
}

bool LocalChannel::SetEnclaveDefault() const {
  return Ghost::SetDefaultQueue(fd_) == 0;
}

absl::string_view Message::describe_type() const {
  switch (type()) {
    case MSG_NOP:
      return "MSG_NOP";
    case MSG_TASK_DEAD:
      return "MSG_TASK_DEAD";
    case MSG_TASK_BLOCKED:
      return "MSG_TASK_BLOCKED";
    case MSG_TASK_WAKEUP:
      return "MSG_TASK_WAKEUP";
    case MSG_TASK_NEW:
      return "MSG_TASK_NEW";
    case MSG_TASK_PREEMPT:
      return "MSG_TASK_PREEMPT";
    case MSG_TASK_YIELD:
      return "MSG_TASK_YIELD";
    case MSG_CPU_TICK:
      return "MSG_CPU_TICK";
    case MSG_CPU_NOT_IDLE:
      return "MSG_CPU_NOT_IDLE";
    case MSG_CPU_TIMER_EXPIRED:
      return "MSG_CPU_TIMER_EXPIRED";
    case MSG_TASK_DEPARTED:
      return "MSG_TASK_DEPARTED";
    case MSG_TASK_SWITCHTO:
      return "MSG_TASK_SWITCHTO";
    case MSG_TASK_AFFINITY_CHANGED:
      return "MSG_TASK_AFFINITY_CHANGED";
    case MSG_TASK_LATCHED:
      return "MSG_TASK_LATCHED";
    default:
      GHOST_ERROR("Unknown message %d", type());
  }
  return "UNKNOWN";
}

std::string Message::stringify() const {
  std::string result = absl::StrCat("M: ", describe_type(), " seq=", seqnum());

  if (is_cpu_msg()) {
    absl::StrAppend(&result, " cpu=", cpu());
    return result;
  }

  if (is_task_msg()) {
    Gtid msg_gtid = gtid();
    absl::StrAppend(&result, " ", msg_gtid.describe());
  }

  switch (type()) {
    case MSG_NOP:
      absl::StrAppend(&result, " l=", length());
      break;

    case MSG_TASK_NEW: {
      const ghost_msg_payload_task_new* new_payload =
          static_cast<const ghost_msg_payload_task_new*>(payload());
      absl::StrAppend(&result, " ",
                      new_payload->runnable ? "runnable" : "blocked");
      break;
    }

    case MSG_TASK_SWITCHTO: {
      const ghost_msg_payload_task_switchto* switchto =
          static_cast<const ghost_msg_payload_task_switchto*>(payload());
      absl::StrAppend(&result, " entering switchto on cpu ", switchto->cpu);
      break;
    }

    case MSG_TASK_BLOCKED: {
      const ghost_msg_payload_task_blocked* blocked =
          static_cast<const ghost_msg_payload_task_blocked*>(payload());
      absl::StrAppend(&result, " on cpu ", blocked->cpu);
      if (blocked->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    case MSG_TASK_YIELD: {
      const ghost_msg_payload_task_yield* yield =
          static_cast<const ghost_msg_payload_task_yield*>(payload());
      absl::StrAppend(&result, " on cpu ", yield->cpu);
      if (yield->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    case MSG_TASK_PREEMPT: {
      const ghost_msg_payload_task_preempt* preempt =
          static_cast<const ghost_msg_payload_task_preempt*>(payload());
      absl::StrAppend(&result, " on cpu ", preempt->cpu);
      if (preempt->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    case MSG_TASK_DEPARTED: {
      const ghost_msg_payload_task_departed* departed =
          static_cast<const ghost_msg_payload_task_departed*>(payload());
      absl::StrAppend(&result, " on cpu ", departed->cpu);
      if (departed->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    default:
      break;
  }

  return result;
}

}  // namespace ghost
<commit_msg>ghOSt: Add latch info to TASK_PREEMPT message string<commit_after>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "channel.h"

#include <stdio.h>
#include <sys/mman.h>

#include <cstdint>
#include <iostream>

#include "lib/ghost.h"

namespace ghost {

// static
ghost_msg Message::kEmpty = {
    .type = 0,
    .length = 0,
    .seqnum = 0,
};

LocalChannel::LocalChannel(int elems, int node, CpuList cpulist)
    : Channel(), elems_(elems), node_(node) {
  fd_ = Ghost::CreateQueue(elems_, node_, 0, map_size_);
  CHECK_GT(fd_, 0);

  header_ = static_cast<ghost_queue_header*>(
      mmap(nullptr, map_size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
  CHECK_NE(header_, MAP_FAILED);
  elems_ = header_->nelems;

  if (!cpulist.Empty()) {
    CHECK_ZERO(Ghost::ConfigQueueWakeup(fd_, cpulist, /*flags=*/0));
  }
};

LocalChannel::~LocalChannel() {
  munmap(header_, map_size_);
  close(fd_);
}

bool LocalChannel::AssociateTask(Gtid gtid, int barrier, int* status) const {
  return Ghost::AssociateQueue(
      fd_, GHOST_TASK, gtid.id(), barrier, 0, status) == 0;
}

void LocalChannel::Consume(const Message& msg) {
  ghost_ring* r = reinterpret_cast<ghost_ring*>(
      reinterpret_cast<char*>(header_) + header_->start);
  const int slot_size = sizeof(ghost_msg);

  uint32_t tail = r->tail.load(std::memory_order_acquire);

  // static_cast<uint32_t> to ensure that msg.length() is properly rounded up.
  // Otherwise if 'msg.length() + slot_size >= 65536' we'll end up only using
  // least significant 16-bits.
  tail += roundup2(static_cast<uint32_t>(msg.length()), slot_size) / slot_size;
  r->tail.store(tail, std::memory_order_release);
}

Message LocalChannel::Peek() const {
  ghost_ring* r = reinterpret_cast<ghost_ring*>(
      reinterpret_cast<char*>(header_) + header_->start);
  uint32_t tidx;

  const uint32_t nelems = header_->nelems;

  const uint32_t tail = r->tail.load(std::memory_order_acquire);
  const uint32_t head = r->head.load(std::memory_order_acquire);

  if (tail == head) return Message();  // Empty message.

  const uint32_t overflow = r->overflow.load(std::memory_order_acquire);
  CHECK_EQ(overflow, 0);

  tidx = tail & (nelems - 1);
  return Message(&r->msgs[tidx]);
}

bool LocalChannel::SetEnclaveDefault() const {
  return Ghost::SetDefaultQueue(fd_) == 0;
}

absl::string_view Message::describe_type() const {
  switch (type()) {
    case MSG_NOP:
      return "MSG_NOP";
    case MSG_TASK_DEAD:
      return "MSG_TASK_DEAD";
    case MSG_TASK_BLOCKED:
      return "MSG_TASK_BLOCKED";
    case MSG_TASK_WAKEUP:
      return "MSG_TASK_WAKEUP";
    case MSG_TASK_NEW:
      return "MSG_TASK_NEW";
    case MSG_TASK_PREEMPT:
      return "MSG_TASK_PREEMPT";
    case MSG_TASK_YIELD:
      return "MSG_TASK_YIELD";
    case MSG_CPU_TICK:
      return "MSG_CPU_TICK";
    case MSG_CPU_NOT_IDLE:
      return "MSG_CPU_NOT_IDLE";
    case MSG_CPU_TIMER_EXPIRED:
      return "MSG_CPU_TIMER_EXPIRED";
    case MSG_TASK_DEPARTED:
      return "MSG_TASK_DEPARTED";
    case MSG_TASK_SWITCHTO:
      return "MSG_TASK_SWITCHTO";
    case MSG_TASK_AFFINITY_CHANGED:
      return "MSG_TASK_AFFINITY_CHANGED";
    case MSG_TASK_LATCHED:
      return "MSG_TASK_LATCHED";
    default:
      GHOST_ERROR("Unknown message %d", type());
  }
  return "UNKNOWN";
}

std::string Message::stringify() const {
  std::string result = absl::StrCat("M: ", describe_type(), " seq=", seqnum());

  if (is_cpu_msg()) {
    absl::StrAppend(&result, " cpu=", cpu());
    return result;
  }

  if (is_task_msg()) {
    Gtid msg_gtid = gtid();
    absl::StrAppend(&result, " ", msg_gtid.describe());
  }

  switch (type()) {
    case MSG_NOP:
      absl::StrAppend(&result, " l=", length());
      break;

    case MSG_TASK_NEW: {
      const ghost_msg_payload_task_new* new_payload =
          static_cast<const ghost_msg_payload_task_new*>(payload());
      absl::StrAppend(&result, " ",
                      new_payload->runnable ? "runnable" : "blocked");
      break;
    }

    case MSG_TASK_SWITCHTO: {
      const ghost_msg_payload_task_switchto* switchto =
          static_cast<const ghost_msg_payload_task_switchto*>(payload());
      absl::StrAppend(&result, " entering switchto on cpu ", switchto->cpu);
      break;
    }

    case MSG_TASK_BLOCKED: {
      const ghost_msg_payload_task_blocked* blocked =
          static_cast<const ghost_msg_payload_task_blocked*>(payload());
      absl::StrAppend(&result, " on cpu ", blocked->cpu);
      if (blocked->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    case MSG_TASK_YIELD: {
      const ghost_msg_payload_task_yield* yield =
          static_cast<const ghost_msg_payload_task_yield*>(payload());
      absl::StrAppend(&result, " on cpu ", yield->cpu);
      if (yield->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    case MSG_TASK_PREEMPT: {
      const ghost_msg_payload_task_preempt* preempt =
          static_cast<const ghost_msg_payload_task_preempt*>(payload());
      absl::StrAppend(&result, " on cpu ", preempt->cpu);
      if (preempt->was_latched) absl::StrAppend(&result, " (was_latched)");
      if (preempt->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    case MSG_TASK_DEPARTED: {
      const ghost_msg_payload_task_departed* departed =
          static_cast<const ghost_msg_payload_task_departed*>(payload());
      absl::StrAppend(&result, " on cpu ", departed->cpu);
      if (departed->from_switchto) absl::StrAppend(&result, " (from_switchto)");
      break;
    }

    default:
      break;
  }

  return result;
}

}  // namespace ghost
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: SlsFocusManager.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-17 10:04:57 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "controller/SlsFocusManager.hxx"

#include "controller/SlideSorterController.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"

#include "Window.hxx"
#include "sdpage.hxx"

namespace sd { namespace slidesorter { namespace controller {

FocusManager::FocusManager (SlideSorterController& rController)
    : mrController (rController),
      mnPageIndex (-1),
      mbPageIsFocused (false)
{
    if (mrController.GetModel().GetPageCount() > 0)
        mnPageIndex = 0;
}

FocusManager::~FocusManager (void)
{
}

void FocusManager::MoveFocus (FocusMoveDirection eDirection)
{
    if (mnPageIndex >= 0 && mbPageIsFocused)
    {
        HideFocusIndicator (GetFocusedPageDescriptor());

        int nColumnCount
            = mrController.GetView().GetLayouter().GetColumnCount();
        switch (eDirection)
        {
            case FMD_NONE:
                if (mnPageIndex >= mrController.GetModel().GetPageCount())
                    mnPageIndex = mrController.GetModel().GetPageCount() - 1;
                break;

            case FMD_LEFT:
                mnPageIndex -= 1;
                if (mnPageIndex < 0)
                    mnPageIndex = mrController.GetModel().GetPageCount() - 1;
                break;

            case FMD_RIGHT:
                mnPageIndex += 1;
                if (mnPageIndex >= mrController.GetModel().GetPageCount())
                    mnPageIndex = 0;
                break;

            case FMD_UP:
            {
                int nColumn = mnPageIndex % nColumnCount;
                mnPageIndex -= nColumnCount;
                if (mnPageIndex < 0)
                {
                    // Wrap arround to the bottom row or the one above and
                    // go to the correct column.
                    int nCandidate = mrController.GetModel().GetPageCount()-1;
                    int nCandidateColumn = nCandidate % nColumnCount;
                    if (nCandidateColumn > nColumn)
                        mnPageIndex = nCandidate - (nCandidateColumn-nColumn);
                    else if (nCandidateColumn < nColumn)
                        mnPageIndex = nCandidate
                            - nColumnCount
                            + (nColumn - nCandidateColumn);
                    else
                        mnPageIndex = nCandidate;
                }
            }
            break;

            case FMD_DOWN:
            {
                int nColumn = mnPageIndex % nColumnCount;
                mnPageIndex += nColumnCount;
                if (mnPageIndex >= mrController.GetModel().GetPageCount())
                {
                    // Wrap arround to the correct column.
                    mnPageIndex = nColumn;
                }
            }
            break;
        }

        ShowFocusIndicator (GetFocusedPageDescriptor());
    }
}

void FocusManager::ShowFocus (void)
{
    mbPageIsFocused = true;
    ShowFocusIndicator (GetFocusedPageDescriptor());
}

void FocusManager::HideFocus (void)
{
    mbPageIsFocused = false;
    HideFocusIndicator (GetFocusedPageDescriptor());
}

bool FocusManager::ToggleFocus (void)
{
    if (mnPageIndex >= 0)
    {
        if (mbPageIsFocused)
            HideFocus ();
        else
            ShowFocus ();
    }
    return mbPageIsFocused;
}

bool FocusManager::HasFocus (void) const
{
    return mrController.GetView().GetWindow()->HasFocus();
}

model::PageDescriptor* FocusManager::GetFocusedPageDescriptor (void) const
{
    return mrController.GetModel().GetPageDescriptor (mnPageIndex);
}

sal_Int32 FocusManager::GetFocusedPageIndex (void) const
{
    return mnPageIndex;
}

void FocusManager::FocusPage (sal_Int32 nPageIndex)
{
    if (nPageIndex != mnPageIndex)
    {
        // Hide the focus while switching it to the specified page.
        FocusHider aHider (*this);
        mnPageIndex = nPageIndex;
    }
}

void FocusManager::SetFocusedPage (const model::PageDescriptor& rDescriptor)
{
    FocusHider aFocusHider (*this);
    mnPageIndex = (rDescriptor.GetPage()->GetPageNum()-1)/2;
}

void FocusManager::SetFocusedPage (sal_Int32 nPageIndex)
{
    FocusHider aFocusHider (*this);
    mnPageIndex = nPageIndex;
}

bool FocusManager::IsFocusShowing (void) const
{
    return HasFocus() && mbPageIsFocused;
}

void FocusManager::HideFocusIndicator (model::PageDescriptor* pDescriptor)
{
    if( pDescriptor )
    {
        pDescriptor->RemoveFocus();
        mrController.GetView().RequestRepaint (*pDescriptor);
    }
}

void FocusManager::ShowFocusIndicator (model::PageDescriptor* pDescriptor)
{
    if (pDescriptor != NULL)
    {
        pDescriptor->SetFocus ();

        // Scroll the focused page object into the visible area and repaint
        // it, so that the focus indicator becomes visible.
        view::SlideSorterView& rView (mrController.GetView());
        mrController.MakeRectangleVisible (
            rView.GetPageBoundingBox (
                *GetFocusedPageDescriptor(),
                view::SlideSorterView::CS_MODEL,
                view::SlideSorterView::BBT_INFO));

        mrController.GetView().RequestRepaint (*pDescriptor);
    }
}

FocusManager::FocusHider::FocusHider (FocusManager& rManager)
    : mrManager(rManager),
      mbFocusVisible(rManager.IsFocusShowing())
{
    mrManager.HideFocus();
}

FocusManager::FocusHider::~FocusHider (void)
{
    if (mbFocusVisible)
        mrManager.ShowFocus();
}

} } } // end of namespace ::sd::slidesorter::controller

<commit_msg>INTEGRATION: CWS impress51 (1.6.90); FILE MERGED 2005/05/04 14:30:01 af 1.6.90.1: #i48703# Added support for focus change listeners.<commit_after>/*************************************************************************
 *
 *  $RCSfile: SlsFocusManager.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2005-07-14 10:16:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "controller/SlsFocusManager.hxx"

#include "controller/SlideSorterController.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"

#include "Window.hxx"
#include "sdpage.hxx"

namespace sd { namespace slidesorter { namespace controller {

FocusManager::FocusManager (SlideSorterController& rController)
    : mrController (rController),
      mnPageIndex (-1),
      mbPageIsFocused (false)
{
    if (mrController.GetModel().GetPageCount() > 0)
        mnPageIndex = 0;
}

FocusManager::~FocusManager (void)
{
}

void FocusManager::MoveFocus (FocusMoveDirection eDirection)
{
    if (mnPageIndex >= 0 && mbPageIsFocused)
    {
        HideFocusIndicator (GetFocusedPageDescriptor());

        int nColumnCount
            = mrController.GetView().GetLayouter().GetColumnCount();
        switch (eDirection)
        {
            case FMD_NONE:
                if (mnPageIndex >= mrController.GetModel().GetPageCount())
                    mnPageIndex = mrController.GetModel().GetPageCount() - 1;
                break;

            case FMD_LEFT:
                mnPageIndex -= 1;
                if (mnPageIndex < 0)
                    mnPageIndex = mrController.GetModel().GetPageCount() - 1;
                break;

            case FMD_RIGHT:
                mnPageIndex += 1;
                if (mnPageIndex >= mrController.GetModel().GetPageCount())
                    mnPageIndex = 0;
                break;

            case FMD_UP:
            {
                int nColumn = mnPageIndex % nColumnCount;
                mnPageIndex -= nColumnCount;
                if (mnPageIndex < 0)
                {
                    // Wrap arround to the bottom row or the one above and
                    // go to the correct column.
                    int nCandidate = mrController.GetModel().GetPageCount()-1;
                    int nCandidateColumn = nCandidate % nColumnCount;
                    if (nCandidateColumn > nColumn)
                        mnPageIndex = nCandidate - (nCandidateColumn-nColumn);
                    else if (nCandidateColumn < nColumn)
                        mnPageIndex = nCandidate
                            - nColumnCount
                            + (nColumn - nCandidateColumn);
                    else
                        mnPageIndex = nCandidate;
                }
            }
            break;

            case FMD_DOWN:
            {
                int nColumn = mnPageIndex % nColumnCount;
                mnPageIndex += nColumnCount;
                if (mnPageIndex >= mrController.GetModel().GetPageCount())
                {
                    // Wrap arround to the correct column.
                    mnPageIndex = nColumn;
                }
            }
            break;
        }

        ShowFocusIndicator (GetFocusedPageDescriptor());
    }
}

void FocusManager::ShowFocus (void)
{
    mbPageIsFocused = true;
    ShowFocusIndicator (GetFocusedPageDescriptor());
}

void FocusManager::HideFocus (void)
{
    mbPageIsFocused = false;
    HideFocusIndicator (GetFocusedPageDescriptor());
}

bool FocusManager::ToggleFocus (void)
{
    if (mnPageIndex >= 0)
    {
        if (mbPageIsFocused)
            HideFocus ();
        else
            ShowFocus ();
    }
    return mbPageIsFocused;
}

bool FocusManager::HasFocus (void) const
{
    return mrController.GetView().GetWindow()->HasFocus();
}

model::PageDescriptor* FocusManager::GetFocusedPageDescriptor (void) const
{
    return mrController.GetModel().GetPageDescriptor (mnPageIndex);
}

sal_Int32 FocusManager::GetFocusedPageIndex (void) const
{
    return mnPageIndex;
}

void FocusManager::FocusPage (sal_Int32 nPageIndex)
{
    if (nPageIndex != mnPageIndex)
    {
        // Hide the focus while switching it to the specified page.
        FocusHider aHider (*this);
        mnPageIndex = nPageIndex;
    }
}

void FocusManager::SetFocusedPage (const model::PageDescriptor& rDescriptor)
{
    FocusHider aFocusHider (*this);
    mnPageIndex = (rDescriptor.GetPage()->GetPageNum()-1)/2;
}

void FocusManager::SetFocusedPage (sal_Int32 nPageIndex)
{
    FocusHider aFocusHider (*this);
    mnPageIndex = nPageIndex;
}

bool FocusManager::IsFocusShowing (void) const
{
    return HasFocus() && mbPageIsFocused;
}

void FocusManager::HideFocusIndicator (model::PageDescriptor* pDescriptor)
{
    if( pDescriptor )
    {
        pDescriptor->RemoveFocus();
        mrController.GetView().RequestRepaint (*pDescriptor);
    }
}

void FocusManager::ShowFocusIndicator (model::PageDescriptor* pDescriptor)
{
    if (pDescriptor != NULL)
    {
        pDescriptor->SetFocus ();

        // Scroll the focused page object into the visible area and repaint
        // it, so that the focus indicator becomes visible.
        view::SlideSorterView& rView (mrController.GetView());
        mrController.MakeRectangleVisible (
            rView.GetPageBoundingBox (
                *GetFocusedPageDescriptor(),
                view::SlideSorterView::CS_MODEL,
                view::SlideSorterView::BBT_INFO));

        mrController.GetView().RequestRepaint (*pDescriptor);
        NotifyFocusChangeListeners();
    }
}

void FocusManager::AddFocusChangeListener (const Link& rListener)
{
    if (::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener)
        == maFocusChangeListeners.end())
    {
        maFocusChangeListeners.push_back (rListener);
    }
}

void FocusManager::RemoveFocusChangeListener (const Link& rListener)
{
    maFocusChangeListeners.erase (
        ::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener));
}

void FocusManager::NotifyFocusChangeListeners (void) const
{
    // Create a copy of the listener list to be safe when that is modified.
    ::std::vector<Link> aListeners (maFocusChangeListeners);

    // Tell the slection change listeners that the selection has changed.
    ::std::vector<Link>::iterator iListener (aListeners.begin());
    ::std::vector<Link>::iterator iEnd (aListeners.end());
    for (; iListener!=iEnd; ++iListener)
    {
        iListener->Call(NULL);
    }
}

FocusManager::FocusHider::FocusHider (FocusManager& rManager)
    : mrManager(rManager),
      mbFocusVisible(rManager.IsFocusShowing())
{
    mrManager.HideFocus();
}

FocusManager::FocusHider::~FocusHider (void)
{
    if (mbFocusVisible)
        mrManager.ShowFocus();
}

} } } // end of namespace ::sd::slidesorter::controller

<|endoftext|>