<commit_before>// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

#pragma once

#if !defined(RXCPP_SOURCES_RX_ITERATE_HPP)
#define RXCPP_SOURCES_RX_ITERATE_HPP

#include "../rx-includes.hpp"

/*! \file rx-iterate.hpp

    \brief Returns an observable that sends each value in the collection, on the specified scheduler.

    \tparam Collection    the type of the collection of values that this observable emits
    \tparam Coordination  the type of the scheduler (optional)

    \param  c   collection containing values to send
    \param  cn  the scheduler to use for scheduling the items (optional)

    \return  Observable that sends each value in the collection.

    \sample
    \snippet iterate.cpp iterate sample
    \snippet output.txt iterate sample

    \sample
    \snippet iterate.cpp threaded iterate sample
    \snippet output.txt threaded iterate sample

*/

namespace rxcpp {

namespace sources {

namespace detail {

template<class Collection>
struct is_iterable
{
    typedef rxu::decay_t<Collection> collection_type;

    struct not_void {};
    template<class CC>
    static auto check(int) -> decltype(std::begin(*(CC*)nullptr));
    template<class CC>
    static not_void check(...);

    static const bool value = !std::is_same<decltype(check<collection_type>(0)), not_void>::value;
};

template<class Collection>
struct iterate_traits
{
    typedef rxu::decay_t<Collection> collection_type;
    typedef rxu::decay_t<decltype(std::begin(*(collection_type*)nullptr))> iterator_type;
    typedef rxu::value_type_t<std::iterator_traits<iterator_type>> value_type;
};

template<class Collection, class Coordination>
struct iterate : public source_base<rxu::value_type_t<iterate_traits<Collection>>>
{
    typedef iterate<Collection, Coordination> this_type;
    typedef iterate_traits<Collection> traits;

    typedef rxu::decay_t<Coordination> coordination_type;
    typedef typename coordination_type::coordinator_type coordinator_type;

    typedef typename traits::collection_type collection_type;
    typedef typename traits::iterator_type iterator_type;

    struct iterate_initial_type
    {
        iterate_initial_type(collection_type c, coordination_type cn)
            : collection(std::move(c))
            , coordination(std::move(cn))
        {
        }
        collection_type collection;
        coordination_type coordination;
    };
    iterate_initial_type initial;

    iterate(collection_type c, coordination_type cn)
        : initial(std::move(c), std::move(cn))
    {
    }
    template<class Subscriber>
    void on_subscribe(Subscriber o) const {
        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");

        typedef typename coordinator_type::template get<Subscriber>::type output_type;

        struct iterate_state_type
            : public iterate_initial_type
        {
            iterate_state_type(const iterate_initial_type& i, output_type o)
                : iterate_initial_type(i)
                , cursor(std::begin(iterate_initial_type::collection))
                , end(std::end(iterate_initial_type::collection))
                , out(std::move(o))
            {
            }
            iterate_state_type(const iterate_state_type& o)
                : iterate_initial_type(o)
                , cursor(std::begin(iterate_initial_type::collection))
                , end(std::end(iterate_initial_type::collection))
                , out(std::move(o.out)) // since lambda capture does not yet support move
            {
            }
            mutable iterator_type cursor;
            iterator_type end;
            mutable output_type out;
        };

        // creates a worker whose lifetime is the same as this subscription
        auto coordinator = initial.coordination.create_coordinator(o.get_subscription());

        iterate_state_type state(initial, o);

        auto controller = coordinator.get_worker();

        auto producer = [state](const rxsc::schedulable& self){
            if (!state.out.is_subscribed()) {
                // terminate loop
                return;
            }

            if (state.cursor != state.end) {
                // send next value
                state.out.on_next(*state.cursor);
                ++state.cursor;
            }

            if (state.cursor == state.end) {
                state.out.on_completed();
                // o is unsubscribed
                return;
            }

            // tail recurse this same action to continue loop
            self();
        };
        auto selectedProducer = on_exception(
            [&](){return coordinator.act(producer);},
            o);
        if (selectedProducer.empty()) {
            return;
        }
        controller.schedule(selectedProducer.get());

    }
};

}

/*! @copydoc rx-iterate.hpp
 */
template<class Collection>
auto iterate(Collection c)
    ->      observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, identity_one_worker>> {
    return  observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, identity_one_worker>>(
                                                                              detail::iterate<Collection, identity_one_worker>(std::move(c), identity_immediate()));
}
/*! @copydoc rx-iterate.hpp
 */
template<class Collection, class Coordination>
auto iterate(Collection c, Coordination cn)
    ->      observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, Coordination>> {
    return  observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, Coordination>>(
                                                                              detail::iterate<Collection, Coordination>(std::move(c), std::move(cn)));
}

/*! Returns an observable that sends an empty set of values and then completes.

    \tparam T  the type of elements (not) to be sent

    \return  Observable that sends an empty set of values and then completes.

    This is a degenerate case of rxcpp::observable<void,void>#from(Value0,ValueN...) operator.

    \note This is a degenerate case of ```from(Value0 v0, ValueN... vn)``` operator.
*/
template<class T>
auto from()
    -> decltype(iterate(std::array<T, 0>(), identity_immediate())) {
    return      iterate(std::array<T, 0>(), identity_immediate());
}
/*! Returns an observable that sends an empty set of values and then completes, on the specified scheduler.

    \tparam T  the type of elements (not) to be sent
    \tparam Coordination  the type of the scheduler

    \return  Observable that sends an empty set of values and then completes.

    \note This is a degenerate case of ```from(Coordination cn, Value0 v0, ValueN... vn)``` operator.
*/
template<class T, class Coordination>
auto from(Coordination cn)
    -> typename std::enable_if<is_coordination<Coordination>::value,
        decltype(   iterate(std::array<T, 0>(), std::move(cn)))>::type {
    return          iterate(std::array<T, 0>(), std::move(cn));
}
/*! Returns an observable that sends each value from its arguments list.

    \tparam Value0  ...
    \tparam ValueN  the type of sending values

    \param  v0  ...
    \param  vn  values to send

    \return  Observable that sends each value from its arguments list.

    \sample
    \snippet from.cpp from sample
    \snippet output.txt from sample

    \note This operator is useful to send separated values. If they are stored as a collection, use observable<void,void>::iterate instead.
*/
template<class Value0, class... ValueN>
auto from(Value0 v0, ValueN... vn)
    -> typename std::enable_if<!is_coordination<Value0>::value,
        decltype(iterate(*(std::array<Value0, sizeof...(ValueN) + 1>*)nullptr, identity_immediate()))>::type {
    std::array<Value0, sizeof...(ValueN) + 1> c{{v0, vn...}};
    return iterate(std::move(c), identity_immediate());
}
/*! Returns an observable that sends each value from its arguments list, on the specified scheduler.

    \tparam Coordination  the type of the scheduler
    \tparam Value0  ...
    \tparam ValueN  the type of sending values

    \param  cn  the scheduler to use for scheduling the items
    \param  v0  ...
    \param  vn  values to send

    \return  Observable that sends each value from its arguments list.

    \sample
    \snippet from.cpp threaded from sample
    \snippet output.txt threaded from sample

    \note This operator is useful to send separated values. If they are stored as a collection, use observable<void,void>::iterate instead.
*/
template<class Coordination, class Value0, class... ValueN>
auto from(Coordination cn, Value0 v0, ValueN... vn)
    -> typename std::enable_if<is_coordination<Coordination>::value,
        decltype(iterate(*(std::array<Value0, sizeof...(ValueN) + 1>*)nullptr, std::move(cn)))>::type {
    std::array<Value0, sizeof...(ValueN) + 1> c{{v0, vn...}};
    return iterate(std::move(c), std::move(cn));
}

/*! Returns an observable that sends the specified item to observer and then completes.

    \tparam T  the type of the emitted item

    \param v  the value to send

    \return  Observable that sends the specified item to observer and then completes.

    \sample
    \snippet just.cpp just sample
    \snippet output.txt just sample
*/
template<class Value0>
auto just(Value0 v0)
    -> typename std::enable_if<!is_coordination<Value0>::value,
        decltype(iterate(*(std::array<Value0, 1>*)nullptr, identity_immediate()))>::type {
    std::array<Value0, 1> c{{v0}};
    return iterate(std::move(c), identity_immediate());
}
/*! Returns an observable that sends the specified item to observer and then completes, on the specified scheduler.

    \tparam T             the type of the emitted item
    \tparam Coordination  the type of the scheduler

    \param v   the value to send
    \param cn  the scheduler to use for scheduling the items

    \return  Observable that sends the specified item to observer and then completes.

    \sample
    \snippet just.cpp threaded just sample
    \snippet output.txt threaded just sample
*/
template<class Value0, class Coordination>
auto just(Value0 v0, Coordination cn)
    -> typename std::enable_if<is_coordination<Coordination>::value,
        decltype(iterate(*(std::array<Value0, 1>*)nullptr, std::move(cn)))>::type {
    std::array<Value0, 1> c{{v0}};
    return iterate(std::move(c), std::move(cn));
}

/*! Returns an observable that sends the specified values before it begins to send items emitted by the given observable.

    \tparam Observable  the type of the observable that emits values for resending
    \tparam Value0      ...
    \tparam ValueN      the type of sending values

    \param  o   the observable that emits values for resending
    \param  v0  ...
    \param  vn  values to send

    \return  Observable that sends the specified values before it begins to send items emitted by the given observable.

    \sample
    \snippet start_with.cpp full start_with sample
    \snippet output.txt full start_with sample

    Instead of passing the observable as a parameter, you can use rxcpp::observable<T, SourceOperator>::start_with method of the existing observable:
    \snippet start_with.cpp short start_with sample
    \snippet output.txt short start_with sample
*/
template<class Observable, class Value0, class... ValueN>
auto start_with(Observable o, Value0 v0, ValueN... vn)
    -> decltype(from(rxu::value_type_t<Observable>(v0), rxu::value_type_t<Observable>(vn)...).concat(o)) {
    return      from(rxu::value_type_t<Observable>(v0), rxu::value_type_t<Observable>(vn)...).concat(o);
}

}

}

#endif
<commit_msg>Fix rxcpp::observable<>::from<T>() when T is non-default constructable<commit_after>// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

#pragma once

#if !defined(RXCPP_SOURCES_RX_ITERATE_HPP)
#define RXCPP_SOURCES_RX_ITERATE_HPP

#include "../rx-includes.hpp"

/*! \file rx-iterate.hpp

    \brief Returns an observable that sends each value in the collection, on the specified scheduler.

    \tparam Collection    the type of the collection of values that this observable emits
    \tparam Coordination  the type of the scheduler (optional)

    \param  c   collection containing values to send
    \param  cn  the scheduler to use for scheduling the items (optional)

    \return  Observable that sends each value in the collection.

    \sample
    \snippet iterate.cpp iterate sample
    \snippet output.txt iterate sample

    \sample
    \snippet iterate.cpp threaded iterate sample
    \snippet output.txt threaded iterate sample

*/

namespace rxcpp {

namespace sources {

namespace detail {

template<class Collection>
struct is_iterable
{
    typedef rxu::decay_t<Collection> collection_type;

    struct not_void {};
    template<class CC>
    static auto check(int) -> decltype(std::begin(*(CC*)nullptr));
    template<class CC>
    static not_void check(...);

    static const bool value = !std::is_same<decltype(check<collection_type>(0)), not_void>::value;
};

template<class Collection>
struct iterate_traits
{
    typedef rxu::decay_t<Collection> collection_type;
    typedef rxu::decay_t<decltype(std::begin(*(collection_type*)nullptr))> iterator_type;
    typedef rxu::value_type_t<std::iterator_traits<iterator_type>> value_type;
};

template<class Collection, class Coordination>
struct iterate : public source_base<rxu::value_type_t<iterate_traits<Collection>>>
{
    typedef iterate<Collection, Coordination> this_type;
    typedef iterate_traits<Collection> traits;

    typedef rxu::decay_t<Coordination> coordination_type;
    typedef typename coordination_type::coordinator_type coordinator_type;

    typedef typename traits::collection_type collection_type;
    typedef typename traits::iterator_type iterator_type;

    struct iterate_initial_type
    {
        iterate_initial_type(collection_type c, coordination_type cn)
            : collection(std::move(c))
            , coordination(std::move(cn))
        {
        }
        collection_type collection;
        coordination_type coordination;
    };
    iterate_initial_type initial;

    iterate(collection_type c, coordination_type cn)
        : initial(std::move(c), std::move(cn))
    {
    }
    template<class Subscriber>
    void on_subscribe(Subscriber o) const {
        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");

        typedef typename coordinator_type::template get<Subscriber>::type output_type;

        struct iterate_state_type
            : public iterate_initial_type
        {
            iterate_state_type(const iterate_initial_type& i, output_type o)
                : iterate_initial_type(i)
                , cursor(std::begin(iterate_initial_type::collection))
                , end(std::end(iterate_initial_type::collection))
                , out(std::move(o))
            {
            }
            iterate_state_type(const iterate_state_type& o)
                : iterate_initial_type(o)
                , cursor(std::begin(iterate_initial_type::collection))
                , end(std::end(iterate_initial_type::collection))
                , out(std::move(o.out)) // since lambda capture does not yet support move
            {
            }
            mutable iterator_type cursor;
            iterator_type end;
            mutable output_type out;
        };

        // creates a worker whose lifetime is the same as this subscription
        auto coordinator = initial.coordination.create_coordinator(o.get_subscription());

        iterate_state_type state(initial, o);

        auto controller = coordinator.get_worker();

        auto producer = [state](const rxsc::schedulable& self){
            if (!state.out.is_subscribed()) {
                // terminate loop
                return;
            }

            if (state.cursor != state.end) {
                // send next value
                state.out.on_next(*state.cursor);
                ++state.cursor;
            }

            if (state.cursor == state.end) {
                state.out.on_completed();
                // o is unsubscribed
                return;
            }

            // tail recurse this same action to continue loop
            self();
        };
        auto selectedProducer = on_exception(
            [&](){return coordinator.act(producer);},
            o);
        if (selectedProducer.empty()) {
            return;
        }
        controller.schedule(selectedProducer.get());

    }
};

}

/*! @copydoc rx-iterate.hpp
 */
template<class Collection>
auto iterate(Collection c)
    ->      observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, identity_one_worker>> {
    return  observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, identity_one_worker>>(
                                                                              detail::iterate<Collection, identity_one_worker>(std::move(c), identity_immediate()));
}
/*! @copydoc rx-iterate.hpp
 */
template<class Collection, class Coordination>
auto iterate(Collection c, Coordination cn)
    ->      observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, Coordination>> {
    return  observable<rxu::value_type_t<detail::iterate_traits<Collection>>, detail::iterate<Collection, Coordination>>(
                                                                              detail::iterate<Collection, Coordination>(std::move(c), std::move(cn)));
}

/*! Returns an observable that sends an empty set of values and then completes.

    \tparam T  the type of elements (not) to be sent

    \return  Observable that sends an empty set of values and then completes.

    This is a degenerate case of rxcpp::observable<void,void>#from(Value0,ValueN...) operator.

    \note This is a degenerate case of ```from(Value0 v0, ValueN... vn)``` operator.
*/
template<class T>
auto from()
    -> decltype(iterate(std::initializer_list<T>(), identity_immediate())) {
    return      iterate(std::initializer_list<T>(), identity_immediate());
}
/*! Returns an observable that sends an empty set of values and then completes, on the specified scheduler.

    \tparam T  the type of elements (not) to be sent
    \tparam Coordination  the type of the scheduler

    \return  Observable that sends an empty set of values and then completes.

    \note This is a degenerate case of ```from(Coordination cn, Value0 v0, ValueN... vn)``` operator.
*/
template<class T, class Coordination>
auto from(Coordination cn)
    -> typename std::enable_if<is_coordination<Coordination>::value,
        decltype(   iterate(std::initializer_list<T>(), std::move(cn)))>::type {
    return          iterate(std::initializer_list<T>(), std::move(cn));
}
/*! Returns an observable that sends each value from its arguments list.

    \tparam Value0  ...
    \tparam ValueN  the type of sending values

    \param  v0  ...
    \param  vn  values to send

    \return  Observable that sends each value from its arguments list.

    \sample
    \snippet from.cpp from sample
    \snippet output.txt from sample

    \note This operator is useful to send separated values. If they are stored as a collection, use observable<void,void>::iterate instead.
*/
template<class Value0, class... ValueN>
auto from(Value0 v0, ValueN... vn)
    -> typename std::enable_if<!is_coordination<Value0>::value,
        decltype(iterate(*(std::array<Value0, sizeof...(ValueN) + 1>*)nullptr, identity_immediate()))>::type {
    std::array<Value0, sizeof...(ValueN) + 1> c{{v0, vn...}};
    return iterate(std::move(c), identity_immediate());
}
/*! Returns an observable that sends each value from its arguments list, on the specified scheduler.

    \tparam Coordination  the type of the scheduler
    \tparam Value0  ...
    \tparam ValueN  the type of sending values

    \param  cn  the scheduler to use for scheduling the items
    \param  v0  ...
    \param  vn  values to send

    \return  Observable that sends each value from its arguments list.

    \sample
    \snippet from.cpp threaded from sample
    \snippet output.txt threaded from sample

    \note This operator is useful to send separated values. If they are stored as a collection, use observable<void,void>::iterate instead.
*/
template<class Coordination, class Value0, class... ValueN>
auto from(Coordination cn, Value0 v0, ValueN... vn)
    -> typename std::enable_if<is_coordination<Coordination>::value,
        decltype(iterate(*(std::array<Value0, sizeof...(ValueN) + 1>*)nullptr, std::move(cn)))>::type {
    std::array<Value0, sizeof...(ValueN) + 1> c{{v0, vn...}};
    return iterate(std::move(c), std::move(cn));
}

/*! Returns an observable that sends the specified item to observer and then completes.

    \tparam T  the type of the emitted item

    \param v  the value to send

    \return  Observable that sends the specified item to observer and then completes.

    \sample
    \snippet just.cpp just sample
    \snippet output.txt just sample
*/
template<class Value0>
auto just(Value0 v0)
    -> typename std::enable_if<!is_coordination<Value0>::value,
        decltype(iterate(*(std::array<Value0, 1>*)nullptr, identity_immediate()))>::type {
    std::array<Value0, 1> c{{v0}};
    return iterate(std::move(c), identity_immediate());
}
/*! Returns an observable that sends the specified item to observer and then completes, on the specified scheduler.

    \tparam T             the type of the emitted item
    \tparam Coordination  the type of the scheduler

    \param v   the value to send
    \param cn  the scheduler to use for scheduling the items

    \return  Observable that sends the specified item to observer and then completes.

    \sample
    \snippet just.cpp threaded just sample
    \snippet output.txt threaded just sample
*/
template<class Value0, class Coordination>
auto just(Value0 v0, Coordination cn)
    -> typename std::enable_if<is_coordination<Coordination>::value,
        decltype(iterate(*(std::array<Value0, 1>*)nullptr, std::move(cn)))>::type {
    std::array<Value0, 1> c{{v0}};
    return iterate(std::move(c), std::move(cn));
}

/*! Returns an observable that sends the specified values before it begins to send items emitted by the given observable.

    \tparam Observable  the type of the observable that emits values for resending
    \tparam Value0      ...
    \tparam ValueN      the type of sending values

    \param  o   the observable that emits values for resending
    \param  v0  ...
    \param  vn  values to send

    \return  Observable that sends the specified values before it begins to send items emitted by the given observable.

    \sample
    \snippet start_with.cpp full start_with sample
    \snippet output.txt full start_with sample

    Instead of passing the observable as a parameter, you can use rxcpp::observable<T, SourceOperator>::start_with method of the existing observable:
    \snippet start_with.cpp short start_with sample
    \snippet output.txt short start_with sample
*/
template<class Observable, class Value0, class... ValueN>
auto start_with(Observable o, Value0 v0, ValueN... vn)
    -> decltype(from(rxu::value_type_t<Observable>(v0), rxu::value_type_t<Observable>(vn)...).concat(o)) {
    return      from(rxu::value_type_t<Observable>(v0), rxu::value_type_t<Observable>(vn)...).concat(o);
}

}

}

#endif
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// 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 "MultiSceneParser.h"

#include "particle/ParticleSceneParser.h"
#include "streamlines/StreamLineSceneParser.h"
#ifdef OSPRAY_TACHYON_SUPPORT
#  include "tachyon/TachyonSceneParser.h"
#endif
#include "trianglemesh/TriangleMeshSceneParser.h"
#ifndef _WIN32
# include "volume/VolumeSceneParser.h"
#endif

using namespace ospray;
using namespace ospcommon;

MultiSceneParser::MultiSceneParser(cpp::Renderer renderer) :
  m_renderer(renderer)
{
}

bool MultiSceneParser::parse(int ac, const char **&av)
{
  TriangleMeshSceneParser triangleMeshParser(m_renderer);
#ifdef OSPRAY_TACHYON_SUPPORT
  TachyonSceneParser      tachyonParser(m_renderer);
#endif
  ParticleSceneParser     particleParser(m_renderer);
  StreamLineSceneParser   streamlineParser(m_renderer);
#ifndef _WIN32
  VolumeSceneParser       volumeParser(m_renderer);
#endif

  bool gotTriangleMeshScene = triangleMeshParser.parse(ac, av);
#ifdef OSPRAY_TACHYON_SUPPORT
  bool gotTachyonScene      = tachyonParser.parse(ac, av);
#endif
  bool gotPartileScene      = particleParser.parse(ac, av);
  bool gotStreamLineScene   = streamlineParser.parse(ac, av);
#ifndef _WIN32
  bool gotVolumeScene       = volumeParser.parse(ac, av);
#endif

  SceneParser *parser = nullptr;

  if (gotTriangleMeshScene)
    parser = &triangleMeshParser;
#ifdef OSPRAY_TACHYON_SUPPORT
  else if (gotTachyonScene)
    parser = &tachyonParser;
#endif
  else if (gotPartileScene)
    parser = &particleParser;
  else if (gotStreamLineScene)
    parser = &streamlineParser;
#ifndef _WIN32
  else if (gotVolumeScene)
    parser = &volumeParser;
#endif

  if (parser) {
    m_model = parser->model();
    m_bbox  = parser->bbox();
  }

  return parser != nullptr;
}

cpp::Model MultiSceneParser::model() const
{
  return m_model;
}

box3f MultiSceneParser::bbox() const
{
  return m_bbox;
}
<commit_msg>fix crash in ospGlutViewer when no scene is passed on the command line<commit_after>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// 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 "MultiSceneParser.h"

#include "particle/ParticleSceneParser.h"
#include "streamlines/StreamLineSceneParser.h"
#ifdef OSPRAY_TACHYON_SUPPORT
#  include "tachyon/TachyonSceneParser.h"
#endif
#include "trianglemesh/TriangleMeshSceneParser.h"
#ifndef _WIN32
# include "volume/VolumeSceneParser.h"
#endif

using namespace ospray;
using namespace ospcommon;

MultiSceneParser::MultiSceneParser(cpp::Renderer renderer) :
  m_renderer(renderer)
{
}

bool MultiSceneParser::parse(int ac, const char **&av)
{
  TriangleMeshSceneParser triangleMeshParser(m_renderer);
#ifdef OSPRAY_TACHYON_SUPPORT
  TachyonSceneParser      tachyonParser(m_renderer);
#endif
  ParticleSceneParser     particleParser(m_renderer);
  StreamLineSceneParser   streamlineParser(m_renderer);
#ifndef _WIN32
  VolumeSceneParser       volumeParser(m_renderer);
#endif

  bool gotTriangleMeshScene = triangleMeshParser.parse(ac, av);
#ifdef OSPRAY_TACHYON_SUPPORT
  bool gotTachyonScene      = tachyonParser.parse(ac, av);
#endif
  bool gotPartileScene      = particleParser.parse(ac, av);
  bool gotStreamLineScene   = streamlineParser.parse(ac, av);
#ifndef _WIN32
  bool gotVolumeScene       = volumeParser.parse(ac, av);
#endif

  SceneParser *parser = nullptr;

  if (gotTriangleMeshScene)
    parser = &triangleMeshParser;
#ifdef OSPRAY_TACHYON_SUPPORT
  else if (gotTachyonScene)
    parser = &tachyonParser;
#endif
  else if (gotPartileScene)
    parser = &particleParser;
  else if (gotStreamLineScene)
    parser = &streamlineParser;
#ifndef _WIN32
  else if (gotVolumeScene)
    parser = &volumeParser;
#endif

  if (parser) {
    m_model = parser->model();
    m_bbox  = parser->bbox();
  } else {
    m_model = cpp::Model();
    m_model.commit();
  }

  return parser != nullptr;
}

cpp::Model MultiSceneParser::model() const
{
  return m_model;
}

box3f MultiSceneParser::bbox() const
{
  return m_bbox;
}
<|endoftext|>


<commit_before>#include <Zmey/Components/TransformManager.h>

#include <nlohmann/json.hpp>

#include <Zmey/MemoryStream.h>
#include <Zmey/Components/ComponentRegistry.h>

namespace Zmey
{
namespace Components
{
TransformInstance TransformManager::Lookup(EntityId id)
{
	return TransformInstance(*this, id);
}

void TransformManager::Simulate(float deltaTime)
{
	for (auto& pos : m_Positions)
	{
		pos += Vector3(0.05f, 0.05f, 0.05f) * deltaTime;
	}
}

void TransformComponentDefaults(IDataBlob& blob)
{
	float position[3] = { 0.f, 0.f, 0.f };
	blob.WriteData("position", reinterpret_cast<uint8_t*>(position), sizeof(position));
	float rotation[4] = { 0.f, 0.f, 0.f, 1.f };
	blob.WriteData("rotation", reinterpret_cast<uint8_t*>(rotation), sizeof(rotation));
	float scale[3] = { 1.f, 1.f, 1.f };
	blob.WriteData("scale", reinterpret_cast<uint8_t*>(scale), sizeof(scale));
}

void TransformComponentToBlob(const nlohmann::json& rawJson, IDataBlob& blob)
{
	if (rawJson.find("position") != rawJson.end())
	{
		ASSERT_FATAL(rawJson["position"].is_array());
		float position[3];
		position[0] = rawJson["position"][0];
		position[1] = rawJson["position"][1];
		position[2] = rawJson["position"][2];
		blob.WriteData("position", reinterpret_cast<uint8_t*>(position), sizeof(position));
	}

	if (rawJson.find("rotation") != rawJson.end())
	{
		ASSERT_FATAL(rawJson["rotation"].is_array());
		float rotation[4];
		rotation[0] = rawJson["rotation"][0];
		rotation[1] = rawJson["rotation"][1];
		rotation[2] = rawJson["rotation"][2];
		rotation[2] = rawJson["rotation"][3];
		blob.WriteData("rotation", reinterpret_cast<uint8_t*>(rotation), sizeof(rotation));
	}

	if (rawJson.find("scale") != rawJson.end())
	{
		ASSERT_FATAL(rawJson["scale"].is_array());
		float scale[3];
		scale[0] = rawJson["scale"][0];
		scale[1] = rawJson["scale"][1];
		scale[2] = rawJson["scale"][2];
		blob.WriteData("scale", reinterpret_cast<uint8_t*>(scale), sizeof(scale));
	}
}

void TransformManager::InitializeFromBlob(const tmp::vector<EntityId>& entities, Zmey::MemoryInputStream& stream)
{
	m_Positions.resize(entities.size());
	size_t positionBufferLength = sizeof(Vector3) * entities.size();
	stream.Read(reinterpret_cast<uint8_t*>(&m_Positions[0]), positionBufferLength);

	m_Rotations.resize(entities.size());
	size_t rotationBufferLength = sizeof(Quaternion) * entities.size();
	stream.Read(reinterpret_cast<uint8_t*>(&m_Rotations[0]), rotationBufferLength);

	m_Scales.resize(entities.size());
	size_t scaleBufferLength = sizeof(Vector3) * entities.size();
	stream.Read(reinterpret_cast<uint8_t*>(&m_Scales[0]), scaleBufferLength);
}

DEFINE_COMPONENT_MANAGER(TransformManager, Transform, &Zmey::Components::TransformComponentDefaults, &Zmey::Components::TransformComponentToBlob);

}
}<commit_msg>The transform manager now properly initializes its entity map when deserializing.<commit_after>#include <Zmey/Components/TransformManager.h>

#include <nlohmann/json.hpp>

#include <Zmey/MemoryStream.h>
#include <Zmey/Components/ComponentRegistry.h>

namespace Zmey
{
namespace Components
{
TransformInstance TransformManager::Lookup(EntityId id)
{
	return TransformInstance(*this, id);
}

void TransformManager::Simulate(float deltaTime)
{
	for (auto& pos : m_Positions)
	{
		pos += Vector3(0.05f, 0.05f, 0.05f) * deltaTime;
	}
}

void TransformComponentDefaults(IDataBlob& blob)
{
	float position[3] = { 0.f, 0.f, 0.f };
	blob.WriteData("position", reinterpret_cast<uint8_t*>(position), sizeof(position));
	float rotation[4] = { 0.f, 0.f, 0.f, 1.f };
	blob.WriteData("rotation", reinterpret_cast<uint8_t*>(rotation), sizeof(rotation));
	float scale[3] = { 1.f, 1.f, 1.f };
	blob.WriteData("scale", reinterpret_cast<uint8_t*>(scale), sizeof(scale));
}

void TransformComponentToBlob(const nlohmann::json& rawJson, IDataBlob& blob)
{
	if (rawJson.find("position") != rawJson.end())
	{
		ASSERT_FATAL(rawJson["position"].is_array());
		float position[3];
		position[0] = rawJson["position"][0];
		position[1] = rawJson["position"][1];
		position[2] = rawJson["position"][2];
		blob.WriteData("position", reinterpret_cast<uint8_t*>(position), sizeof(position));
	}

	if (rawJson.find("rotation") != rawJson.end())
	{
		ASSERT_FATAL(rawJson["rotation"].is_array());
		float rotation[4];
		rotation[0] = rawJson["rotation"][0];
		rotation[1] = rawJson["rotation"][1];
		rotation[2] = rawJson["rotation"][2];
		rotation[2] = rawJson["rotation"][3];
		blob.WriteData("rotation", reinterpret_cast<uint8_t*>(rotation), sizeof(rotation));
	}

	if (rawJson.find("scale") != rawJson.end())
	{
		ASSERT_FATAL(rawJson["scale"].is_array());
		float scale[3];
		scale[0] = rawJson["scale"][0];
		scale[1] = rawJson["scale"][1];
		scale[2] = rawJson["scale"][2];
		blob.WriteData("scale", reinterpret_cast<uint8_t*>(scale), sizeof(scale));
	}
}

void TransformManager::InitializeFromBlob(const tmp::vector<EntityId>& entities, Zmey::MemoryInputStream& stream)
{
	m_Positions.resize(entities.size());
	size_t positionBufferLength = sizeof(Vector3) * entities.size();
	stream.Read(reinterpret_cast<uint8_t*>(&m_Positions[0]), positionBufferLength);

	m_Rotations.resize(entities.size());
	size_t rotationBufferLength = sizeof(Quaternion) * entities.size();
	stream.Read(reinterpret_cast<uint8_t*>(&m_Rotations[0]), rotationBufferLength);

	m_Scales.resize(entities.size());
	size_t scaleBufferLength = sizeof(Vector3) * entities.size();
	stream.Read(reinterpret_cast<uint8_t*>(&m_Scales[0]), scaleBufferLength);

	// Fill the entity map
	for (EntityId::IndexType i = 0u; i < entities.size(); ++i)
	{
		m_EntityToIndex[entities[i]] = i;
	}
}

DEFINE_COMPONENT_MANAGER(TransformManager, Transform, &Zmey::Components::TransformComponentDefaults, &Zmey::Components::TransformComponentToBlob);

}
}<|endoftext|>


<commit_before><commit_msg>Minor edit<commit_after><|endoftext|>


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

class Solution {
public:
    /**
     * @param expression: A string array
     * @return: The Polish notation of this expression
     */
    vector<string> convertToPN(vector<string> &expression) {
        vector<string> output;
        infixToPrefix(expression, output);
        return output;
    }

    // Convert Infix to Prefix Expression.
    void infixToPrefix(vector<string>& infix, vector<string>& prefix) {
        reverse(infix.begin(), infix.end());
        stack<string> s;
        for (const auto& tok : infix) {
            if (stoi(tok)) {
                prefix.emplace_back(tok);
            } else if (tok == ")") {
                s.emplace(tok);
            } else if (tok == "(") {
                while (!s.empty()) {
                    tok = s.top();
                    s.pop();
                    if (tok == ")") {
                        break;
                    }
                    prefix.emplace_back(tok);
                }
            } else {
                while (!s.empty() && precedence(tok) < precedence(s.top())) {
                    prefix.emplace_back(s.top());
                    s.pop();
                }
                s.emplace(tok);
            }
        }
        while (!s.empty()) {
            prefix.emplace_back(s.top());
            s.pop();
        }
        reverse(prefix.begin(), prefix.end());
    }

    int precedence(string x) {
        if (x == ")") {
            return 0;
        } else if (x == "+" || x == "-") {
            return 1;
        } else if (x == "*" || x == "/") {
            return 2;
        }
        return 3;
    }
};
<commit_msg>Update convert-expression-to-polish-notation.cpp<commit_after>// Time:  O(n)
// Space: O(n)

class Solution {
public:
    /**
     * @param expression: A string array
     * @return: The Polish notation of this expression
     */
    vector<string> convertToPN(vector<string> &expression) {
        vector<string> output;
        infixToPrefix(expression, output);
        return output;
    }

    // Convert Infix to Prefix Expression.
    void infixToPrefix(vector<string>& infix, vector<string>& prefix) {
        reverse(infix.begin(), infix.end());
        stack<string> s;
        for (auto& tok : infix) {
            if (atoi(tok.c_str())) {
                prefix.emplace_back(tok);
            } else if (tok == ")") {
                s.emplace(tok);
            } else if (tok == "(") {
                while (!s.empty()) {
                    tok = s.top();
                    s.pop();
                    if (tok == ")") {
                        break;
                    }
                    prefix.emplace_back(tok);
                }
            } else {
                while (!s.empty() && precedence(tok) < precedence(s.top())) {
                    prefix.emplace_back(s.top());
                    s.pop();
                }
                s.emplace(tok);
            }
        }
        while (!s.empty()) {
            prefix.emplace_back(s.top());
            s.pop();
        }
        reverse(prefix.begin(), prefix.end());
    }

    int precedence(string x) {
        if (x == ")") {
            return 0;
        } else if (x == "+" || x == "-") {
            return 1;
        } else if (x == "*" || x == "/") {
            return 2;
        }
        return 3;
    }
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, Cryptonomex, Inc.
 * All rights reserved.
 *
 * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
 * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
 * are permitted until September 8, 2015, provided that the following conditions are met:
 *
 * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/io/raw.hpp>
#include <fc/bitutil.hpp>
#include <fc/smart_ref_impl.hpp>
#include <algorithm>

namespace graphene { namespace chain {

digest_type processed_transaction::merkle_digest()const
{
   return digest_type::hash(*this);
}

digest_type transaction::digest()const
{
   digest_type::encoder enc;
   fc::raw::pack( enc, *this );
   return enc.result();
}
void transaction::validate() const
{
   FC_ASSERT( operations.size() > 0, "A transaction must have at least one operation", ("trx",*this) );
   for( const auto& op : operations )
      operation_validate(op);
}

graphene::chain::transaction_id_type graphene::chain::transaction::id() const
{
   digest_type::encoder enc;
   fc::raw::pack(enc, *this);
   auto hash = enc.result();
   transaction_id_type result;
   memcpy(result._hash, hash._hash, std::min(sizeof(result), sizeof(hash)));
   return result;
}

const signature_type& graphene::chain::signed_transaction::sign(const private_key_type& key)
{
   signatures.push_back(key.sign_compact(digest()));
   return signatures.back();
}
signature_type graphene::chain::signed_transaction::sign(const private_key_type& key)const
{
   return key.sign_compact(digest());
}

void transaction::set_expiration( fc::time_point_sec expiration_time )
{
    expiration = expiration_time;
}

void transaction::set_reference_block( const block_id_type& reference_block )
{
   ref_block_num = fc::endian_reverse_u32(reference_block._hash[0]);
   if( ref_block_num == 0 ) ref_block_prefix = 0;
   ref_block_prefix = reference_block._hash[1];
}

void transaction::get_required_authorities( flat_set<account_id_type>& active, flat_set<account_id_type>& owner, vector<authority>& other )const
{
   for( const auto& op : operations )
      operation_get_required_authorities( op, active, owner, other );
}

struct sign_state
{
      /** returns true if we have a signature for this key or can
       * produce a signature for this key, else returns false.
       */
      bool signed_by( const public_key_type& k )
      {
         auto itr = provided_signatures.find(k);
         if( itr == provided_signatures.end() )
         {
            auto pk = available_keys.find(k);
            if( pk  != available_keys.end() )
               return provided_signatures[k] = true;
            return false;
         }
         return itr->second = true;
      }

      bool check_authority( account_id_type id )
      {
         if( approved_by.find(id) != approved_by.end() ) return true;
         return check_authority( get_active(id) );
      }

      /**
       *  Checks to see if we have signatures of the active authorites of
       *  the accounts specified in authority or the keys specified.
       */
      bool check_authority( const authority* au, uint32_t depth = 0 )
      {
         if( au == nullptr ) return false;
         const authority& auth = *au;

         uint32_t total_weight = 0;
         for( const auto& k : auth.key_auths )
            if( signed_by( k.first ) )
            {
               total_weight += k.second;
               if( total_weight >= auth.weight_threshold )
                  return true;
            }

         for( const auto& a : auth.account_auths )
         {
            if( approved_by.find(a.first) == approved_by.end() )
            {
               if( depth == max_recursion )
                  return false;
               if( check_authority( get_active( a.first ), depth+1 ) )
               {
                  approved_by.insert( a.first );
                  total_weight += a.second;
                  if( total_weight >= auth.weight_threshold )
                     return true;
               }
            }
            else
            {
               total_weight += a.second;
               if( total_weight >= auth.weight_threshold )
                  return true;
            }
         }
         return total_weight >= auth.weight_threshold;
      }

      bool remove_unused_signatures()
      {
         vector<public_key_type> remove_sigs;
         for( const auto& sig : provided_signatures )
            if( !sig.second ) remove_sigs.push_back( sig.first );

         for( auto& sig : remove_sigs )
            provided_signatures.erase(sig);

         return remove_sigs.size() != 0;
      }

      sign_state( const flat_set<public_key_type>& sigs,
                  const std::function<const authority*(account_id_type)>& a,
                  const flat_set<public_key_type>& keys = flat_set<public_key_type>() )
      :get_active(a),available_keys(keys)
      {
         for( const auto& key : sigs )
            provided_signatures[ key ] = false;
         approved_by.insert( GRAPHENE_TEMP_ACCOUNT  );
      }

      const std::function<const authority*(account_id_type)>& get_active;
      const flat_set<public_key_type>&                        available_keys;

      flat_map<public_key_type,bool>   provided_signatures;
      flat_set<account_id_type>        approved_by;
      uint32_t                         max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH;
};

void verify_authority( const vector<operation>& ops, const flat_set<public_key_type>& sigs,
                       const std::function<const authority*(account_id_type)>& get_active,
                       const std::function<const authority*(account_id_type)>& get_owner,
                       uint32_t max_recursion_depth,
                       bool  allow_committe,
                       const flat_set<account_id_type>& active_aprovals,
                       const flat_set<account_id_type>& owner_approvals )
{ try {
   flat_set<account_id_type> required_active;
   flat_set<account_id_type> required_owner;
   vector<authority> other;

   for( const auto& op : ops )
      operation_get_required_authorities( op, required_active, required_owner, other );

   if( !allow_committe )
      GRAPHENE_ASSERT( required_active.find(GRAPHENE_COMMITTEE_ACCOUNT) == required_active.end(),
                       invalid_committee_approval, "Committee account may only propose transactions" );

   sign_state s(sigs,get_active);
   s.max_recursion = max_recursion_depth;
   for( auto& id : active_aprovals )
      s.approved_by.insert( id );
   for( auto& id : owner_approvals )
      s.approved_by.insert( id );

   for( const auto& auth : other )
   {
      GRAPHENE_ASSERT( s.check_authority(&auth), tx_missing_other_auth, "Missing Authority", ("auth",auth)("sigs",sigs) );
   }

   // fetch all of the top level authorities
   for( auto id : required_active )
   {
      GRAPHENE_ASSERT( s.check_authority(id) ||
                       s.check_authority(get_owner(id)),
                       tx_missing_active_auth, "Missing Active Authority ${id}", ("id",id)("auth",*get_active(id))("owner",*get_owner(id)) );
   }

   for( auto id : required_owner )
   {
      GRAPHENE_ASSERT( owner_approvals.find(id) != owner_approvals.end() ||
                       s.check_authority(get_owner(id)),
                       tx_missing_other_auth, "Missing Owner Authority ${id}", ("id",id)("auth",*get_owner(id)) );
   }

   GRAPHENE_ASSERT(
      !s.remove_unused_signatures(),
      tx_irrelevant_sig,
      "Unnecessary signature(s) detected"
      );
} FC_CAPTURE_AND_RETHROW( (ops)(sigs) ) }

flat_set<public_key_type> signed_transaction::get_signature_keys()const
{ try {
   auto d = digest();
   flat_set<public_key_type> result;
   for( const auto&  sig : signatures )
   {
      GRAPHENE_ASSERT(
         result.insert( fc::ecc::public_key(sig,d) ).second,
         tx_duplicate_sig,
         "Duplicate Signature detected" );
   }
   return result;
} FC_CAPTURE_AND_RETHROW() }

set<public_key_type> signed_transaction::get_required_signatures( const flat_set<public_key_type>& available_keys,
                                              const std::function<const authority*(account_id_type)>& get_active,
                                              const std::function<const authority*(account_id_type)>& get_owner,
                                              uint32_t max_recursion_depth )const
{
   flat_set<account_id_type> required_active;
   flat_set<account_id_type> required_owner;
   vector<authority> other;
   get_required_authorities( required_active, required_owner, other );

   sign_state s(get_signature_keys(),get_active,available_keys);
   s.max_recursion = max_recursion_depth;

   for( const auto& auth : other )
      s.check_authority(&auth);
   for( auto& owner : required_owner )
      s.check_authority( get_owner( owner ) );
   for( auto& active : required_active )
      s.check_authority( active  );

   s.remove_unused_signatures();

   set<public_key_type> result;

   for( auto& provided_sig : s.provided_signatures )
      if( available_keys.find( provided_sig.first ) != available_keys.end() )
         result.insert( provided_sig.first );

   return result;
}

set<public_key_type> signed_transaction::minimize_required_signatures(
   const flat_set<public_key_type>& available_keys,
   const std::function<const authority*(account_id_type)>& get_active,
   const std::function<const authority*(account_id_type)>& get_owner,
   uint32_t max_recursion
   ) const
{
   set< public_key_type > s = get_required_signatures( available_keys, get_active, get_owner, max_recursion );
   flat_set< public_key_type > result( s.begin(), s.end() );

   for( const public_key_type& k : s )
   {
      result.erase( k );
      try
      {
         graphene::chain::verify_authority( operations, result, get_active, get_owner, max_recursion );
         continue;  // element stays erased if verify_authority is ok
      }
      catch( const tx_missing_owner_auth& e ) {}
      catch( const tx_missing_active_auth& e ) {}
      catch( const tx_missing_other_auth& e ) {}
      result.insert( k );
   }
   return set<public_key_type>( result.begin(), result.end() );
}

void signed_transaction::verify_authority( const std::function<const authority*(account_id_type)>& get_active,
                                           const std::function<const authority*(account_id_type)>& get_owner,
                                           uint32_t max_recursion )const
{ try {
   graphene::chain::verify_authority( operations, get_signature_keys(), get_active, get_owner, max_recursion );
} FC_CAPTURE_AND_RETHROW( (*this) ) }

void transaction::get_impacted_accounts( flat_set<account_id_type>& impacted ) const
{
   for( const auto& op : operations )
      operation_get_impacted_accounts( op, impacted );
}

} } // graphene::chain
<commit_msg>Fix throwing incorrect exception type<commit_after>/*
 * Copyright (c) 2015, Cryptonomex, Inc.
 * All rights reserved.
 *
 * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
 * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
 * are permitted until September 8, 2015, provided that the following conditions are met:
 *
 * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/io/raw.hpp>
#include <fc/bitutil.hpp>
#include <fc/smart_ref_impl.hpp>
#include <algorithm>

namespace graphene { namespace chain {

digest_type processed_transaction::merkle_digest()const
{
   return digest_type::hash(*this);
}

digest_type transaction::digest()const
{
   digest_type::encoder enc;
   fc::raw::pack( enc, *this );
   return enc.result();
}
void transaction::validate() const
{
   FC_ASSERT( operations.size() > 0, "A transaction must have at least one operation", ("trx",*this) );
   for( const auto& op : operations )
      operation_validate(op);
}

graphene::chain::transaction_id_type graphene::chain::transaction::id() const
{
   digest_type::encoder enc;
   fc::raw::pack(enc, *this);
   auto hash = enc.result();
   transaction_id_type result;
   memcpy(result._hash, hash._hash, std::min(sizeof(result), sizeof(hash)));
   return result;
}

const signature_type& graphene::chain::signed_transaction::sign(const private_key_type& key)
{
   signatures.push_back(key.sign_compact(digest()));
   return signatures.back();
}
signature_type graphene::chain::signed_transaction::sign(const private_key_type& key)const
{
   return key.sign_compact(digest());
}

void transaction::set_expiration( fc::time_point_sec expiration_time )
{
    expiration = expiration_time;
}

void transaction::set_reference_block( const block_id_type& reference_block )
{
   ref_block_num = fc::endian_reverse_u32(reference_block._hash[0]);
   if( ref_block_num == 0 ) ref_block_prefix = 0;
   ref_block_prefix = reference_block._hash[1];
}

void transaction::get_required_authorities( flat_set<account_id_type>& active, flat_set<account_id_type>& owner, vector<authority>& other )const
{
   for( const auto& op : operations )
      operation_get_required_authorities( op, active, owner, other );
}

struct sign_state
{
      /** returns true if we have a signature for this key or can
       * produce a signature for this key, else returns false.
       */
      bool signed_by( const public_key_type& k )
      {
         auto itr = provided_signatures.find(k);
         if( itr == provided_signatures.end() )
         {
            auto pk = available_keys.find(k);
            if( pk  != available_keys.end() )
               return provided_signatures[k] = true;
            return false;
         }
         return itr->second = true;
      }

      bool check_authority( account_id_type id )
      {
         if( approved_by.find(id) != approved_by.end() ) return true;
         return check_authority( get_active(id) );
      }

      /**
       *  Checks to see if we have signatures of the active authorites of
       *  the accounts specified in authority or the keys specified.
       */
      bool check_authority( const authority* au, uint32_t depth = 0 )
      {
         if( au == nullptr ) return false;
         const authority& auth = *au;

         uint32_t total_weight = 0;
         for( const auto& k : auth.key_auths )
            if( signed_by( k.first ) )
            {
               total_weight += k.second;
               if( total_weight >= auth.weight_threshold )
                  return true;
            }

         for( const auto& a : auth.account_auths )
         {
            if( approved_by.find(a.first) == approved_by.end() )
            {
               if( depth == max_recursion )
                  return false;
               if( check_authority( get_active( a.first ), depth+1 ) )
               {
                  approved_by.insert( a.first );
                  total_weight += a.second;
                  if( total_weight >= auth.weight_threshold )
                     return true;
               }
            }
            else
            {
               total_weight += a.second;
               if( total_weight >= auth.weight_threshold )
                  return true;
            }
         }
         return total_weight >= auth.weight_threshold;
      }

      bool remove_unused_signatures()
      {
         vector<public_key_type> remove_sigs;
         for( const auto& sig : provided_signatures )
            if( !sig.second ) remove_sigs.push_back( sig.first );

         for( auto& sig : remove_sigs )
            provided_signatures.erase(sig);

         return remove_sigs.size() != 0;
      }

      sign_state( const flat_set<public_key_type>& sigs,
                  const std::function<const authority*(account_id_type)>& a,
                  const flat_set<public_key_type>& keys = flat_set<public_key_type>() )
      :get_active(a),available_keys(keys)
      {
         for( const auto& key : sigs )
            provided_signatures[ key ] = false;
         approved_by.insert( GRAPHENE_TEMP_ACCOUNT  );
      }

      const std::function<const authority*(account_id_type)>& get_active;
      const flat_set<public_key_type>&                        available_keys;

      flat_map<public_key_type,bool>   provided_signatures;
      flat_set<account_id_type>        approved_by;
      uint32_t                         max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH;
};

void verify_authority( const vector<operation>& ops, const flat_set<public_key_type>& sigs,
                       const std::function<const authority*(account_id_type)>& get_active,
                       const std::function<const authority*(account_id_type)>& get_owner,
                       uint32_t max_recursion_depth,
                       bool  allow_committe,
                       const flat_set<account_id_type>& active_aprovals,
                       const flat_set<account_id_type>& owner_approvals )
{ try {
   flat_set<account_id_type> required_active;
   flat_set<account_id_type> required_owner;
   vector<authority> other;

   for( const auto& op : ops )
      operation_get_required_authorities( op, required_active, required_owner, other );

   if( !allow_committe )
      GRAPHENE_ASSERT( required_active.find(GRAPHENE_COMMITTEE_ACCOUNT) == required_active.end(),
                       invalid_committee_approval, "Committee account may only propose transactions" );

   sign_state s(sigs,get_active);
   s.max_recursion = max_recursion_depth;
   for( auto& id : active_aprovals )
      s.approved_by.insert( id );
   for( auto& id : owner_approvals )
      s.approved_by.insert( id );

   for( const auto& auth : other )
   {
      GRAPHENE_ASSERT( s.check_authority(&auth), tx_missing_other_auth, "Missing Authority", ("auth",auth)("sigs",sigs) );
   }

   // fetch all of the top level authorities
   for( auto id : required_active )
   {
      GRAPHENE_ASSERT( s.check_authority(id) ||
                       s.check_authority(get_owner(id)),
                       tx_missing_active_auth, "Missing Active Authority ${id}", ("id",id)("auth",*get_active(id))("owner",*get_owner(id)) );
   }

   for( auto id : required_owner )
   {
      GRAPHENE_ASSERT( owner_approvals.find(id) != owner_approvals.end() ||
                       s.check_authority(get_owner(id)),
                       tx_missing_owner_auth, "Missing Owner Authority ${id}", ("id",id)("auth",*get_owner(id)) );
   }

   GRAPHENE_ASSERT(
      !s.remove_unused_signatures(),
      tx_irrelevant_sig,
      "Unnecessary signature(s) detected"
      );
} FC_CAPTURE_AND_RETHROW( (ops)(sigs) ) }

flat_set<public_key_type> signed_transaction::get_signature_keys()const
{ try {
   auto d = digest();
   flat_set<public_key_type> result;
   for( const auto&  sig : signatures )
   {
      GRAPHENE_ASSERT(
         result.insert( fc::ecc::public_key(sig,d) ).second,
         tx_duplicate_sig,
         "Duplicate Signature detected" );
   }
   return result;
} FC_CAPTURE_AND_RETHROW() }

set<public_key_type> signed_transaction::get_required_signatures( const flat_set<public_key_type>& available_keys,
                                              const std::function<const authority*(account_id_type)>& get_active,
                                              const std::function<const authority*(account_id_type)>& get_owner,
                                              uint32_t max_recursion_depth )const
{
   flat_set<account_id_type> required_active;
   flat_set<account_id_type> required_owner;
   vector<authority> other;
   get_required_authorities( required_active, required_owner, other );

   sign_state s(get_signature_keys(),get_active,available_keys);
   s.max_recursion = max_recursion_depth;

   for( const auto& auth : other )
      s.check_authority(&auth);
   for( auto& owner : required_owner )
      s.check_authority( get_owner( owner ) );
   for( auto& active : required_active )
      s.check_authority( active  );

   s.remove_unused_signatures();

   set<public_key_type> result;

   for( auto& provided_sig : s.provided_signatures )
      if( available_keys.find( provided_sig.first ) != available_keys.end() )
         result.insert( provided_sig.first );

   return result;
}

set<public_key_type> signed_transaction::minimize_required_signatures(
   const flat_set<public_key_type>& available_keys,
   const std::function<const authority*(account_id_type)>& get_active,
   const std::function<const authority*(account_id_type)>& get_owner,
   uint32_t max_recursion
   ) const
{
   set< public_key_type > s = get_required_signatures( available_keys, get_active, get_owner, max_recursion );
   flat_set< public_key_type > result( s.begin(), s.end() );

   for( const public_key_type& k : s )
   {
      result.erase( k );
      try
      {
         graphene::chain::verify_authority( operations, result, get_active, get_owner, max_recursion );
         continue;  // element stays erased if verify_authority is ok
      }
      catch( const tx_missing_owner_auth& e ) {}
      catch( const tx_missing_active_auth& e ) {}
      catch( const tx_missing_other_auth& e ) {}
      result.insert( k );
   }
   return set<public_key_type>( result.begin(), result.end() );
}

void signed_transaction::verify_authority( const std::function<const authority*(account_id_type)>& get_active,
                                           const std::function<const authority*(account_id_type)>& get_owner,
                                           uint32_t max_recursion )const
{ try {
   graphene::chain::verify_authority( operations, get_signature_keys(), get_active, get_owner, max_recursion );
} FC_CAPTURE_AND_RETHROW( (*this) ) }

void transaction::get_impacted_accounts( flat_set<account_id_type>& impacted ) const
{
   for( const auto& op : operations )
      operation_get_impacted_accounts( op, impacted );
}

} } // graphene::chain
<|endoftext|>


<commit_before>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include "vvplatform.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include "vvopengl.h"

#if defined(HAVE_X11) && !defined(__APPLE__)
#include <GL/glx.h>
#include <X11/Xlib.h>
#endif

#ifdef VV_DEBUG_MEMORY
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif

#include "vvtoolshed.h"
#include "vvprintgl.h"
#include "vvdebugmsg.h"

using std::cerr;
using std::endl;

#if defined(HAVE_X11) && !defined(__APPLE__)
Display* dsp = NULL;
#endif

#ifdef __APPLE__
#include <CoreGraphics/CoreGraphics.h>
#endif

/** Constructor.
  Builds the bitmap font.
  @param hDC Windows device context
*/
vvPrintGL::vvPrintGL()
  : _fontColor(vvVector4(1.0f, 1.0f, 1.0f, 1.0f))
{
  vvDebugMsg::msg(3, "vvPrintGL::vvPrintGL()");

#ifdef _WIN32
  HFONT font;                                     // Windows Font ID
  HDC   hDC;                                      // Windows device context

  base = glGenLists(96);                          // Storage For 96 Characters

  font = CreateFont(-24,                          // Height Of Font
    0,                                            // Width Of Font
    0,                                            // Angle Of Escapement
    0,                                            // Orientation Angle
    FW_BOLD,                                      // Font Weight
    FALSE,                                        // Italic
    FALSE,                                        // Underline
    FALSE,                                        // Strikeout
    ANSI_CHARSET,                                 // Character Set Identifier
    OUT_TT_PRECIS,                                // Output Precision
    CLIP_DEFAULT_PRECIS,                          // Clipping Precision
    ANTIALIASED_QUALITY,                          // Output Quality
    FF_DONTCARE|DEFAULT_PITCH,                    // Family And Pitch
    TEXT("Courier New"));                         // Font Name

  hDC = wglGetCurrentDC();
  SelectObject(hDC, font);                        // Selects The Font We Want

  wglUseFontBitmaps(hDC, 32, 96, base);           // Builds 96 Characters Starting At Character 32
#elif defined(HAVE_X11) && !defined(__APPLE__)
  if (dsp == NULL)
  {
    dsp = XOpenDisplay(NULL);
  }
  XFontStruct* font = XLoadQueryFont(dsp, "-*-courier-bold-r-normal--20-*-*-*-*-*-*-*");

  if (font)
  {
    const Font id = font->fid;
    uint first = font->min_char_or_byte2;
    uint last = font->max_char_or_byte2;
    base = glGenLists(last + 1);

    if (base)
    {
      glXUseXFont(id, first, last - first + 1, base + first);
    }
  }
#endif
}

/** Destructor.
  Deletes the bitmap font.
*/
vvPrintGL::~vvPrintGL()
{
  vvDebugMsg::msg(3, "vvPrintGL::~vvPrintGL()");

  glDeleteLists(base, 96);                        // Delete All 96 Characters
}

//----------------------------------------------------------------------------
/** Print a text string to the current screen position.
  The current OpenGL drawing color is used.
  @param x,y text position [0..1]
  @param fmt printf compatible argument format
*/
void vvPrintGL::print(const float x, const float y, const char *fmt, ...)
{

  vvDebugMsg::msg(3, "vvPrintGL::print()");

  va_list ap;                                     // Pointer To List Of Arguments
  char    text[1024];                             // Holds Our String

  if (fmt == NULL)                                // If There's No Text
    return;                                       // Do Nothing

  va_start(ap, fmt);                              // Parses The String For Variables
  vsprintf(text, fmt, ap);                        // And Converts Symbols To Actual Numbers
  va_end(ap);                                     // Results Are Stored In Text

  // make sure that only valid display lists are called
  for(char *p=text; *p; ++p)
  {
      int c = *p;
      if(c < 32 || c >= 128)
          *p = '+';
  }

  saveGLState();

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glRasterPos2f(x, y);

#if !defined(__APPLE__)
  glColor4f(_fontColor[0], _fontColor[1], _fontColor[2], _fontColor[3]);
#ifdef _WIN32
  glListBase(base - 32);                          // Sets The Base Character to 32
#else
  glListBase(base);
#endif
                                                    // Draws The Display List Text
  glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
#elif defined(__APPLE__)
  size_t size = 24;
  std::string font = "Courier New";
  size_t len = strlen(text);
  CGFloat w = size * len;
  CGFloat h = size;
  void* buf = NULL;
  buf = calloc(4 * w, h);
  CGContextRef ctx = CGBitmapContextCreate(buf, w, h, 8, w * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
  CGContextSelectFont(ctx, font.c_str(), size, kCGEncodingMacRoman);//kCGEncodingFontSpecific);
  CGContextSetTextDrawingMode(ctx, kCGTextFill);
  CGContextSetRGBFillColor(ctx, _fontColor[0], _fontColor[1], _fontColor[2], _fontColor[3]);
  CGContextSetTextMatrix(ctx, CGAffineTransformIdentity);
  CGContextTranslateCTM(ctx, 0, size);
  CGContextScaleCTM(ctx, 1, -1);
  CGContextShowTextAtPoint(ctx, 0, 0, text, len);

  glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, buf);

  CGContextRelease(ctx);
  free(buf);
#endif
  restoreGLState();
}

//----------------------------------------------------------------------------
/// Set the font color.
void vvPrintGL::setFontColor(const vvVector4& fontColor)
{
  _fontColor = fontColor;
}

//----------------------------------------------------------------------------
/// Save GL state for text display.
void vvPrintGL::saveGLState()
{
  vvDebugMsg::msg(3, "vvPrintGL::saveGLState()");

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();

  glPushAttrib(GL_CURRENT_BIT | GL_TRANSFORM_BIT | GL_LIST_BIT);
}

//----------------------------------------------------------------------------
/// Restore GL state to previous state.
void vvPrintGL::restoreGLState()
{
  vvDebugMsg::msg(3, "vvPrintGL::restoreGLState()");

  glPopAttrib();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();
}

//============================================================================
// End of File
//============================================================================
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<commit_msg>vvprintgl needs config header<commit_after>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#ifdef HAVE_CONFIG_H
#include "vvconfig.h"
#endif

#include "vvplatform.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include "vvopengl.h"

#if defined(HAVE_X11) && !defined(__APPLE__)
#include <GL/glx.h>
#include <X11/Xlib.h>
#endif

#ifdef VV_DEBUG_MEMORY
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif

#include "vvtoolshed.h"
#include "vvprintgl.h"
#include "vvdebugmsg.h"

using std::cerr;
using std::endl;

#if defined(HAVE_X11) && !defined(__APPLE__)
Display* dsp = NULL;
#endif

#ifdef __APPLE__
#include <CoreGraphics/CoreGraphics.h>
#endif

/** Constructor.
  Builds the bitmap font.
  @param hDC Windows device context
*/
vvPrintGL::vvPrintGL()
  : _fontColor(vvVector4(1.0f, 1.0f, 1.0f, 1.0f))
{
  vvDebugMsg::msg(3, "vvPrintGL::vvPrintGL()");

#ifdef _WIN32
  HFONT font;                                     // Windows Font ID
  HDC   hDC;                                      // Windows device context

  base = glGenLists(96);                          // Storage For 96 Characters

  font = CreateFont(-24,                          // Height Of Font
    0,                                            // Width Of Font
    0,                                            // Angle Of Escapement
    0,                                            // Orientation Angle
    FW_BOLD,                                      // Font Weight
    FALSE,                                        // Italic
    FALSE,                                        // Underline
    FALSE,                                        // Strikeout
    ANSI_CHARSET,                                 // Character Set Identifier
    OUT_TT_PRECIS,                                // Output Precision
    CLIP_DEFAULT_PRECIS,                          // Clipping Precision
    ANTIALIASED_QUALITY,                          // Output Quality
    FF_DONTCARE|DEFAULT_PITCH,                    // Family And Pitch
    TEXT("Courier New"));                         // Font Name

  hDC = wglGetCurrentDC();
  SelectObject(hDC, font);                        // Selects The Font We Want

  wglUseFontBitmaps(hDC, 32, 96, base);           // Builds 96 Characters Starting At Character 32
#elif defined(HAVE_X11) && !defined(__APPLE__)
  if (dsp == NULL)
  {
    dsp = XOpenDisplay(NULL);
  }
  XFontStruct* font = XLoadQueryFont(dsp, "-*-courier-bold-r-normal--20-*-*-*-*-*-*-*");

  if (font)
  {
    const Font id = font->fid;
    uint first = font->min_char_or_byte2;
    uint last = font->max_char_or_byte2;
    base = glGenLists(last + 1);

    if (base)
    {
      glXUseXFont(id, first, last - first + 1, base + first);
    }
  }
#endif
}

/** Destructor.
  Deletes the bitmap font.
*/
vvPrintGL::~vvPrintGL()
{
  vvDebugMsg::msg(3, "vvPrintGL::~vvPrintGL()");

  glDeleteLists(base, 96);                        // Delete All 96 Characters
}

//----------------------------------------------------------------------------
/** Print a text string to the current screen position.
  The current OpenGL drawing color is used.
  @param x,y text position [0..1]
  @param fmt printf compatible argument format
*/
void vvPrintGL::print(const float x, const float y, const char *fmt, ...)
{

  vvDebugMsg::msg(3, "vvPrintGL::print()");

  va_list ap;                                     // Pointer To List Of Arguments
  char    text[1024];                             // Holds Our String

  if (fmt == NULL)                                // If There's No Text
    return;                                       // Do Nothing

  va_start(ap, fmt);                              // Parses The String For Variables
  vsprintf(text, fmt, ap);                        // And Converts Symbols To Actual Numbers
  va_end(ap);                                     // Results Are Stored In Text

  // make sure that only valid display lists are called
  for(char *p=text; *p; ++p)
  {
      int c = *p;
      if(c < 32 || c >= 128)
          *p = '+';
  }

  saveGLState();

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glRasterPos2f(x, y);

#if !defined(__APPLE__)
  glColor4f(_fontColor[0], _fontColor[1], _fontColor[2], _fontColor[3]);
#ifdef _WIN32
  glListBase(base - 32);                          // Sets The Base Character to 32
#else
  glListBase(base);
#endif
                                                    // Draws The Display List Text
  glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
#elif defined(__APPLE__)
  size_t size = 24;
  std::string font = "Courier New";
  size_t len = strlen(text);
  CGFloat w = size * len;
  CGFloat h = size;
  void* buf = NULL;
  buf = calloc(4 * w, h);
  CGContextRef ctx = CGBitmapContextCreate(buf, w, h, 8, w * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
  CGContextSelectFont(ctx, font.c_str(), size, kCGEncodingMacRoman);//kCGEncodingFontSpecific);
  CGContextSetTextDrawingMode(ctx, kCGTextFill);
  CGContextSetRGBFillColor(ctx, _fontColor[0], _fontColor[1], _fontColor[2], _fontColor[3]);
  CGContextSetTextMatrix(ctx, CGAffineTransformIdentity);
  CGContextTranslateCTM(ctx, 0, size);
  CGContextScaleCTM(ctx, 1, -1);
  CGContextShowTextAtPoint(ctx, 0, 0, text, len);

  glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, buf);

  CGContextRelease(ctx);
  free(buf);
#endif
  restoreGLState();
}

//----------------------------------------------------------------------------
/// Set the font color.
void vvPrintGL::setFontColor(const vvVector4& fontColor)
{
  _fontColor = fontColor;
}

//----------------------------------------------------------------------------
/// Save GL state for text display.
void vvPrintGL::saveGLState()
{
  vvDebugMsg::msg(3, "vvPrintGL::saveGLState()");

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();

  glPushAttrib(GL_CURRENT_BIT | GL_TRANSFORM_BIT | GL_LIST_BIT);
}

//----------------------------------------------------------------------------
/// Restore GL state to previous state.
void vvPrintGL::restoreGLState()
{
  vvDebugMsg::msg(3, "vvPrintGL::restoreGLState()");

  glPopAttrib();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();
}

//============================================================================
// End of File
//============================================================================
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<|endoftext|>


<commit_before>#ifndef MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#define MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/VelocityVerletIntegrator.hpp>
#include <mjolnir/core/UnderdampedLangevinIntegrator.hpp>
#include <mjolnir/core/BAOABLangevinIntegrator.hpp>
#include <mjolnir/core/SystemMotionRemover.hpp>
#include <mjolnir/input/utility.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/util/throw_exception.hpp>

namespace mjolnir
{

template<typename traitsT>
SystemMotionRemover<traitsT>
read_system_motion_remover(const toml::value& simulator)
{
    if(!simulator.contains("integrator") ||
       !simulator.at("integrator").contains("remove"))
    {
        return SystemMotionRemover<traitsT>(false, false, false);
    }

    const auto& remove = toml::find(simulator, "integrator", "remove");

    const bool translation = toml::find_or(remove, "translation", false);
    const bool rotation    = toml::find_or(remove, "rotation",    false);
    const bool rescale     = toml::find_or(remove, "rescale",     false);

    return SystemMotionRemover<traitsT>(translation, rotation, rescale);
}

template<typename traitsT>
VelocityVerletIntegrator<traitsT>
read_velocity_verlet_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    return VelocityVerletIntegrator<traitsT>(delta_t,
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
UnderdampedLangevinIntegrator<traitsT>
read_underdamped_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx){gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return UnderdampedLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
BAOABLangevinIntegrator<traitsT>
read_BAOAB_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx) {gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return BAOABLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

// A mapping object from type information (template parameter) to the actual
// read_xxx_integrator function
template<typename T>
struct read_integrator_impl;

template<typename traitsT>
struct read_integrator_impl<VelocityVerletIntegrator<traitsT>>
{
    static VelocityVerletIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_velocity_verlet_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<UnderdampedLangevinIntegrator<traitsT>>
{
    static UnderdampedLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_underdamped_langevin_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<BAOABLangevinIntegrator<traitsT>>
{
    static BAOABLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_BAOAB_langevin_integrator<traitsT>(sim);
    }
};

template<typename integratorT>
integratorT read_integrator(const toml::value& sim)
{
    if(sim.as_table().count("integrator") == 0)
    {
        throw_exception<std::runtime_error>(toml::format_error("[error] "
            "mjolnir::read_integrator: No integrator defined: ", sim, "here", {
            "expected value is one of the following.",
            "- \"VelocityVerlet\"     : simple and standard Velocity Verlet integrator.",
            "- \"UnderdampedLangevin\": simple Underdamped Langevin Integrator"
                                      " based on the Velocity Verlet",
            "- \"BAOABLangevin\"      : well-known BAOAB Langevin Integrator"
            }));
    }
    return read_integrator_impl<integratorT>::invoke(sim);
}

#ifdef MJOLNIR_SEPARATE_BUILD
extern template VelocityVerletIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);

extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);

extern template BAOABLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
#endif

} // mjolnir
#endif// MJOLNIR_READ_INTEGRATOR
<commit_msg>fix: suppress invalid warning messages<commit_after>#ifndef MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#define MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/VelocityVerletIntegrator.hpp>
#include <mjolnir/core/UnderdampedLangevinIntegrator.hpp>
#include <mjolnir/core/BAOABLangevinIntegrator.hpp>
#include <mjolnir/core/SystemMotionRemover.hpp>
#include <mjolnir/input/utility.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/util/throw_exception.hpp>

namespace mjolnir
{

template<typename traitsT>
SystemMotionRemover<traitsT>
read_system_motion_remover(const toml::value& simulator)
{
    if(!simulator.contains("integrator") ||
       !simulator.at("integrator").contains("remove"))
    {
        return SystemMotionRemover<traitsT>(false, false, false);
    }

    const auto& remove = toml::find(simulator, "integrator", "remove");

    const bool translation = toml::find_or(remove, "translation", false);
    const bool rotation    = toml::find_or(remove, "rotation",    false);
    const bool rescale     = toml::find_or(remove, "rescale",     false);

    return SystemMotionRemover<traitsT>(translation, rotation, rescale);
}

template<typename traitsT>
VelocityVerletIntegrator<traitsT>
read_velocity_verlet_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    return VelocityVerletIntegrator<traitsT>(delta_t,
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
UnderdampedLangevinIntegrator<traitsT>
read_underdamped_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s, "remove"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx){gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return UnderdampedLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
BAOABLangevinIntegrator<traitsT>
read_BAOAB_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s, "remove"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx) {gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return BAOABLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

// A mapping object from type information (template parameter) to the actual
// read_xxx_integrator function
template<typename T>
struct read_integrator_impl;

template<typename traitsT>
struct read_integrator_impl<VelocityVerletIntegrator<traitsT>>
{
    static VelocityVerletIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_velocity_verlet_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<UnderdampedLangevinIntegrator<traitsT>>
{
    static UnderdampedLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_underdamped_langevin_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<BAOABLangevinIntegrator<traitsT>>
{
    static BAOABLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_BAOAB_langevin_integrator<traitsT>(sim);
    }
};

template<typename integratorT>
integratorT read_integrator(const toml::value& sim)
{
    if(sim.as_table().count("integrator") == 0)
    {
        throw_exception<std::runtime_error>(toml::format_error("[error] "
            "mjolnir::read_integrator: No integrator defined: ", sim, "here", {
            "expected value is one of the following.",
            "- \"VelocityVerlet\"     : simple and standard Velocity Verlet integrator.",
            "- \"UnderdampedLangevin\": simple Underdamped Langevin Integrator"
                                      " based on the Velocity Verlet",
            "- \"BAOABLangevin\"      : well-known BAOAB Langevin Integrator"
            }));
    }
    return read_integrator_impl<integratorT>::invoke(sim);
}

#ifdef MJOLNIR_SEPARATE_BUILD
extern template VelocityVerletIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);

extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);

extern template BAOABLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
#endif

} // mjolnir
#endif// MJOLNIR_READ_INTEGRATOR
<|endoftext|>


<commit_before>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */

/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Default base with a few methods implemented in standard ways.
------------------------------------------------------------------------- */

#ifndef ATS_PK_DEFAULT_BASE_HH_
#define ATS_PK_DEFAULT_BASE_HH_

#include "Teuchos_ParameterList.hpp"

#include "VerboseObject.hh"
#include "pk.hh"

namespace Amanzi {

class PKDefaultBase : public PK_ATS {

 public:

  PKDefaultBase(const Teuchos::RCP<Teuchos::ParameterList>& plist,
                Teuchos::ParameterList& FElist,
                const Teuchos::RCP<TreeVector>& solution) :
      plist_(plist), solution_(solution) {}

  // Virtual destructor
  virtual ~PKDefaultBase() {}

  virtual void setup(const Teuchos::Ptr<State>& S);

  virtual void set_states(const Teuchos::RCP<const State>& S,
                          const Teuchos::RCP<State>& S_inter,
                          const Teuchos::RCP<State>& S_next);

  // -- ensure a solution is valid
  virtual bool valid_step() { return true; }

  virtual void solution_to_state(TreeVector& soln,
          const Teuchos::RCP<State>& S) = 0; // this is here to pass the buck virtually
  virtual void solution_to_state(const TreeVector& soln,
          const Teuchos::RCP<State>& S);

  virtual std::string name() { return name_; }

 protected:

  Teuchos::RCP<Teuchos::ParameterList> plist_;
  Teuchos::RCP<TreeVector> solution_;
  std::string name_;

  // states
  Teuchos::RCP<const State> S_;
  Teuchos::RCP<State> S_inter_;
  Teuchos::RCP<State> S_next_;

  // fancy OS
  Teuchos::RCP<VerboseObject> vo_;
};

} // namespace

#endif
<commit_msg>after merge<commit_after>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */

/* -------------------------------------------------------------------------
ATS

License: see $ATS_DIR/COPYRIGHT
Author: Ethan Coon

Default base with a few methods implemented in standard ways.
------------------------------------------------------------------------- */

#ifndef ATS_PK_DEFAULT_BASE_HH_
#define ATS_PK_DEFAULT_BASE_HH_

#include "Teuchos_ParameterList.hpp"

#include "VerboseObject.hh"
#include "pk.hh"

namespace Amanzi {

class PKDefaultBase : public PK_ATS {

 public:

  PKDefaultBase(const Teuchos::RCP<Teuchos::ParameterList>& plist,
                Teuchos::ParameterList& FElist,
                const Teuchos::RCP<TreeVector>& solution) :
      plist_(plist), solution_(solution) {}

  // Virtual destructor
  virtual ~PKDefaultBase() {}

  virtual void setup(const Teuchos::Ptr<State>& S);

  virtual void set_states(const Teuchos::RCP<const State>& S,
                          const Teuchos::RCP<State>& S_inter,
                          const Teuchos::RCP<State>& S_next);

  // -- ensure a solution is valid
  virtual bool valid_step() { return true; }

  virtual void solution_to_state(TreeVector& soln,
          const Teuchos::RCP<State>& S) = 0; // this is here to pass the buck virtually
  virtual void solution_to_state(const TreeVector& soln,
          const Teuchos::RCP<State>& S);

  virtual std::string name() { return name_; }

 protected:

  Teuchos::RCP<Teuchos::ParameterList> plist_;
  Teuchos::RCP<TreeVector> solution_;
  std::string name_;

  // states
  Teuchos::RCP<const State> S_;
  Teuchos::RCP<State> S_inter_;
  Teuchos::RCP<State> S_next_;

  // fancy OS
  Teuchos::RCP<VerboseObject> vo_;
};

} // namespace

#endif
<|endoftext|>