<commit_before>/*
    openDCM, dimensional constraint manager
    Copyright (C) 2012  Stefan Troeger <stefantroeger@gmx.net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef GCM_SYSTEM_H
#define GCM_SYSTEM_H

#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector/vector0.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/count.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/less_equal.hpp>
#include <boost/mpl/print.hpp>
#include <boost/mpl/and.hpp>

#include <boost/graph/adjacency_list.hpp>

#include <iostream>

#include "property.hpp"
#include "clustergraph.hpp"
#include "sheduler.hpp"
#include "logging.hpp"
#include "traits.hpp"

namespace mpl = boost::mpl;

namespace dcm {

struct No_Identifier {};
struct Unspecified_Identifier {};

namespace details {

template<typename seq, typename state>
struct vector_fold : mpl::fold< seq, state,
        mpl::push_back<mpl::_1,mpl::_2> > {};

template<typename seq, typename state>
struct edge_fold : mpl::fold< seq, state,
        mpl::if_< is_edge_property<mpl::_2>,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename seq, typename state>
struct vertex_fold : mpl::fold< seq, state,
        mpl::if_< is_vertex_property<mpl::_2>,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename seq, typename state>
struct cluster_fold : mpl::fold< seq, state,
        mpl::if_< is_cluster_property<mpl::_2>,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename seq, typename state, typename obj>
struct obj_fold : mpl::fold< seq, state,
        mpl::if_< mpl::or_<
        boost::is_same< details::property_kind<mpl::_2>, obj>, is_object_property<mpl::_2> >,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename objects, typename properties>
struct property_map {
    typedef typename mpl::fold<
    objects, mpl::map<>, mpl::insert< mpl::_1, mpl::pair<
    mpl::_2, details::obj_fold<properties, mpl::vector<>, mpl::_2 > > > >::type type;
};
template<typename T>
struct get_identifier {
    typedef typename T::Identifier type;
};

template<typename seq, typename state>
struct map_fold : mpl::fold< seq, state, mpl::insert<mpl::_1,mpl::_2> > {};

struct nothing {};

template<int v>
struct EmptyModule {

    template<typename T>
    struct type {
        struct inheriter {};
        typedef mpl::vector<>	properties;
        typedef mpl::vector<>   objects;
        typedef Unspecified_Identifier Identifier;

        static void system_init(T& sys) {};
        static void system_copy(const T& from, T& into) {};
    };
};

template <class T>
struct is_shared_ptr : boost::mpl::false_ {};
template <class T>
struct is_shared_ptr<boost::shared_ptr<T> > : boost::mpl::true_ {};

}

template< typename KernelType,
          typename  T1 = details::EmptyModule<1>,
          typename  T2 = details::EmptyModule<2>,
          typename  T3 = details::EmptyModule<3> >
class System : 	public T1::template type< System<KernelType,T1,T2,T3> >::inheriter,
    public T2::template type< System<KernelType,T1,T2,T3> >::inheriter,
    public T3::template type< System<KernelType,T1,T2,T3> >::inheriter {

    typedef System<KernelType,T1,T2,T3> BaseType;
public:
    typedef typename T1::template type< BaseType > Type1;
    typedef typename T2::template type< BaseType > Type2;
    typedef typename T3::template type< BaseType > Type3;
    typedef mpl::vector3<Type1, Type2, Type3> TypeVector;

    //Check if all Identifiers are the same and find out which type it is
    typedef typename mpl::fold<TypeVector, mpl::vector<>,
            mpl::if_<boost::is_same<details::get_identifier<mpl::_2>, Unspecified_Identifier>,
            mpl::_1, mpl::push_back<mpl::_1, details::get_identifier<mpl::_2> > > >::type Identifiers;
    BOOST_MPL_ASSERT((mpl::or_<
                      mpl::less_equal<typename mpl::size<Identifiers>::type, mpl::int_<1> >,
                      mpl::equal< typename mpl::count<Identifiers,
                      typename mpl::at_c<Identifiers,0> >::type, typename mpl::size<Identifiers>::type > >));

    typedef typename mpl::if_< mpl::empty<Identifiers>,
            No_Identifier, typename mpl::at_c<Identifiers, 0>::type >::type Identifier;

public:
    //get all module objects and properties
    typedef typename details::vector_fold<typename Type3::objects,
            typename details::vector_fold<typename Type2::objects,
            typename details::vector_fold<typename Type1::objects,
            mpl::vector<> >::type >::type>::type objects;

    typedef typename details::vector_fold<typename Type3::properties,
            typename details::vector_fold<typename Type2::properties,
            typename details::vector_fold<typename Type1::properties,
            mpl::vector<id_prop<Identifier> > >::type >::type>::type properties;

    //make the subcomponent lists of objects and properties
    typedef typename details::edge_fold< properties, mpl::vector<> >::type 	edge_properties;
    typedef typename details::vertex_fold< properties, mpl::vector<> >::type 	vertex_properties;
    typedef typename details::cluster_fold< properties,
            mpl::vector<changed_prop, type_prop>  >::type 			cluster_properties;

    typedef typename details::property_map<objects, properties>::type 		object_properties;

protected:
    //object storage
    typedef typename mpl::transform<objects, boost::shared_ptr<mpl::_1> >::type sp_objects;
    typedef typename mpl::fold< sp_objects, mpl::vector<>,
            mpl::push_back<mpl::_1, std::vector<mpl::_2> > >::type 	object_vectors;
    typedef typename fusion::result_of::as_vector<object_vectors>::type Storage;

    template<typename FT1, typename FT2, typename FT3>
    friend struct Object;

    struct clearer {
        template<typename T>
        void operator()(T& vector) const {
            vector.clear();
        };
    };

#ifdef USE_LOGGING
    boost::shared_ptr< sink_t > sink;
#endif

public:
    typedef ClusterGraph<edge_properties, vertex_properties, cluster_properties, objects> Cluster;
    typedef Sheduler< BaseType > Shedule;
    typedef KernelType Kernel;

public:
    System() : m_cluster(new Cluster)
#ifdef USE_LOGGING
    , sink(init_log())
#endif
    {
        Type1::system_init(*this);
        Type2::system_init(*this);
        Type3::system_init(*this);

    };

    ~System() {
#ifdef USE_LOGGING
        stop_log(sink);
#endif
    };

    void clear() {

        m_cluster->clearClusters();
        m_cluster->clear();
        fusion::for_each(m_storage, clearer());
    };

    template<typename Object>
    typename std::vector< boost::shared_ptr<Object> >::iterator begin() {

        typedef typename mpl::find<objects, Object>::type iterator;
        typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
        BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
        return fusion::at<distance>(m_storage).begin();
    };

    template<typename Object>
    typename std::vector< boost::shared_ptr<Object> >::iterator end() {

        typedef typename mpl::find<objects, Object>::type iterator;
        typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
        BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
        return fusion::at<distance>(m_storage).end();
    };

    template<typename Object>
    std::vector< boost::shared_ptr<Object> >& objectVector() {

        typedef typename mpl::find<objects, Object>::type iterator;
        typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
        BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
        return fusion::at<distance>(m_storage);
    };

    template<typename Object>
    void push_back(boost::shared_ptr<Object> ptr) {
        objectVector<Object>().push_back(ptr);
    };

    template<typename Object>
    void erase(boost::shared_ptr<Object> ptr) {

        std::vector< boost::shared_ptr<Object> >& vec = objectVector<Object>();
        vec.erase(std::remove(vec.begin(), vec.end(), ptr), vec.end());
    };

    void solve() {
        clock_t start = clock();
        m_sheduler.execute(*this);
        clock_t end = clock();
        double ms = (double(end-start)* 1000.) / double(CLOCKS_PER_SEC);
        //Base::Console().Message("overall solving time in ms: %f\n", ms);

    };

private:
    struct cloner {

        System& newSys;
        cloner(System& ns) : newSys(ns) {};

	template<typename T>
	struct test : mpl::and_<details::is_shared_ptr<T>,
		    mpl::not_<boost::is_same<T, boost::shared_ptr<typename System::Cluster> > > > {};

        template<typename T>
        typename boost::enable_if< test<T>, void>::type operator()(T& p) const {
            p = p->clone(newSys);
            newSys.push_back(p);
        };
        template<typename T>
        typename boost::enable_if< mpl::not_<test<T> >, void>::type operator()(const T& p) const {};
    };

public:
    void copyInto(System& into) const {

        //copy the clustergraph and clone all objects while at it. They are also pushed to the storage
        cloner cl(into);
        m_cluster->copyInto(into.m_cluster, cl);

        //notify all modules that they are copied
        Type1::system_copy(*this, into);
        Type2::system_copy(*this, into);
        Type3::system_copy(*this, into);
    };

    System* clone() const {

        System* ns = new System();
        this->copyInto(*ns);
        return ns;
    };

    boost::shared_ptr<Cluster> m_cluster;
    Shedule m_sheduler;
    Kernel  m_kernel;
    Storage m_storage;
};

}
#endif //GCM_SYSTEM_H

<commit_msg>aloow shared object storage<commit_after>/*
    openDCM, dimensional constraint manager
    Copyright (C) 2012  Stefan Troeger <stefantroeger@gmx.net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef GCM_SYSTEM_H
#define GCM_SYSTEM_H

#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector/vector0.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/count.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/less_equal.hpp>
#include <boost/mpl/print.hpp>
#include <boost/mpl/and.hpp>

#include <boost/graph/adjacency_list.hpp>

#include <iostream>

#include "property.hpp"
#include "clustergraph.hpp"
#include "sheduler.hpp"
#include "logging.hpp"
#include "traits.hpp"

namespace mpl = boost::mpl;

namespace dcm {

struct No_Identifier {};
struct Unspecified_Identifier {};

namespace details {

template<typename seq, typename state>
struct vector_fold : mpl::fold< seq, state,
        mpl::push_back<mpl::_1,mpl::_2> > {};

template<typename seq, typename state>
struct edge_fold : mpl::fold< seq, state,
        mpl::if_< is_edge_property<mpl::_2>,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename seq, typename state>
struct vertex_fold : mpl::fold< seq, state,
        mpl::if_< is_vertex_property<mpl::_2>,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename seq, typename state>
struct cluster_fold : mpl::fold< seq, state,
        mpl::if_< is_cluster_property<mpl::_2>,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename seq, typename state, typename obj>
struct obj_fold : mpl::fold< seq, state,
        mpl::if_< mpl::or_<
        boost::is_same< details::property_kind<mpl::_2>, obj>, is_object_property<mpl::_2> >,
        mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};

template<typename objects, typename properties>
struct property_map {
    typedef typename mpl::fold<
    objects, mpl::map<>, mpl::insert< mpl::_1, mpl::pair<
    mpl::_2, details::obj_fold<properties, mpl::vector<>, mpl::_2 > > > >::type type;
};
template<typename T>
struct get_identifier {
    typedef typename T::Identifier type;
};

template<typename seq, typename state>
struct map_fold : mpl::fold< seq, state, mpl::insert<mpl::_1,mpl::_2> > {};

struct nothing {};

template<int v>
struct EmptyModule {

    template<typename T>
    struct type {
        struct inheriter {};
        typedef mpl::vector<>	properties;
        typedef mpl::vector<>   objects;
        typedef Unspecified_Identifier Identifier;

        static void system_init(T& sys) {};
        static void system_copy(const T& from, T& into) {};
    };
};

template <class T>
struct is_shared_ptr : boost::mpl::false_ {};
template <class T>
struct is_shared_ptr<boost::shared_ptr<T> > : boost::mpl::true_ {};

}

template< typename KernelType,
          typename  T1 = details::EmptyModule<1>,
          typename  T2 = details::EmptyModule<2>,
          typename  T3 = details::EmptyModule<3> >
class System : 	public T1::template type< System<KernelType,T1,T2,T3> >::inheriter,
    public T2::template type< System<KernelType,T1,T2,T3> >::inheriter,
    public T3::template type< System<KernelType,T1,T2,T3> >::inheriter {

    typedef System<KernelType,T1,T2,T3> BaseType;
public:
    typedef typename T1::template type< BaseType > Type1;
    typedef typename T2::template type< BaseType > Type2;
    typedef typename T3::template type< BaseType > Type3;
    typedef mpl::vector3<Type1, Type2, Type3> TypeVector;

    //Check if all Identifiers are the same and find out which type it is
    typedef typename mpl::fold<TypeVector, mpl::vector<>,
            mpl::if_<boost::is_same<details::get_identifier<mpl::_2>, Unspecified_Identifier>,
            mpl::_1, mpl::push_back<mpl::_1, details::get_identifier<mpl::_2> > > >::type Identifiers;
    BOOST_MPL_ASSERT((mpl::or_<
                      mpl::less_equal<typename mpl::size<Identifiers>::type, mpl::int_<1> >,
                      mpl::equal< typename mpl::count<Identifiers,
                      typename mpl::at_c<Identifiers,0> >::type, typename mpl::size<Identifiers>::type > >));

    typedef typename mpl::if_< mpl::empty<Identifiers>,
            No_Identifier, typename mpl::at_c<Identifiers, 0>::type >::type Identifier;

public:
    //get all module objects and properties
    typedef typename details::vector_fold<typename Type3::objects,
            typename details::vector_fold<typename Type2::objects,
            typename details::vector_fold<typename Type1::objects,
            mpl::vector<> >::type >::type>::type objects;

    typedef typename details::vector_fold<typename Type3::properties,
            typename details::vector_fold<typename Type2::properties,
            typename details::vector_fold<typename Type1::properties,
            mpl::vector<id_prop<Identifier> > >::type >::type>::type properties;

    //make the subcomponent lists of objects and properties
    typedef typename details::edge_fold< properties, mpl::vector<> >::type 	edge_properties;
    typedef typename details::vertex_fold< properties, mpl::vector<> >::type 	vertex_properties;
    typedef typename details::cluster_fold< properties,
            mpl::vector<changed_prop, type_prop>  >::type 			cluster_properties;

    typedef typename details::property_map<objects, properties>::type 		object_properties;

protected:
    //object storage
    typedef typename mpl::transform<objects, boost::shared_ptr<mpl::_1> >::type sp_objects;
    typedef typename mpl::fold< sp_objects, mpl::vector<>,
            mpl::push_back<mpl::_1, std::vector<mpl::_2> > >::type 	object_vectors;
    typedef typename fusion::result_of::as_vector<object_vectors>::type Storage;

    template<typename FT1, typename FT2, typename FT3>
    friend struct Object;

    struct clearer {
        template<typename T>
        void operator()(T& vector) const {
            vector.clear();
        };
    };

#ifdef USE_LOGGING
    boost::shared_ptr< sink_t > sink;
#endif

public:
    typedef ClusterGraph<edge_properties, vertex_properties, cluster_properties, objects> Cluster;
    typedef Sheduler< BaseType > Shedule;
    typedef KernelType Kernel;

public:
    System() : m_cluster(new Cluster), m_storage(new Storage)
#ifdef USE_LOGGING
    , sink(init_log())
#endif
    {
        Type1::system_init(*this);
        Type2::system_init(*this);
        Type3::system_init(*this);

    };

    ~System() {
#ifdef USE_LOGGING
        stop_log(sink);
#endif
    };

    void clear() {

        m_cluster->clearClusters();
        m_cluster->clear();
        fusion::for_each(*m_storage, clearer());
    };

    template<typename Object>
    typename std::vector< boost::shared_ptr<Object> >::iterator begin() {

        typedef typename mpl::find<objects, Object>::type iterator;
        typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
        BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
        return fusion::at<distance>(*m_storage).begin();
    };

    template<typename Object>
    typename std::vector< boost::shared_ptr<Object> >::iterator end() {

        typedef typename mpl::find<objects, Object>::type iterator;
        typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
        BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
        return fusion::at<distance>(*m_storage).end();
    };

    template<typename Object>
    std::vector< boost::shared_ptr<Object> >& objectVector() {

        typedef typename mpl::find<objects, Object>::type iterator;
        typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
        BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
        return fusion::at<distance>(*m_storage);
    };

    template<typename Object>
    void push_back(boost::shared_ptr<Object> ptr) {
        objectVector<Object>().push_back(ptr);
    };

    template<typename Object>
    void erase(boost::shared_ptr<Object> ptr) {

        std::vector< boost::shared_ptr<Object> >& vec = objectVector<Object>();
        vec.erase(std::remove(vec.begin(), vec.end(), ptr), vec.end());
    };

    void solve() {
        clock_t start = clock();
        m_sheduler.execute(*this);
        clock_t end = clock();
        double ms = (double(end-start)* 1000.) / double(CLOCKS_PER_SEC);
        //Base::Console().Message("overall solving time in ms: %f\n", ms);

    };

private:
    struct cloner {

        System& newSys;
        cloner(System& ns) : newSys(ns) {};

	template<typename T>
	struct test : mpl::and_<details::is_shared_ptr<T>,
		    mpl::not_<boost::is_same<T, boost::shared_ptr<typename System::Cluster> > > > {};

        template<typename T>
        typename boost::enable_if< test<T>, void>::type operator()(T& p) const {
            p = p->clone(newSys);
            newSys.push_back(p);
        };
        template<typename T>
        typename boost::enable_if< mpl::not_<test<T> >, void>::type operator()(const T& p) const {};
    };

public:
    void copyInto(System& into) const {

        //copy the clustergraph and clone all objects while at it. They are also pushed to the storage
        cloner cl(into);
        m_cluster->copyInto(into.m_cluster, cl);

        //notify all modules that they are copied
        Type1::system_copy(*this, into);
        Type2::system_copy(*this, into);
        Type3::system_copy(*this, into);
    };

    System* clone() const {

        System* ns = new System();
        this->copyInto(*ns);
        return ns;
    };

    boost::shared_ptr<Cluster> m_cluster;
    boost::shared_ptr<Storage> m_storage;
    Shedule m_sheduler;
    Kernel  m_kernel;
};

}
#endif //GCM_SYSTEM_H

<|endoftext|>


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

#include "Track.h"

#include "Capture.h"
#include "CoreMath.h"
#include "GlCanvas.h"
#include "TimeGraphLayout.h"
#include "absl/strings/str_format.h"

//-----------------------------------------------------------------------------
Track::Track(TimeGraph* time_graph)
    : time_graph_(time_graph),
      collapse_toggle_(
          TriangleToggle::State::kExpanded,
          [this](TriangleToggle::State state) { OnCollapseToggle(state); },
          time_graph) {
  m_MousePos[0] = m_MousePos[1] = Vec2(0, 0);
  m_Pos = Vec2(0, 0);
  m_Size = Vec2(0, 0);
  m_PickingOffset = Vec2(0, 0);
  m_Picked = false;
  m_Moving = false;
  m_Canvas = nullptr;
}

//-----------------------------------------------------------------------------
std::vector<Vec2> GetRoundedCornerMask(float radius, uint32_t num_sides) {
  std::vector<Vec2> points;
  points.emplace_back(0.f, 0.f);
  points.emplace_back(0.f, radius);

  float increment_radians = 0.5f * kPiFloat / static_cast<float>(num_sides);
  for (uint32_t i = 1; i < num_sides; ++i) {
    float angle = kPiFloat + static_cast<float>(i) * increment_radians;
    points.emplace_back(radius * cosf(angle) + radius,
                        radius * sinf(angle) + radius);
  }

  points.emplace_back(radius, 0.f);
  return points;
}

//-----------------------------------------------------------------------------
std::vector<Vec2> RotatePoints(const std::vector<Vec2>& points,
                               float rotation) {
  float cos_r = cosf(kPiFloat * rotation / 180.f);
  float sin_r = sinf(kPiFloat * rotation / 180.f);
  std::vector<Vec2> result;
  for (const Vec2 point : points) {
    float x_rotated = cos_r * point[0] - sin_r * point[1];
    float y_rotated = sin_r * point[0] + cos_r * point[1];
    result.push_back(Vec2(x_rotated, y_rotated));
  }
  return result;
}

//-----------------------------------------------------------------------------
void DrawTriangleFan(Batcher* batcher, const std::vector<Vec2>& points,
                     const Vec2& pos, const Color& color, float rotation,
                     float z) {
  if (points.size() < 3) {
    return;
  }

  std::vector<Vec2> rotated_points = RotatePoints(points, rotation);
  Vec3 position(pos[0], pos[1], z);
  Vec3 pivot = position + Vec3(rotated_points[0][0], rotated_points[0][1], z);

  Vec3 vertices[2];
  vertices[0] = position + Vec3(rotated_points[1][0], rotated_points[1][1], z);

  for (size_t i = 1; i < rotated_points.size() - 1; ++i) {
    vertices[i % 2] =
        position + Vec3(rotated_points[i + 1][0], rotated_points[i + 1][1], z);
    Triangle triangle(pivot, vertices[i % 2], vertices[(i + 1) % 2]);
    batcher->AddTriangle(triangle, color, PickingID::PICKABLE);
  }
}

//-----------------------------------------------------------------------------
void Track::Draw(GlCanvas* canvas, bool picking) {
  Batcher* batcher = canvas->GetBatcher();

  const TimeGraphLayout& layout = time_graph_->GetLayout();
  Color picking_color = canvas->GetPickingManager().GetPickableColor(
      this, PickingID::BatcherId::UI);
  const Color kTabColor(50, 50, 50, 255);
  Color color = picking ? picking_color : kTabColor;
  glColor4ubv(&color[0]);

  float x0 = m_Pos[0];
  float x1 = x0 + m_Size[0];
  float y0 = m_Pos[1];
  float y1 = y0 - m_Size[1];
  float track_z = layout.GetTrackZ();
  float text_z = layout.GetTextZ();
  float top_margin = layout.GetTrackTopMargin();

  // Draw track background.
  if (!picking) {
    if (layout.GetDrawTrackBackground()) {
      Box box(Vec2(x0, y0 + top_margin),
              Vec2(m_Size[0], -m_Size[1] - top_margin), track_z);
      batcher->AddBox(box, color, PickingID::PICKABLE);
    }
  }

  // Draw tab.
  float label_height = layout.GetTrackTabHeight();
  float half_label_height = 0.5f * label_height;
  float label_width = layout.GetTrackTabWidth();
  float tab_x0 = x0 + layout.GetTrackTabOffset();

  Box box(Vec2(tab_x0, y0), Vec2(label_width, label_height), track_z);
  batcher->AddBox(box, color, PickingID::PICKABLE,
    std::make_shared<PickingUserData>(nullptr, [&](PickingID id) {
      return GetGenericTooltip(id);
    })
  );

  // Draw rounded corners.
  if (!picking) {
    float vertical_margin = time_graph_->GetVerticalMargin();
    const Color kBackgroundColor(70, 70, 70, 255);

    float radius = std::min(layout.GetRoundingRadius(), half_label_height);
    uint32_t sides = static_cast<uint32_t>(layout.GetRoundingNumSides() + 0.5f);
    auto rounded_corner = GetRoundedCornerMask(radius, sides);
    Vec2 bottom_left(x0, y1);
    Vec2 bottom_right(tab_x0 + label_width, y0 + top_margin);
    Vec2 top_right(tab_x0 + label_width, y0 + label_height);
    Vec2 top_left(tab_x0, y0 + label_height);
    Vec2 end_bottom(x1 - vertical_margin, y1);
    Vec2 end_top(x1 - vertical_margin, y0 + top_margin);
    float z = GlCanvas::Z_VALUE_BOX_ACTIVE + 0.001f;
    DrawTriangleFan(batcher, rounded_corner, bottom_left, kBackgroundColor, 0,
                    z);
    DrawTriangleFan(batcher, rounded_corner, bottom_right, color, 0, z);
    DrawTriangleFan(batcher, rounded_corner, top_right, kBackgroundColor, 180.f,
                    z);
    DrawTriangleFan(batcher, rounded_corner, top_left, kBackgroundColor, -90.f,
                    z);
    DrawTriangleFan(batcher, rounded_corner, end_bottom, kBackgroundColor, 90.f,
                    z);
    DrawTriangleFan(batcher, rounded_corner, end_top, kBackgroundColor, 180.f,
                    z);

    // Collapse toggle state management.
    if (!this->IsCollapsable()) {
      collapse_toggle_.SetState(TriangleToggle::State::kInactive);
    } else if (collapse_toggle_.IsInactive()) {
      collapse_toggle_.ResetToInitialState();
    }

    // Draw collapsing triangle.
    float button_offset = layout.GetCollapseButtonOffset();
    Vec2 toggle_pos =
        Vec2(tab_x0 + button_offset, m_Pos[1] + half_label_height);
    collapse_toggle_.SetPos(toggle_pos);
    collapse_toggle_.Draw(canvas, picking);

    // Draw label.
    float label_offset_x = layout.GetTrackLabelOffsetX();
    float label_offset_y = layout.GetTrackLabelOffsetY();
    const Color kTextWhite(255, 255, 255, 255);
    canvas->AddText(label_.c_str(), tab_x0 + label_offset_x,
                    y1 + label_offset_y + m_Size[1], text_z, kTextWhite,
                    label_width - label_offset_x);
  }

  m_Canvas = canvas;
}

//-----------------------------------------------------------------------------
void Track::UpdatePrimitives(uint64_t /*t_min*/, uint64_t /*t_max*/) {}

//-----------------------------------------------------------------------------
void Track::SetPos(float a_X, float a_Y) {
  if (!m_Moving) {
    m_Pos = Vec2(a_X, a_Y);
  }
}

//-----------------------------------------------------------------------------
void Track::SetY(float y) {
  if (!m_Moving) {
    m_Pos[1] = y;
  }
}

//-----------------------------------------------------------------------------
void Track::SetSize(float a_SizeX, float a_SizeY) {
  m_Size = Vec2(a_SizeX, a_SizeY);
}

//-----------------------------------------------------------------------------
void Track::OnCollapseToggle(TriangleToggle::State /*state*/) {
  time_graph_->NeedsUpdate();
  time_graph_->NeedsRedraw();
}

std::string Track::GetGenericTooltip(PickingID _) const {
  return std::string("Displays all hooked functions executed from thread ") + GetLabel();
}

//-----------------------------------------------------------------------------
void Track::OnPick(int a_X, int a_Y) {
  if (!m_PickingEnabled) return;

  Vec2& mousePos = m_MousePos[0];
  m_Canvas->ScreenToWorld(a_X, a_Y, mousePos[0], mousePos[1]);
  m_PickingOffset = mousePos - m_Pos;
  m_MousePos[1] = m_MousePos[0];
  m_Picked = true;
}

//-----------------------------------------------------------------------------
void Track::OnRelease() {
  if (!m_PickingEnabled) return;

  m_Picked = false;
  m_Moving = false;
  time_graph_->NeedsUpdate();
}

//-----------------------------------------------------------------------------
void Track::OnDrag(int a_X, int a_Y) {
  if (!m_PickingEnabled) return;

  m_Moving = true;
  float x = 0.f;
  m_Canvas->ScreenToWorld(a_X, a_Y, x, m_Pos[1]);
  m_MousePos[1] = m_Pos;
  m_Pos[1] -= m_PickingOffset[1];
  time_graph_->NeedsUpdate();
}
<commit_msg>Collapse triangle is rendered into picking again, was falsely removed<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "Track.h"

#include "Capture.h"
#include "CoreMath.h"
#include "GlCanvas.h"
#include "TimeGraphLayout.h"
#include "absl/strings/str_format.h"

//-----------------------------------------------------------------------------
Track::Track(TimeGraph* time_graph)
    : time_graph_(time_graph),
      collapse_toggle_(
          TriangleToggle::State::kExpanded,
          [this](TriangleToggle::State state) { OnCollapseToggle(state); },
          time_graph) {
  m_MousePos[0] = m_MousePos[1] = Vec2(0, 0);
  m_Pos = Vec2(0, 0);
  m_Size = Vec2(0, 0);
  m_PickingOffset = Vec2(0, 0);
  m_Picked = false;
  m_Moving = false;
  m_Canvas = nullptr;
}

//-----------------------------------------------------------------------------
std::vector<Vec2> GetRoundedCornerMask(float radius, uint32_t num_sides) {
  std::vector<Vec2> points;
  points.emplace_back(0.f, 0.f);
  points.emplace_back(0.f, radius);

  float increment_radians = 0.5f * kPiFloat / static_cast<float>(num_sides);
  for (uint32_t i = 1; i < num_sides; ++i) {
    float angle = kPiFloat + static_cast<float>(i) * increment_radians;
    points.emplace_back(radius * cosf(angle) + radius,
                        radius * sinf(angle) + radius);
  }

  points.emplace_back(radius, 0.f);
  return points;
}

//-----------------------------------------------------------------------------
std::vector<Vec2> RotatePoints(const std::vector<Vec2>& points,
                               float rotation) {
  float cos_r = cosf(kPiFloat * rotation / 180.f);
  float sin_r = sinf(kPiFloat * rotation / 180.f);
  std::vector<Vec2> result;
  for (const Vec2 point : points) {
    float x_rotated = cos_r * point[0] - sin_r * point[1];
    float y_rotated = sin_r * point[0] + cos_r * point[1];
    result.push_back(Vec2(x_rotated, y_rotated));
  }
  return result;
}

//-----------------------------------------------------------------------------
void DrawTriangleFan(Batcher* batcher, const std::vector<Vec2>& points,
                     const Vec2& pos, const Color& color, float rotation,
                     float z) {
  if (points.size() < 3) {
    return;
  }

  std::vector<Vec2> rotated_points = RotatePoints(points, rotation);
  Vec3 position(pos[0], pos[1], z);
  Vec3 pivot = position + Vec3(rotated_points[0][0], rotated_points[0][1], z);

  Vec3 vertices[2];
  vertices[0] = position + Vec3(rotated_points[1][0], rotated_points[1][1], z);

  for (size_t i = 1; i < rotated_points.size() - 1; ++i) {
    vertices[i % 2] =
        position + Vec3(rotated_points[i + 1][0], rotated_points[i + 1][1], z);
    Triangle triangle(pivot, vertices[i % 2], vertices[(i + 1) % 2]);
    batcher->AddTriangle(triangle, color, PickingID::PICKABLE);
  }
}

//-----------------------------------------------------------------------------
void Track::Draw(GlCanvas* canvas, bool picking) {
  Batcher* batcher = canvas->GetBatcher();

  const TimeGraphLayout& layout = time_graph_->GetLayout();
  Color picking_color = canvas->GetPickingManager().GetPickableColor(
      this, PickingID::BatcherId::UI);
  const Color kTabColor(50, 50, 50, 255);
  Color color = picking ? picking_color : kTabColor;
  glColor4ubv(&color[0]);

  float x0 = m_Pos[0];
  float x1 = x0 + m_Size[0];
  float y0 = m_Pos[1];
  float y1 = y0 - m_Size[1];
  float track_z = layout.GetTrackZ();
  float text_z = layout.GetTextZ();
  float top_margin = layout.GetTrackTopMargin();

  // Draw track background.
  if (!picking) {
    if (layout.GetDrawTrackBackground()) {
      Box box(Vec2(x0, y0 + top_margin),
              Vec2(m_Size[0], -m_Size[1] - top_margin), track_z);
      batcher->AddBox(box, color, PickingID::PICKABLE);
    }
  }

  // Draw tab.
  float label_height = layout.GetTrackTabHeight();
  float half_label_height = 0.5f * label_height;
  float label_width = layout.GetTrackTabWidth();
  float tab_x0 = x0 + layout.GetTrackTabOffset();

  Box box(Vec2(tab_x0, y0), Vec2(label_width, label_height), track_z);
  batcher->AddBox(box, color, PickingID::PICKABLE,
                  std::make_shared<PickingUserData>(nullptr, [&](PickingID id) {
                    return GetGenericTooltip(id);
                  }));

  // Draw rounded corners.
  if (!picking) {
    float vertical_margin = time_graph_->GetVerticalMargin();
    const Color kBackgroundColor(70, 70, 70, 255);

    float radius = std::min(layout.GetRoundingRadius(), half_label_height);
    uint32_t sides = static_cast<uint32_t>(layout.GetRoundingNumSides() + 0.5f);
    auto rounded_corner = GetRoundedCornerMask(radius, sides);
    Vec2 bottom_left(x0, y1);
    Vec2 bottom_right(tab_x0 + label_width, y0 + top_margin);
    Vec2 top_right(tab_x0 + label_width, y0 + label_height);
    Vec2 top_left(tab_x0, y0 + label_height);
    Vec2 end_bottom(x1 - vertical_margin, y1);
    Vec2 end_top(x1 - vertical_margin, y0 + top_margin);
    float z = GlCanvas::Z_VALUE_BOX_ACTIVE + 0.001f;
    DrawTriangleFan(batcher, rounded_corner, bottom_left, kBackgroundColor, 0,
                    z);
    DrawTriangleFan(batcher, rounded_corner, bottom_right, color, 0, z);
    DrawTriangleFan(batcher, rounded_corner, top_right, kBackgroundColor, 180.f,
                    z);
    DrawTriangleFan(batcher, rounded_corner, top_left, kBackgroundColor, -90.f,
                    z);
    DrawTriangleFan(batcher, rounded_corner, end_bottom, kBackgroundColor, 90.f,
                    z);
    DrawTriangleFan(batcher, rounded_corner, end_top, kBackgroundColor, 180.f,
                    z);
  }

  // Collapse toggle state management.
  if (!this->IsCollapsable()) {
    collapse_toggle_.SetState(TriangleToggle::State::kInactive);
  } else if (collapse_toggle_.IsInactive()) {
    collapse_toggle_.ResetToInitialState();
  }

  // Draw collapsing triangle.
  float button_offset = layout.GetCollapseButtonOffset();
  Vec2 toggle_pos = Vec2(tab_x0 + button_offset, m_Pos[1] + half_label_height);
  collapse_toggle_.SetPos(toggle_pos);
  collapse_toggle_.Draw(canvas, picking);

  if (!picking) {
    // Draw label.
    float label_offset_x = layout.GetTrackLabelOffsetX();
    float label_offset_y = layout.GetTrackLabelOffsetY();
    const Color kTextWhite(255, 255, 255, 255);
    canvas->AddText(label_.c_str(), tab_x0 + label_offset_x,
                    y1 + label_offset_y + m_Size[1], text_z, kTextWhite,
                    label_width - label_offset_x);
  }

  m_Canvas = canvas;
}

//-----------------------------------------------------------------------------
void Track::UpdatePrimitives(uint64_t /*t_min*/, uint64_t /*t_max*/) {}

//-----------------------------------------------------------------------------
void Track::SetPos(float a_X, float a_Y) {
  if (!m_Moving) {
    m_Pos = Vec2(a_X, a_Y);
  }
}

//-----------------------------------------------------------------------------
void Track::SetY(float y) {
  if (!m_Moving) {
    m_Pos[1] = y;
  }
}

//-----------------------------------------------------------------------------
void Track::SetSize(float a_SizeX, float a_SizeY) {
  m_Size = Vec2(a_SizeX, a_SizeY);
}

//-----------------------------------------------------------------------------
void Track::OnCollapseToggle(TriangleToggle::State /*state*/) {
  time_graph_->NeedsUpdate();
  time_graph_->NeedsRedraw();
}

std::string Track::GetGenericTooltip(PickingID _) const {
  return std::string("Displays all hooked functions executed from thread ") + GetLabel();
}

//-----------------------------------------------------------------------------
void Track::OnPick(int a_X, int a_Y) {
  if (!m_PickingEnabled) return;

  Vec2& mousePos = m_MousePos[0];
  m_Canvas->ScreenToWorld(a_X, a_Y, mousePos[0], mousePos[1]);
  m_PickingOffset = mousePos - m_Pos;
  m_MousePos[1] = m_MousePos[0];
  m_Picked = true;
}

//-----------------------------------------------------------------------------
void Track::OnRelease() {
  if (!m_PickingEnabled) return;

  m_Picked = false;
  m_Moving = false;
  time_graph_->NeedsUpdate();
}

//-----------------------------------------------------------------------------
void Track::OnDrag(int a_X, int a_Y) {
  if (!m_PickingEnabled) return;

  m_Moving = true;
  float x = 0.f;
  m_Canvas->ScreenToWorld(a_X, a_Y, x, m_Pos[1]);
  m_MousePos[1] = m_Pos;
  m_Pos[1] -= m_PickingOffset[1];
  time_graph_->NeedsUpdate();
}
<|endoftext|>


<commit_before>// Copyright (c) The University of Cincinnati.
// All rights reserved.

// UC MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
// THE SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  UC SHALL NOT BE LIABLE
// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
// RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
// DERIVATIVES.

// By using or copying this Software, Licensee agrees to abide by the
// intellectual property laws, and all other applicable laws of the
// U.S., and the terms of this license.

//Authors: Xinyu Guo                   guox2@mail.uc.edu
//         Philip A. Wilsey            phil.wilsey@uc.edu

#include "Iscas85Application.h"
#include "LogicEvent.h"
#include "FileReaderWriter.h"
#include "NInputAndGate.h"
#include "NInputXorGate.h"
#include "NInputOrGate.h"
#include "NInputNandGate.h"
#include "NInputNorGate.h"
#include "NotGate.h"
#include <warped/PartitionInfo.h>
#include <warped/RoundRobinPartitioner.h>
#include <warped/DeserializerManager.h>
#include <utils/ArgumentParser.h>
#include "vector"
#include "iostream"
#include "fstream"
#include "stdlib.h"

using namespace std;

Iscas85Application::Iscas85Application()
  :inputFileName( "" ),
   testCaseFileName(""),
   numObjects( 0 ){}

int
Iscas85Application::initialize( vector<string> &arguments ){
  string path="circuitsimulationmodels/iscas85/iscas85Sim/";

  getArgumentParser().checkArgs( arguments );

  if( inputFileName.empty() ){
    std::cerr << "A smmpSim configuration file must be specified using -simulate"<<std::endl;
    abort();
  }
  return 0;
}

int
Iscas85Application::finalize(){
  return 0;
}

int
Iscas85Application::getNumberOfSimulationObjects(int mgrId) const {
  return numObjects;
}

const PartitionInfo*
Iscas85Application::getPartitionInfo(unsigned int numberOfProcessorsAvailable){
  const PartitionInfo *retval = 0;
  Partitioner *myPartitioner = new RoundRobinPartitioner();

  int numFileObjects;
  string fileName;
  int numOfGates;
  string type;
  int desPort;
  string desGateName;
  int maxLines;

  ifstream configfile;

  configfile.open(inputFileName.c_str());

  if(configfile.fail()){
    cerr<<"Could not open file!:'"<<inputFileName<<"'"<<endl;
    cerr<<"Terminating simulation."<<endl;
    abort();
  }

  vector<SimulationObject *> *objects = new vector<SimulationObject *>;

  string filePath;//
  int totalGates; // total gates number in the circuit
  configfile>>filePath;//
  configfile>>numFileObjects;
  configfile>>totalGates;

  for(int i=0; i < numFileObjects; i++){
    configfile>>fileName>>numOfGates>>type;
    vector<int> *desPortId = new vector<int>;
    vector<string> *desGatesNames = new vector<string>;

    if(0==numOfGates){
      configfile>>desPort;
      //cout<<"numOfGates is:"<<numOfGates<<endl;
      //cout<<"desPort Value is:"<<desPort<<endl;
      desPortId->push_back(desPort);
      configfile>>desGateName;
      //cout<<"numOfGates is:"<<numOfGates<<endl;
      //cout<<"desPort Value is:"<<desPort<<endl;
      desGatesNames->push_back(desGateName);
    }
  else{
    for(int j= 0;j<numOfGates;j++){
    configfile>>desPort;
    //cout<<"numOfGates is:"<<numOfGates<<endl;
    //cout<<"desPort Value is:"<<desPort<<endl;
    desPortId->push_back(desPort);
   }
    for(int j= 0;j<numOfGates;j++){
      configfile>>desGateName;
      desGatesNames->push_back(desGateName);
    }
  }
    configfile>>maxLines;
    fileName = filePath+fileName;//the absolute path of the file
    SimulationObject *newObject = new FileReaderWriter(fileName,numOfGates,type,desPortId,desGatesNames,maxLines);
    objects->push_back(newObject);
    //cout<<"construct FileReaderWriter object!"<<endl;
  }

   // int totalGates; // total gates number in the circuit

    string myObjName;    // object name
    int numberOfInputs;  // the number of inputs of the object
    int numberOfOutputs; // the number of objects connected to the object
    string destObjName;  // the name of the gate which receives the object output
    int desInputPort;    // pin id of the gate which receives the object output
    int delay;           // the delay between event receiving and event sending

  // configfile >> totalGates;

    for(int i = 0; i < totalGates; i++){
      configfile >> myObjName >> numberOfInputs >> numberOfOutputs;// >> destObjName >> desInputPort;
      vector<string> *outputObjectNames = new vector<string>;
      vector<int> *destinationPorts = new vector<int>;

      for(int i = 0; i < numberOfOutputs; i++){
        configfile >> destObjName;
        //cout<<"object name is "<< destObjName<<endl;
        outputObjectNames -> push_back(destObjName);
      }

      for(int i =0; i < numberOfOutputs; i++){
        configfile >> desInputPort;
        destinationPorts->push_back(desInputPort);
      }

      configfile >> delay;
      string gate= myObjName.substr(0,1);
      string gate1 = myObjName.substr(0,3);

      if("A"==gate){
        SimulationObject *newObject = new NInputAndGate(myObjName,
                                                        numberOfInputs,
                                                        numberOfOutputs,
                                                        outputObjectNames,
                                                        destinationPorts,
                                                        delay);

        objects->push_back(newObject);
        // cout << "building object with R !"<<endl;
        // cout << "the address of the object is " << newObject<<endl;
      }
      else if ("X"==gate){
        SimulationObject *newObject = new NInputXorGate(myObjName,
                                                        numberOfInputs,
                                                        numberOfOutputs,
                                                        outputObjectNames,
                                                        destinationPorts,
                                                        delay);

        objects->push_back(newObject);
        // cout << "building object with R !"<<endl;
        // cout << "the address of the object is " << newObject<<endl;
      }
      else if ("O"==gate){
        SimulationObject *newObject = new NInputOrGate(myObjName,
                                                       numberOfInputs,
                                                       numberOfOutputs,
                                                       outputObjectNames,
                                                       destinationPorts,
                                                       delay);
        objects->push_back(newObject);
        // cout << "building object with R !"<<endl;
        // cout << "the address of the object is " << newObject<<endl;
      }
      else {
        if("NOT"==gate1){
          SimulationObject *newObject = new NotGate(myObjName,
                                                    numberOfInputs,numberOfOutputs,outputObjectNames,
                                                    destinationPorts,delay);
          objects->push_back(newObject);
        }
        if("NAN"==gate1){
          SimulationObject *newObject = new NotGate(myObjName,
                                                     numberOfInputs,numberOfOutputs,outputObjectNames,
                                                     destinationPorts,delay);
	  objects->push_back(newObject);
	}

       if("NOR"==gate1){
         SimulationObject *newObject = new NotGate(myObjName,
                                                   numberOfInputs,numberOfOutputs,outputObjectNames,
                                                   destinationPorts,delay);
         objects->push_back(newObject);
        }
     }
   }
     // cout<<"objects size is"<<objects->size()<<endl;
      retval = myPartitioner->partition( objects, numberOfProcessorsAvailable );
      delete objects;
      return retval;
}

void
Iscas85Application::registerDeserializers(){
	DeserializerManager::instance()->registerDeserializer(LogicEvent::getLogicEventDataType(),&LogicEvent::deserialize);
}

ArgumentParser &
Iscas85Application::getArgumentParser(){
  static ArgumentParser::ArgRecord args[] = {
  {"-simulate", "input file name", &inputFileName, ArgumentParser::STRING,false},
  {"","",0 }
  };
  static ArgumentParser *myArgParser = new ArgumentParser(args);
  return *myArgParser;
}

<commit_msg>change the Iscas85 models configuration file input manner<commit_after>// Copyright (c) The University of Cincinnati.
// All rights reserved.

// UC MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
// THE SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  UC SHALL NOT BE LIABLE
// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
// RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
// DERIVATIVES.

// By using or copying this Software, Licensee agrees to abide by the
// intellectual property laws, and all other applicable laws of the
// U.S., and the terms of this license.

//Authors: Xinyu Guo                   guox2@mail.uc.edu
//         Philip A. Wilsey            phil.wilsey@uc.edu

#include "Iscas85Application.h"
#include "LogicEvent.h"
#include "FileReaderWriter.h"
#include "NInputAndGate.h"
#include "NInputXorGate.h"
#include "NInputOrGate.h"
#include "NInputNandGate.h"
#include "NInputNorGate.h"
#include "NotGate.h"
#include <warped/PartitionInfo.h>
#include <warped/RoundRobinPartitioner.h>
#include <warped/DeserializerManager.h>
#include <utils/ArgumentParser.h>
#include "vector"
#include "iostream"
#include "fstream"
#include "stdlib.h"

using namespace std;

Iscas85Application::Iscas85Application()
  :inputFileName( "" ),
   testCaseFileName(""),
   numObjects( 0 ){}

int
Iscas85Application::initialize( vector<string> &arguments ){
  string path="circuitsimulationmodels/iscas85/iscas85Sim/";
  arguments[2] = path+arguments[2]+"/"+arguments[2]+"config";

  getArgumentParser().checkArgs( arguments );

  if( inputFileName.empty() ){
    std::cerr << "A smmpSim configuration file must be specified using -simulate"<<std::endl;
    abort();
  }
  return 0;
}

int
Iscas85Application::finalize(){
  return 0;
}

int
Iscas85Application::getNumberOfSimulationObjects(int mgrId) const {
  return numObjects;
}

const PartitionInfo*
Iscas85Application::getPartitionInfo(unsigned int numberOfProcessorsAvailable){
  const PartitionInfo *retval = 0;
  Partitioner *myPartitioner = new RoundRobinPartitioner();

  int numFileObjects;
  string fileName;
  int numOfGates;
  string type;
  int desPort;
  string desGateName;
  int maxLines;

  ifstream configfile;

  configfile.open(inputFileName.c_str());

  if(configfile.fail()){
    cerr<<"Could not open file!:'"<<inputFileName<<"'"<<endl;
    cerr<<"Terminating simulation."<<endl;
    abort();
  }

  vector<SimulationObject *> *objects = new vector<SimulationObject *>;

  string filePath;//
  int totalGates; // total gates number in the circuit
  configfile>>filePath;//
  configfile>>numFileObjects;
  configfile>>totalGates;

  for(int i=0; i < numFileObjects; i++){
    configfile>>fileName>>numOfGates>>type;
    vector<int> *desPortId = new vector<int>;
    vector<string> *desGatesNames = new vector<string>;

    if(0==numOfGates){
      configfile>>desPort;
      //cout<<"numOfGates is:"<<numOfGates<<endl;
      //cout<<"desPort Value is:"<<desPort<<endl;
      desPortId->push_back(desPort);
      configfile>>desGateName;
      //cout<<"numOfGates is:"<<numOfGates<<endl;
      //cout<<"desPort Value is:"<<desPort<<endl;
      desGatesNames->push_back(desGateName);
    }
  else{
    for(int j= 0;j<numOfGates;j++){
    configfile>>desPort;
    //cout<<"numOfGates is:"<<numOfGates<<endl;
    //cout<<"desPort Value is:"<<desPort<<endl;
    desPortId->push_back(desPort);
   }
    for(int j= 0;j<numOfGates;j++){
      configfile>>desGateName;
      desGatesNames->push_back(desGateName);
    }
  }
    configfile>>maxLines;
    fileName = filePath+fileName;//the absolute path of the file
    SimulationObject *newObject = new FileReaderWriter(fileName,numOfGates,type,desPortId,desGatesNames,maxLines);
    objects->push_back(newObject);
    //cout<<"construct FileReaderWriter object!"<<endl;
  }

   // int totalGates; // total gates number in the circuit

    string myObjName;    // object name
    int numberOfInputs;  // the number of inputs of the object
    int numberOfOutputs; // the number of objects connected to the object
    string destObjName;  // the name of the gate which receives the object output
    int desInputPort;    // pin id of the gate which receives the object output
    int delay;           // the delay between event receiving and event sending

  // configfile >> totalGates;

    for(int i = 0; i < totalGates; i++){
      configfile >> myObjName >> numberOfInputs >> numberOfOutputs;// >> destObjName >> desInputPort;
      vector<string> *outputObjectNames = new vector<string>;
      vector<int> *destinationPorts = new vector<int>;

      for(int i = 0; i < numberOfOutputs; i++){
        configfile >> destObjName;
        //cout<<"object name is "<< destObjName<<endl;
        outputObjectNames -> push_back(destObjName);
      }

      for(int i =0; i < numberOfOutputs; i++){
        configfile >> desInputPort;
        destinationPorts->push_back(desInputPort);
      }

      configfile >> delay;
      string gate= myObjName.substr(0,1);
      string gate1 = myObjName.substr(0,3);

      if("A"==gate){
        SimulationObject *newObject = new NInputAndGate(myObjName,
                                                        numberOfInputs,
                                                        numberOfOutputs,
                                                        outputObjectNames,
                                                        destinationPorts,
                                                        delay);

        objects->push_back(newObject);
        // cout << "building object with R !"<<endl;
        // cout << "the address of the object is " << newObject<<endl;
      }
      else if ("X"==gate){
        SimulationObject *newObject = new NInputXorGate(myObjName,
                                                        numberOfInputs,
                                                        numberOfOutputs,
                                                        outputObjectNames,
                                                        destinationPorts,
                                                        delay);

        objects->push_back(newObject);
        // cout << "building object with R !"<<endl;
        // cout << "the address of the object is " << newObject<<endl;
      }
      else if ("O"==gate){
        SimulationObject *newObject = new NInputOrGate(myObjName,
                                                       numberOfInputs,
                                                       numberOfOutputs,
                                                       outputObjectNames,
                                                       destinationPorts,
                                                       delay);
        objects->push_back(newObject);
        // cout << "building object with R !"<<endl;
        // cout << "the address of the object is " << newObject<<endl;
      }
      else {
        if("NOT"==gate1){
          SimulationObject *newObject = new NotGate(myObjName,
                                                    numberOfInputs,numberOfOutputs,outputObjectNames,
                                                    destinationPorts,delay);
          objects->push_back(newObject);
        }
        if("NAN"==gate1){
          SimulationObject *newObject = new NotGate(myObjName,
                                                     numberOfInputs,numberOfOutputs,outputObjectNames,
                                                     destinationPorts,delay);
	  objects->push_back(newObject);
	}

       if("NOR"==gate1){
         SimulationObject *newObject = new NotGate(myObjName,
                                                   numberOfInputs,numberOfOutputs,outputObjectNames,
                                                   destinationPorts,delay);
         objects->push_back(newObject);
        }
     }
   }
     // cout<<"objects size is"<<objects->size()<<endl;
      retval = myPartitioner->partition( objects, numberOfProcessorsAvailable );
      delete objects;
      return retval;
}

void
Iscas85Application::registerDeserializers(){
	DeserializerManager::instance()->registerDeserializer(LogicEvent::getLogicEventDataType(),&LogicEvent::deserialize);
}

ArgumentParser &
Iscas85Application::getArgumentParser(){
  static ArgumentParser::ArgRecord args[] = {
  {"-simulate", "input file name", &inputFileName, ArgumentParser::STRING,false},
  {"","",0 }
  };
  static ArgumentParser *myArgParser = new ArgumentParser(args);
  return *myArgParser;
}

<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/UI/Attic/CTabWidget.cpp,v $
//   $Revision: 1.16 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2008/06/03 13:58:56 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include <qtabwidget.h>
#include <qlayout.h>

#include "CTabWidget.h"
#include "ModelWidget.h"
#include "MIRIAMUI/CQMiriamWidget.h"
#include "MIRIAMUI/CQRDFListViewWidget.h"

/*
 *  Constructs a CTabWidget as a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'. label is the first
 *  tab name.
 */
CTabWidget::CTabWidget(const QString & label, CopasiWidget * pCopasiWidget,
                       QWidget* parent, const char* name, WFlags f)
    : CopasiWidget(parent, name, f)
{
  if (!name)
    CopasiWidget::setName("CTabWidget");

  QHBoxLayout* tabLayout = new QHBoxLayout(this, 0, 0, "tabLayout");
  mTabWidget = new QTabWidget (this, "mTabWidget");
  tabLayout->addWidget(mTabWidget);

  mPages.push_back(pCopasiWidget);
  mTabWidget->addTab(pCopasiWidget, label);

  CQMiriamWidget* pMIRIAMWidget = new CQMiriamWidget(mTabWidget);
  mPages.push_back(pMIRIAMWidget);
  mTabWidget->addTab(mPages[1], "Annotation");

  CQRDFListViewWidget* pRDFListViewWidget = new CQRDFListViewWidget(mTabWidget);
  mPages.push_back(pRDFListViewWidget);
  mTabWidget->addTab(mPages[2], "RDF Browser");
  pRDFListViewWidget->setMIRIAMInfo(&pMIRIAMWidget->getMIRIAMInfo());
}

/*
 *  Destroys the object and frees any allocated resources
 */
CTabWidget::~CTabWidget()
{
  // no need to delete child widgets, Qt does it all for us
}

bool CTabWidget::leave()
{
  std::vector< CopasiWidget * >::iterator it = mPages.begin();
  std::vector< CopasiWidget * >::iterator end = mPages.end();

  for (; it != end; ++it)
    (*it)->leave();

  return true;
}

bool CTabWidget::enter(const std::string & key)
{
  std::vector< CopasiWidget * >::iterator it = mPages.begin();
  std::vector< CopasiWidget * >::iterator end = mPages.end();

  for (; it != end; ++it)
    (*it)->enter(key);

  return true;
}
<commit_msg>Removed obsolete call to CRDFListViewWidget::setMIRIAMInfo.<commit_after>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/UI/Attic/CTabWidget.cpp,v $
//   $Revision: 1.17 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2008/06/10 20:30:32 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include <qtabwidget.h>
#include <qlayout.h>

#include "CTabWidget.h"
#include "ModelWidget.h"
#include "MIRIAMUI/CQMiriamWidget.h"
#include "MIRIAMUI/CQRDFListViewWidget.h"

/*
 *  Constructs a CTabWidget as a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'. label is the first
 *  tab name.
 */
CTabWidget::CTabWidget(const QString & label, CopasiWidget * pCopasiWidget,
                       QWidget* parent, const char* name, WFlags f)
    : CopasiWidget(parent, name, f)
{
  if (!name)
    CopasiWidget::setName("CTabWidget");

  QHBoxLayout* tabLayout = new QHBoxLayout(this, 0, 0, "tabLayout");
  mTabWidget = new QTabWidget (this, "mTabWidget");
  tabLayout->addWidget(mTabWidget);

  mPages.push_back(pCopasiWidget);
  mTabWidget->addTab(pCopasiWidget, label);

  CQMiriamWidget* pMIRIAMWidget = new CQMiriamWidget(mTabWidget);
  mPages.push_back(pMIRIAMWidget);
  mTabWidget->addTab(mPages[1], "Annotation");

  CQRDFListViewWidget* pRDFListViewWidget = new CQRDFListViewWidget(mTabWidget);
  mPages.push_back(pRDFListViewWidget);
  mTabWidget->addTab(mPages[2], "RDF Browser");
}

/*
 *  Destroys the object and frees any allocated resources
 */
CTabWidget::~CTabWidget()
{
  // no need to delete child widgets, Qt does it all for us
}

bool CTabWidget::leave()
{
  std::vector< CopasiWidget * >::iterator it = mPages.begin();
  std::vector< CopasiWidget * >::iterator end = mPages.end();

  for (; it != end; ++it)
    (*it)->leave();

  return true;
}

bool CTabWidget::enter(const std::string & key)
{
  std::vector< CopasiWidget * >::iterator it = mPages.begin();
  std::vector< CopasiWidget * >::iterator end = mPages.end();

  for (; it != end; ++it)
    (*it)->enter(key);

  return true;
}
<|endoftext|>


<commit_before>#include "RooFitCore/RooFit.hh"

#include "Rtypes.h"
#include "Rtypes.h"
#include "Riostream.h"

// -- CLASS DESCRIPTION [AUX] --
// Print banner message when RooFit library is loaded

const char* VTAG="2.06" ;

Int_t doBanner()
{
  cout << endl
  << "\033[1mRooFit v" << VTAG << " -- Developed by Wouter Verkerke and David Kirkby\033[0m " << endl
              << "                Copyright (C) 2000-2005 NIKHEF, University of California & Stanford University" << endl
              << "                All rights reserved, please read http://roofit.sourceforge.net/license.txt" << endl << endl ;
  return 0 ;
}

static Int_t dummy = doBanner() ;
<commit_msg><commit_after>#include "RooFitCore/RooFit.hh"

#include "Rtypes.h"
#include "Rtypes.h"
#include "Riostream.h"

// -- CLASS DESCRIPTION [AUX] --
// Print banner message when RooFit library is loaded

const char* VTAG="2.07" ;

Int_t doBanner()
{
  cout << endl
  << "\033[1mRooFit v" << VTAG << " -- Developed by Wouter Verkerke and David Kirkby\033[0m " << endl
              << "                Copyright (C) 2000-2005 NIKHEF, University of California & Stanford University" << endl
              << "                All rights reserved, please read http://roofit.sourceforge.net/license.txt" << endl << endl ;
  return 0 ;
}

static Int_t dummy = doBanner() ;
<|endoftext|>


<commit_before>/**
Copyright (c) 2013, Philip Deegan.
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
    * Neither the name of Philip Deegan nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

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

#include <string>
#include <tchar.h>
#include <stdio.h>
#include <sstream>
#include <strsafe.h>
#include <Windows.h>

#include "kul/os.hpp"
#include "kul/def.hpp"
#include "kul/log.hpp"
#include "kul/string.hpp"
#include "kul/proc.base.hpp"

// extern char **environ;
#include <iostream>

namespace kul{

namespace this_proc{
inline int32_t id(){
	return GetCurrentProcessId();
}
inline void kill(const int32_t& e){
	TerminateProcess(OpenProcess(PROCESS_TERMINATE, 0, kul::this_proc::id()), 128+e);
}
}

class Process : public kul::AProcess{
	private:
		static ULONG PIPE_ID(){
			static ULONG p = 999;
			p++;
			return p;
		}
		HANDLE g_hChildStd_OUT_Rd = NULL;
		HANDLE g_hChildStd_OUT_Wr = NULL;
		HANDLE g_hChildStd_ERR_Rd = NULL;
		HANDLE g_hChildStd_ERR_Wr = NULL;

		HANDLE revent = CreateEvent(0, 1, 0, 0);
	public:
		Process(const std::string& cmd, const bool& wfe = true)                         : kul::AProcess(cmd, wfe)      {}
		Process(const std::string& cmd, const std::string& path, const bool& wfe = true): kul::AProcess(cmd, path, wfe){}
		~Process(){ tearDown(); }
		bool kill(int16_t k = 6){
			if(!started()) return 0;
			DWORD dwDesiredAccess = PROCESS_TERMINATE;
			bool  bInheritHandle  = 0;
			HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, pid());
			if (hProcess == NULL) return 0;
			bool r = TerminateProcess(hProcess, 128+k);
			CloseHandle(hProcess);
			setFinished();
			return r;
		}
	protected:
		void tearDown(){
			CloseHandle(g_hChildStd_OUT_Rd);
			CloseHandle(g_hChildStd_ERR_Rd);
		}
		void run() throw (kul::Exception){
			SECURITY_ATTRIBUTES sa;
			ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
			// Set the bInheritHandle flag so pipe handles are inherited.
			sa.nLength = sizeof(SECURITY_ATTRIBUTES);
			sa.bInheritHandle = TRUE;
			sa.lpSecurityDescriptor = NULL;

			std::stringstream ss;
			ss << this;

			const ULONG& pipeID = PIPE_ID();
			std::string pipeOut = "\\\\.\\Pipe\\kul_proc_out."+std::to_string(this_proc::id())+"."+ss.str()+"."+std::to_string(pipeID);
			std::string pipeErr = "\\\\.\\Pipe\\kul_proc_err."+std::to_string(this_proc::id())+"."+ss.str()+"."+std::to_string(pipeID);
			std::string pipeIn  = "\\\\.\\Pipe\\kul_proc_in." +std::to_string(this_proc::id())+"."+ss.str()+"."+std::to_string(pipeID);

			LPSTR lPipeOut = _strdup(pipeOut.c_str());
			g_hChildStd_OUT_Wr = ::CreateNamedPipeA(lPipeOut, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
				 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, __KUL_PROCESS_BUFFER__,
				 __KUL_PROCESS_BUFFER__, 0, &sa);
			if(!g_hChildStd_OUT_Wr) error(__LINE__, "CreatePipe failed");
			g_hChildStd_OUT_Rd = ::CreateFileA(lPipeOut, GENERIC_READ, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
			if(!g_hChildStd_OUT_Rd) error(__LINE__, "CreatePipe failed");
			if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) 	error(__LINE__, "SetHandleInformation failed");

			LPSTR lPipeErr = _strdup(pipeErr.c_str());
			g_hChildStd_ERR_Wr = ::CreateNamedPipeA(lPipeErr, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
				 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, __KUL_PROCESS_BUFFER__,
				 __KUL_PROCESS_BUFFER__, 0, &sa);
			if(!g_hChildStd_ERR_Wr) error(__LINE__, "CreatePipe failed");
			g_hChildStd_ERR_Rd = ::CreateFileA(lPipeErr, GENERIC_READ, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
			if(!g_hChildStd_ERR_Rd) error(__LINE__, "CreatePipe failed");
			if (!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) 	error(__LINE__, "SetHandleInformation failed");

			bool bSuccess = FALSE;

			PROCESS_INFORMATION piProcInfo;
			STARTUPINFO siStartInfo;

			ZeroMemory(&piProcInfo,  sizeof(PROCESS_INFORMATION));
			ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));

			siStartInfo.cb = sizeof(STARTUPINFO);
			siStartInfo.dwFlags = STARTF_USESTDHANDLES;
			siStartInfo.hStdError = g_hChildStd_ERR_Wr;
			siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
			siStartInfo.wShowWindow = SW_HIDE;
			siStartInfo.lpDesktop = NULL;
			siStartInfo.lpReserved = NULL;
			siStartInfo.lpTitle = NULL;
			siStartInfo.cbReserved2 = 0;
			siStartInfo.lpReserved2 = NULL;

			unsigned flags = CREATE_UNICODE_ENVIRONMENT;
			HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE,
					FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
					FILE_ATTRIBUTE_NORMAL, NULL);
			if (cons == INVALID_HANDLE_VALUE) {
				flags |= DETACHED_PROCESS;
			} else {
				CloseHandle(cons);
			}

			preStart();

			LPTSTR lpszVariable;
			LPCH lpvEnv;
			lpvEnv = GetEnvironmentStrings();
			if (lpvEnv == NULL) error(__LINE__, "GetEnvironmentStrings() failed.");
			kul::hash::map::S2S env;
			for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++){
				std::stringstream ss;
				while (*lpszVariable) ss << *lpszVariable++;
				std::string var = ss.str();
				if(var.find(":") != std::string::npos)
					env.insert(var.substr(0, var.find(":")), var.substr(var.find(":") + 1));
				else env.insert(var, "");
			}
			if(FreeEnvironmentStrings(lpvEnv) == 0) error(__LINE__, "FreeEnvironmentStrings() failed");

			const char* dir = directory().empty() ? 0 : directory().c_str();
			LPSTR szCmdline = _strdup(toString().c_str());
			if(vars().size()){
				TCHAR chNewEnv[__KUL_PROCESS_ENV_BUFFER__];
				LPTSTR lpszCurrentVariable;
				lpszCurrentVariable = (LPTSTR) chNewEnv;
				for(auto& evs : vars()){
					if(FAILED(StringCchCopy(lpszCurrentVariable, __KUL_PROCESS_ENV_BUFFER__, TEXT(std::string(evs.first + "=" + evs.second).c_str()))))
						error(__LINE__, "String copy failed");
					lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
				}
				for(auto& evs : env){
					if(vars().count(evs.first)) continue;
					if(FAILED(StringCchCopy(lpszCurrentVariable, __KUL_PROCESS_ENV_BUFFER__, TEXT(std::string(evs.first + "=" + evs.second).c_str()))))
						error(__LINE__, "String copy failed");
					lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
				}
				*lpszCurrentVariable = (TCHAR)0;
				bSuccess = CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, flags, chNewEnv, dir, &siStartInfo, &piProcInfo);
			}else
				bSuccess = CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, flags, NULL,     dir, &siStartInfo, &piProcInfo);

			if(!bSuccess) error(__LINE__, "CreateProcess failed with last error: " + GetLastError());

			pid(piProcInfo.dwProcessId);

			CloseHandle(g_hChildStd_OUT_Wr);
			CloseHandle(g_hChildStd_ERR_Wr);

			if(this->waitForExit()){
				OVERLAPPED il = { 0 };
				memset(&il, 0, sizeof(il));
				il.hEvent = revent;
				OVERLAPPED ol = { 0 };
				memset(&ol, 0, sizeof(ol));
				ol.hEvent = revent;
				OVERLAPPED el = { 0 };
				memset(&el, 0, sizeof(el));
				el.hEvent = revent;

				DWORD dwRead;
				CHAR chBuf[__KUL_PROCESS_BUFFER__ + 1];
				bSuccess = FALSE;
				bool alive = true;
				do{
					alive = WaitForSingleObject(piProcInfo.hProcess, 11) == WAIT_TIMEOUT;
					for (;;) {
						dwRead = 0;
						bSuccess = ::ReadFile( g_hChildStd_OUT_Rd, chBuf, __KUL_PROCESS_BUFFER__, &dwRead, &ol);
						while(!bSuccess && (GetLastError() == ERROR_IO_PENDING || GetLastError() == ERROR_IO_INCOMPLETE)){
							WaitForSingleObject(ol.hEvent, 11);
							bSuccess = GetOverlappedResult(g_hChildStd_OUT_Rd, &ol, &dwRead, 0);
						}
						if(!bSuccess || dwRead == 0) break;
						chBuf[dwRead] = '\0';
						out(std::string(chBuf, dwRead));
					}
					for (;;) {
						dwRead = 0;
						bSuccess = ::ReadFile( g_hChildStd_ERR_Rd, chBuf, __KUL_PROCESS_BUFFER__, &dwRead, &el);
						if (GetLastError() == ERROR_IO_PENDING) {
							WaitForSingleObject(el.hEvent, 11);
							bSuccess = GetOverlappedResult(g_hChildStd_OUT_Rd, &el, &dwRead, 0);
						}
						if(!bSuccess || dwRead == 0) break;
						chBuf[dwRead] = '\0';
						err(std::string(chBuf, dwRead));
					}
				}while(alive);
			}
			tearDown();
			if(this->waitForExit()){
				DWORD ec = 0;
				if (FALSE == GetExitCodeProcess(piProcInfo.hProcess, &ec))
					KEXCEPT(kul::proc::Exception, "GetExitCodeProcess failure");
				exitCode(ec);
				finish();
				setFinished();
			}
			CloseHandle(piProcInfo.hThread);
			CloseHandle(piProcInfo.hProcess);
		}
	};
}

#endif /* _KUL_PROC_HPP_ */
<commit_msg>wstring in win proc for env vars<commit_after>/**
Copyright (c) 2013, Philip Deegan.
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
    * Neither the name of Philip Deegan nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

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

#include <string>
#include <tchar.h>
#include <stdio.h>
#include <sstream>
#include <strsafe.h>
#include <Windows.h>

#include "kul/os.hpp"
#include "kul/def.hpp"
#include "kul/log.hpp"
#include "kul/string.hpp"
#include "kul/proc.base.hpp"

// extern char **environ;
#include <iostream>

namespace kul{

namespace this_proc{
inline int32_t id(){
	return GetCurrentProcessId();
}
inline void kill(const int32_t& e){
	TerminateProcess(OpenProcess(PROCESS_TERMINATE, 0, kul::this_proc::id()), 128+e);
}
}

class Process : public kul::AProcess{
	private:
		static ULONG PIPE_ID(){
			static ULONG p = 999;
			p++;
			return p;
		}
		HANDLE g_hChildStd_OUT_Rd = NULL;
		HANDLE g_hChildStd_OUT_Wr = NULL;
		HANDLE g_hChildStd_ERR_Rd = NULL;
		HANDLE g_hChildStd_ERR_Wr = NULL;

		HANDLE revent = CreateEvent(0, 1, 0, 0);
	public:
		Process(const std::string& cmd, const bool& wfe = true)                         : kul::AProcess(cmd, wfe)      {}
		Process(const std::string& cmd, const std::string& path, const bool& wfe = true): kul::AProcess(cmd, path, wfe){}
		~Process(){ tearDown(); }
		bool kill(int16_t k = 6){
			if(!started()) return 0;
			DWORD dwDesiredAccess = PROCESS_TERMINATE;
			bool  bInheritHandle  = 0;
			HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, pid());
			if (hProcess == NULL) return 0;
			bool r = TerminateProcess(hProcess, 128+k);
			CloseHandle(hProcess);
			setFinished();
			return r;
		}
	protected:
		void tearDown(){
			CloseHandle(g_hChildStd_OUT_Rd);
			CloseHandle(g_hChildStd_ERR_Rd);
		}
		void run() throw (kul::Exception){
			SECURITY_ATTRIBUTES sa;
			ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
			// Set the bInheritHandle flag so pipe handles are inherited.
			sa.nLength = sizeof(SECURITY_ATTRIBUTES);
			sa.bInheritHandle = TRUE;
			sa.lpSecurityDescriptor = NULL;

			std::stringstream ss;
			ss << this;

			const ULONG& pipeID = PIPE_ID();
			std::string pipeOut = "\\\\.\\Pipe\\kul_proc_out."+std::to_string(this_proc::id())+"."+ss.str()+"."+std::to_string(pipeID);
			std::string pipeErr = "\\\\.\\Pipe\\kul_proc_err."+std::to_string(this_proc::id())+"."+ss.str()+"."+std::to_string(pipeID);
			std::string pipeIn  = "\\\\.\\Pipe\\kul_proc_in." +std::to_string(this_proc::id())+"."+ss.str()+"."+std::to_string(pipeID);

			LPSTR lPipeOut = _strdup(pipeOut.c_str());
			g_hChildStd_OUT_Wr = ::CreateNamedPipeA(lPipeOut, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
				 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, __KUL_PROCESS_BUFFER__,
				 __KUL_PROCESS_BUFFER__, 0, &sa);
			if(!g_hChildStd_OUT_Wr) error(__LINE__, "CreatePipe failed");
			g_hChildStd_OUT_Rd = ::CreateFileA(lPipeOut, GENERIC_READ, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
			if(!g_hChildStd_OUT_Rd) error(__LINE__, "CreatePipe failed");
			if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) 	error(__LINE__, "SetHandleInformation failed");

			LPSTR lPipeErr = _strdup(pipeErr.c_str());
			g_hChildStd_ERR_Wr = ::CreateNamedPipeA(lPipeErr, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
				 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, __KUL_PROCESS_BUFFER__,
				 __KUL_PROCESS_BUFFER__, 0, &sa);
			if(!g_hChildStd_ERR_Wr) error(__LINE__, "CreatePipe failed");
			g_hChildStd_ERR_Rd = ::CreateFileA(lPipeErr, GENERIC_READ, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
			if(!g_hChildStd_ERR_Rd) error(__LINE__, "CreatePipe failed");
			if (!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) 	error(__LINE__, "SetHandleInformation failed");

			bool bSuccess = FALSE;

			PROCESS_INFORMATION piProcInfo;
			STARTUPINFO siStartInfo;

			ZeroMemory(&piProcInfo,  sizeof(PROCESS_INFORMATION));
			ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));

			siStartInfo.cb = sizeof(STARTUPINFO);
			siStartInfo.dwFlags = STARTF_USESTDHANDLES;
			siStartInfo.hStdError = g_hChildStd_ERR_Wr;
			siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
			siStartInfo.wShowWindow = SW_HIDE;
			siStartInfo.lpDesktop = NULL;
			siStartInfo.lpReserved = NULL;
			siStartInfo.lpTitle = NULL;
			siStartInfo.cbReserved2 = 0;
			siStartInfo.lpReserved2 = NULL;

			unsigned flags = CREATE_UNICODE_ENVIRONMENT;
			HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE,
					FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
					FILE_ATTRIBUTE_NORMAL, NULL);
			if (cons == INVALID_HANDLE_VALUE) {
				flags |= DETACHED_PROCESS;
			} else {
				CloseHandle(cons);
			}

			preStart();

			LPTSTR lpszVariable;
			LPCH lpvEnv;
			lpvEnv = GetEnvironmentStrings();
			if (lpvEnv == NULL) error(__LINE__, "GetEnvironmentStrings() failed.");
			kul::hash::map::S2S env;
			for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++){
				std::stringstream ss;
				while (*lpszVariable) ss << *lpszVariable++;
				std::string var = ss.str();
				if(var.find(":") != std::string::npos)
					env.insert(var.substr(0, var.find(":")), var.substr(var.find(":") + 1));
				else env.insert(var, "");
			}
			if(FreeEnvironmentStrings(lpvEnv) == 0) error(__LINE__, "FreeEnvironmentStrings() failed");

			const char* dir = directory().empty() ? 0 : directory().c_str();
			LPSTR szCmdline = _strdup(toString().c_str());
			if(vars().size()){
				WCHAR chNewEnv[__KUL_PROCESS_ENV_BUFFER__];
				LPWSTR lpszCurrentVariable;
				lpszCurrentVariable = (LPWSTR) chNewEnv;
				for(auto& evs : vars()){
					std::string var(evs.first + "=" + evs.second);
					if(FAILED(StringCchCopyW(lpszCurrentVariable, __KUL_PROCESS_ENV_BUFFER__, (std::wstring(var.begin(), var.end()).c_str()))))
						error(__LINE__, "String copy failed");
					lpszCurrentVariable += wcslen(lpszCurrentVariable) + 1;
				}
				for(auto& evs : env){
					if(vars().count(evs.first)) continue;
					std::string var(evs.first + "=" + evs.second);
					if(FAILED(StringCchCopyW(lpszCurrentVariable, __KUL_PROCESS_ENV_BUFFER__, (std::wstring(var.begin(), var.end()).c_str()))))
						error(__LINE__, "String copy failed");
					lpszCurrentVariable += wcslen(lpszCurrentVariable) + 1;
				}
				*lpszCurrentVariable = (TCHAR)0;
				bSuccess = CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, flags, chNewEnv, dir, &siStartInfo, &piProcInfo);
			}else
				bSuccess = CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, flags, NULL,     dir, &siStartInfo, &piProcInfo);

			if(!bSuccess) error(__LINE__, "CreateProcess failed with last error: " + GetLastError());

			pid(piProcInfo.dwProcessId);

			CloseHandle(g_hChildStd_OUT_Wr);
			CloseHandle(g_hChildStd_ERR_Wr);

			if(this->waitForExit()){
				OVERLAPPED il = { 0 };
				memset(&il, 0, sizeof(il));
				il.hEvent = revent;
				OVERLAPPED ol = { 0 };
				memset(&ol, 0, sizeof(ol));
				ol.hEvent = revent;
				OVERLAPPED el = { 0 };
				memset(&el, 0, sizeof(el));
				el.hEvent = revent;

				DWORD dwRead;
				CHAR chBuf[__KUL_PROCESS_BUFFER__ + 1];
				bSuccess = FALSE;
				bool alive = true;
				do{
					alive = WaitForSingleObject(piProcInfo.hProcess, 11) == WAIT_TIMEOUT;
					for (;;) {
						dwRead = 0;
						bSuccess = ::ReadFile( g_hChildStd_OUT_Rd, chBuf, __KUL_PROCESS_BUFFER__, &dwRead, &ol);
						while(!bSuccess && (GetLastError() == ERROR_IO_PENDING || GetLastError() == ERROR_IO_INCOMPLETE)){
							WaitForSingleObject(ol.hEvent, 11);
							bSuccess = GetOverlappedResult(g_hChildStd_OUT_Rd, &ol, &dwRead, 0);
						}
						if(!bSuccess || dwRead == 0) break;
						chBuf[dwRead] = '\0';
						out(std::string(chBuf, dwRead));
					}
					for (;;) {
						dwRead = 0;
						bSuccess = ::ReadFile( g_hChildStd_ERR_Rd, chBuf, __KUL_PROCESS_BUFFER__, &dwRead, &el);
						if (GetLastError() == ERROR_IO_PENDING) {
							WaitForSingleObject(el.hEvent, 11);
							bSuccess = GetOverlappedResult(g_hChildStd_OUT_Rd, &el, &dwRead, 0);
						}
						if(!bSuccess || dwRead == 0) break;
						chBuf[dwRead] = '\0';
						err(std::string(chBuf, dwRead));
					}
				}while(alive);
			}
			tearDown();
			if(this->waitForExit()){
				DWORD ec = 0;
				if (FALSE == GetExitCodeProcess(piProcInfo.hProcess, &ec))
					KEXCEPT(kul::proc::Exception, "GetExitCodeProcess failure");
				exitCode(ec);
				finish();
				setFinished();
			}
			CloseHandle(piProcInfo.hThread);
			CloseHandle(piProcInfo.hProcess);
		}
	};
}

#endif /* _KUL_PROC_HPP_ */
<|endoftext|>


<commit_before>/*
 * File:   PIDController.cpp
 * Author: User
 *
 * Created on April 22, 2014, 6:28 PM
 */

#include "PIDController.h"

using namespace boost::chrono;

PIDController::PIDController(double kp, double ki, double kd) {
    this->setGains(kp, ki, kd);
    this->setConstraints(-1, -1);
    this->init();
}

PIDController::PIDController(double kp, double ki, double kd, double lowerConstraint, double upperConstraint) {
    this->setGains(kp, ki, kd);
    this->setConstraints(lowerConstraint, upperConstraint);
    this->init();
}

PIDController::PIDController() {
    this->setGains(0, 0, 0);
    this->setConstraints(-100,100);
    this->init();
}

PIDController::PIDController(const PIDController& orig) {
    this->setGains(orig.kp, orig.ki, orig.kd);
    this->setConstraints(orig.lowerConstraint, orig.upperConstraint);
    integrator = orig.integrator;
    lastError = orig.lastError;
}

PIDController::~PIDController() {
}

void PIDController::targetSetpoint(double setpoint) {
    this->setpoint = setpoint;
    peakTime = -1;
	settlingTime = -1;
	percentOvershoot = 0;
    sample_timer.start();
    performance_timer.start();
}

void PIDController::setGains(double kp, double ki, double kd) {
    this->kp = kp;
    this->ki = ki;
    this->kd = kd;
}

void PIDController::setConstraints(double lowerConstraint, double upperConstraint) {
    this->lowerConstraint = lowerConstraint;
    this->upperConstraint = upperConstraint;
}

double PIDController::getSetpoint() {
    return setpoint;
}

double PIDController::getKp() {
    return kp;
}

double PIDController::getKi() {
    return ki;
}

double PIDController::getKd() {
    return kd;
}

void PIDController::init() {
    setpoint = 0;
    integrator = 0;
    lastError = 0;
	peakTime = -1;
	settlingTime = -1;
	percentOvershoot = 0;
    sample_timer.stop();
	performance_timer.stop();
}

bool PIDController::hasSettled() {
	if(settlingTime != -1) {
		return true;
	}

	else {
		return false;
	}
}

double PIDController::calc(double processVariable) {
    sample_timer.stop();

	double percent = (processVariable/setpoint) - 1;

	if(percent > percentOvershoot && percent > 0)
	{
		percentOvershoot = processVariable/setpoint;
		peakTime = (performance_timer.elapsed().wall)/1e9;
	}
	if(abs(percent) < 0.05 && settlingTime == -1)
	{
		performance_timer.stop();
		settlingTime = (performance_timer.elapsed().wall)/1e9;
		std::cout << "Peak Time Tp: " << peakTime << std::endl;
		std::cout << "Percent Overshoot %OS: " << percentOvershoot << std::endl;
		std::cout << "Settling Time Ts" << settlingTime << std::endl;
	}

	double error = setpoint - processVariable;
    double samplingTime = (sample_timer.elapsed().wall)/1e9;
	double differentiator = (error - lastError)/samplingTime;
    integrator += (error * samplingTime);
    double controlVariable = kp * error + ki * integrator + kd * differentiator;
    if(controlVariable < lowerConstraint) {
        controlVariable = lowerConstraint;
    }
    else if(controlVariable > upperConstraint) {
        controlVariable = upperConstraint;
    }
    lastError = error;

	sample_timer.start();

    return controlVariable;
}

<commit_msg>Attempt to fix tabs<commit_after>/*
 * File:   PIDController.cpp
 * Author: User
 *
 * Created on April 22, 2014, 6:28 PM
 */

#include "PIDController.h"

using namespace boost::chrono;

PIDController::PIDController(double kp, double ki, double kd) {
	this->setGains(kp, ki, kd);
	this->setConstraints(-1, -1);
	this->init();
}

PIDController::PIDController(double kp, double ki, double kd, double lowerConstraint, double upperConstraint) {
	this->setGains(kp, ki, kd);
	this->setConstraints(lowerConstraint, upperConstraint);
	this->init();
}

PIDController::PIDController() {
	this->setGains(0, 0, 0);
	this->setConstraints(-100,100);
	this->init();
}

PIDController::PIDController(const PIDController& orig) {
	this->setGains(orig.kp, orig.ki, orig.kd);
	this->setConstraints(orig.lowerConstraint, orig.upperConstraint);
	integrator = orig.integrator;
	lastError = orig.lastError;
}

PIDController::~PIDController() {
}

void PIDController::targetSetpoint(double setpoint) {
	this->setpoint = setpoint;
	peakTime = -1;
	settlingTime = -1;
	percentOvershoot = 0;
	sample_timer.start();
	performance_timer.start();
}

void PIDController::setGains(double kp, double ki, double kd) {
	this->kp = kp;
	this->ki = ki;
	this->kd = kd;
}

void PIDController::setConstraints(double lowerConstraint, double upperConstraint) {
	this->lowerConstraint = lowerConstraint;
	this->upperConstraint = upperConstraint;
}

double PIDController::getSetpoint() {
	return setpoint;
}

double PIDController::getKp() {
	return kp;
}

double PIDController::getKi() {
	return ki;
}

double PIDController::getKd() {
	return kd;
}

void PIDController::init() {
	setpoint = 0;
	integrator = 0;
	lastError = 0;
	peakTime = -1;
	settlingTime = -1;
	percentOvershoot = 0;
	sample_timer.stop();
	performance_timer.stop();
}

bool PIDController::hasSettled() {
	if(settlingTime != -1) {
		return true;
	}

	else {
		return false;
	}
}

double PIDController::calc(double processVariable) {
	sample_timer.stop();

	double percent = (processVariable/setpoint) - 1;

	if(percent > percentOvershoot && percent > 0)
	{
		percentOvershoot = processVariable/setpoint;
		peakTime = (performance_timer.elapsed().wall)/1e9;
	}
	if(abs(percent) < 0.05 && settlingTime == -1)
	{
		performance_timer.stop();
		settlingTime = (performance_timer.elapsed().wall)/1e9;
		std::cout << "Peak Time Tp: " << peakTime << std::endl;
		std::cout << "Percent Overshoot %OS: " << percentOvershoot << std::endl;
		std::cout << "Settling Time Ts" << settlingTime << std::endl;
	}

	double error = setpoint - processVariable;
	double samplingTime = (sample_timer.elapsed().wall)/1e9;
	double differentiator = (error - lastError)/samplingTime;
	integrator += (error * samplingTime);
	double controlVariable = kp * error + ki * integrator + kd * differentiator;
	if(controlVariable < lowerConstraint) {
		controlVariable = lowerConstraint;
	}
	else if(controlVariable > upperConstraint) {
		controlVariable = upperConstraint;
	}
	lastError = error;

	sample_timer.start();

	return controlVariable;
}

<|endoftext|>


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

#include "random_pcg.h"

#include "core/os/os.h"

RandomPCG::RandomPCG(uint64_t p_seed, uint64_t p_inc) :
		pcg(),
		current_inc(p_inc) {
	seed(p_seed);
}

void RandomPCG::randomize() {
	seed((OS::get_singleton()->get_unix_time() + OS::get_singleton()->get_ticks_usec()) * pcg.state + PCG_DEFAULT_INC_64);
}

double RandomPCG::random(double p_from, double p_to) {
	return randd() * (p_to - p_from) + p_from;
}

float RandomPCG::random(float p_from, float p_to) {
	return randf() * (p_to - p_from) + p_from;
}

int RandomPCG::random(int p_from, int p_to) {
	if (p_from == p_to) {
		return p_from;
	}
	return rand(abs(p_from - p_to) + 1) + MIN(p_from, p_to);
}
<commit_msg>Cast Unix time to uint in the randomize function<commit_after>/*************************************************************************/
/*  random_pcg.cpp                                                       */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "random_pcg.h"

#include "core/os/os.h"

RandomPCG::RandomPCG(uint64_t p_seed, uint64_t p_inc) :
		pcg(),
		current_inc(p_inc) {
	seed(p_seed);
}

void RandomPCG::randomize() {
	seed(((uint64_t)OS::get_singleton()->get_unix_time() + OS::get_singleton()->get_ticks_usec()) * pcg.state + PCG_DEFAULT_INC_64);
}

double RandomPCG::random(double p_from, double p_to) {
	return randd() * (p_to - p_from) + p_from;
}

float RandomPCG::random(float p_from, float p_to) {
	return randf() * (p_to - p_from) + p_from;
}

int RandomPCG::random(int p_from, int p_to) {
	if (p_from == p_to) {
		return p_from;
	}
	return rand(abs(p_from - p_to) + 1) + MIN(p_from, p_to);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: auditsh.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-27 13:19:56 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_AUDITSH_HXX
#define SC_AUDITSH_HXX

#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif
#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif

#include "shellids.hxx"

class ScViewData;

class ScAuditingShell : public SfxShell
{
private:
    ScViewData* pViewData;
    USHORT      nFunction;

public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_AUDITING_SHELL)

                    ScAuditingShell(ScViewData* pData);
                    ~ScAuditingShell();

    void    Execute(SfxRequest& rReq);
    void    GetState(SfxItemSet& rSet);
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.330); FILE MERGED 2008/04/01 15:30:49 thb 1.3.330.2: #i85898# Stripping all external header guards 2008/03/31 17:15:39 rt 1.3.330.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: auditsh.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_AUDITSH_HXX
#define SC_AUDITSH_HXX

#include <sfx2/shell.hxx>
#include <sfx2/module.hxx>

#include "shellids.hxx"

class ScViewData;

class ScAuditingShell : public SfxShell
{
private:
    ScViewData* pViewData;
    USHORT      nFunction;

public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_AUDITING_SHELL)

                    ScAuditingShell(ScViewData* pData);
                    ~ScAuditingShell();

    void    Execute(SfxRequest& rReq);
    void    GetState(SfxItemSet& rSet);
};

#endif

<|endoftext|>