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

#include "data_set.hpp"

#include "utilities.hpp"

//#define BOOST_SPIRIT_DEBUG 1

#include <ostream>

// Parser section
#include <boost/config/warning_disable.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
namespace spirit = boost::spirit;
namespace l = boost::lambda;

namespace std {
  static inline ostream &operator<<(ostream &s, const mtconnect::observation::DataSetEntry &t);

  static inline ostream &operator<<(ostream &s, const mtconnect::observation::DataSetValue &t)
  {
    using namespace mtconnect::observation;
    visit(mtconnect::overloaded {[&s](const monostate &) { s << "NULL"; },
                                 [&s](const std::string &st) { s << "string(" << st << ")"; },
                                 [&s](const int64_t &i) { s << "int(" << i << ")"; },
                                 [&s](const double &d) { s << "double(" << d << ")"; },
                                 [&s](const DataSet &arg) {
                                   s << "{";
                                   for (const auto &v : arg)
                                   {
                                     s << v << ", ";
                                   }
                                   s << "}";
                                 }},
          t);
    return s;
  }

  static inline ostream &operator<<(ostream &s, const mtconnect::observation::DataSetEntry &t)
  {
    s << t.m_key << "=" << t.m_value << (t.m_removed ? ":removed" : "");
    return s;
  }

}  // namespace std

using namespace std;

namespace mtconnect {
  namespace observation {
    struct data_set
    {
      inline static void add_entry_f(DataSet &ds, const DataSetEntry &entry) { ds.emplace(entry); }
      inline static void add_value_entry_f(DataSetValue &ds, const DataSetEntry &entry)
      {
        if (holds_alternative<monostate>(ds))
        {
          ds = DataSet();
        }
        if (holds_alternative<DataSet>(ds))
        {
          get<DataSet>(ds).emplace(entry);
        }
        else
        {
          LOG(error) << "Incorrect type for data set entry of table";
        }
      }
      static void make_entry_f(DataSetEntry &entry, const string &key,
                               const boost::optional<DataSetValue> &v)
      {
        entry.m_key = key;
        if (v && !holds_alternative<monostate>(*v))
          entry.m_value = *v;
        else
          entry.m_removed = true;
      }
      static void make_entry_f(DataSetEntry &entry, const string &key,
                               const boost::optional<DataSet> &v)
      {
        entry.m_key = key;
        if (v)
          entry.m_value = *v;
        else
          entry.m_removed = true;
      }
      template <typename Iterator>
      static size_t pos_f(Iterator it)
      {
        return it.position();
      }
    };
    BOOST_PHOENIX_ADAPT_FUNCTION(void, add_entry, data_set::add_entry_f, 2);
    BOOST_PHOENIX_ADAPT_FUNCTION(void, add_value_entry, data_set::add_value_entry_f, 2);
    BOOST_PHOENIX_ADAPT_FUNCTION(void, make_entry, data_set::make_entry_f, 3);
    BOOST_PHOENIX_ADAPT_FUNCTION(size_t, pos, data_set::pos_f, 1);

    template <typename It>
    class DataSetParser : public qi::grammar<It, DataSet()>
    {
    protected:
      template<typename P, typename O, typename R>
      void logError(P &params, O &obj, R& result)
      {
        using namespace boost::fusion;

        auto &start = at_c<0>(params);
        auto &end = at_c<1>(params);
        //auto &what = at_c<2>(params);
        auto &expected = at_c<3>(params);

        std::string text(start, end);

        LOG(error) << "Error when parsing DataSet, expecting '" << expected << "' when parsing '"
                  << text << '\'';

      }

    public:
      DataSetParser(bool table) : DataSetParser::base_type(m_start)
      {
        using namespace qi;
        using phx::construct;
        using phx::val;
        using qi::_1;
        using qi::_2;
        using qi::as_string;
        using qi::double_;
        using qi::lexeme;
        using qi::long_long;
        using qi::on_error;
        using spirit::ascii::char_;

        // Data set parser
        m_key %= lexeme[+(char_ - (space | char_("=|{}'\"")))];
        m_number %= (m_real | long_long) >> &(space | char_("}'\"") | eoi);
        m_value %= (m_number | m_quoted | m_braced | m_simple);
        m_simple %= lexeme[+(char_ - (char_("\"'{}") | space))];

        m_quoted %= (omit[char_("\"'")[_a = _1]] >>
                    as_string[*((lit('\\') >> (char_(_a))) | char_ - lit(_a))]) > lit(_a);

        m_braced %= (lit('{') >>
                    as_string[*((lit('\\') >> char_('}')) | char_ - lit('}'))]) >
                    lit('}');

        m_entry = (m_key >> -("=" >> -m_value))[make_entry(_val, _1, _2)];

        // Table support with quoted and braced content
        m_quotedDataSet =
            (char_("\"'")[_a = _1] >> *space >> *(m_entry[add_entry(_val, _1)] >> *space)) > lit(_a);
        m_bracedDataSet =
            (lit('{') >> *space >> *(m_entry[add_entry(_val, _1)] >> *space)) > lit('}');
        m_tableValue %= (m_quotedDataSet | m_bracedDataSet);
        m_tableEntry = (m_key >> -("=" > &(space | lit('{') | '\'' | '"' ) >> -m_tableValue))[make_entry(_val, _1, _2)];

        if (table)
        {
          m_start = *space >> *(m_tableEntry[add_entry(_val, _1)] >> *space) >> eoi;
        }
        else
        {
          m_start = *space >> *(m_entry[add_entry(_val, _1)] >> *space) >> eoi;
        }

        BOOST_SPIRIT_DEBUG_NODES((m_start)(m_quoted)(m_braced)(m_key)(m_value)(m_entry)(m_simple)(
            m_quoted)(m_tableValue)(m_quotedDataSet)(m_bracedDataSet)(m_tableEntry));

        m_start.name("top");
        m_simple.name("simple");
        m_quoted.name("quoted");
        m_entry.name("entry");
        m_value.name("value");
        m_simple.name("simple");
        m_quoted.name("quoted");

        m_tableValue.name("table value");
        m_quotedDataSet.name("quoted data set");
        m_bracedDataSet.name("braced data set");
        m_tableEntry.name("table entry");

        using namespace boost::fusion;

        on_error<fail>(m_entry, [&](auto &params, auto &obj, auto &result) {
          logError(params, obj, result);
        });
        on_error<fail>(m_tableEntry, [&](auto &params, auto &obj, auto &result) {
          logError(params, obj, result);
        });
        on_error<fail>(m_start, [&](auto &params, auto &obj, auto &result) {
          logError(params, obj, result);
        });
      }

    protected:
      qi::rule<It, DataSet()> m_start;
      qi::real_parser<double, qi::strict_real_policies<double>> m_real;
      qi::rule<It, DataSetValue()> m_number;
      qi::rule<It, DataSetValue(), qi::locals<char>> m_quoted;
      qi::rule<It, DataSetValue()> m_braced;
      qi::rule<It, string()> m_key;
      qi::rule<It, string()> m_simple;
      qi::rule<It, DataSetValue()> m_value;
      qi::rule<It, DataSetEntry()> m_entry;

      qi::rule<It, DataSet(), qi::locals<char>> m_quotedDataSet;
      qi::rule<It, DataSet()> m_bracedDataSet;
      qi::rule<It, DataSet()> m_tableValue;
      qi::rule<It, DataSetEntry()> m_tableEntry;
    };

    // Split the data set entries by space delimiters and account for the
    // use of single and double quotes as well as curly braces
    bool DataSet::parse(const std::string &text, bool table)
    {
      using boost::spirit::ascii::space;

      using Iterator = std::string::const_iterator;
      DataSetParser<Iterator> parser(table);

      auto s = text.begin();
      auto e = text.end();

      bool r = qi::parse(s, e, parser, *this);
      if (r && s == e)
      {
        // cout << "Success: " << tree << endl;
        return true;
      }
      else
      {
        LOG(error) << "Failed to parse data set: " << text;
        return false;
      }
    }
  }  // namespace observation
}  // namespace mtconnect
<commit_msg>use int_parser instead of long_long parser for ubuntu compatibility<commit_after>//
// Copyright Copyright 2009-2021, AMT – The Association For Manufacturing Technology (“AMT”)
// All rights reserved.
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//

#include "data_set.hpp"

#include "utilities.hpp"

//#define BOOST_SPIRIT_DEBUG 1

#include <ostream>

// Parser section
#include <boost/config/warning_disable.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
namespace spirit = boost::spirit;
namespace l = boost::lambda;

namespace std {
  static inline ostream &operator<<(ostream &s, const mtconnect::observation::DataSetEntry &t);

  static inline ostream &operator<<(ostream &s, const mtconnect::observation::DataSetValue &t)
  {
    using namespace mtconnect::observation;
    visit(mtconnect::overloaded {[&s](const monostate &) { s << "NULL"; },
                                 [&s](const std::string &st) { s << "string(" << st << ")"; },
                                 [&s](const int64_t &i) { s << "int(" << i << ")"; },
                                 [&s](const double &d) { s << "double(" << d << ")"; },
                                 [&s](const DataSet &arg) {
                                   s << "{";
                                   for (const auto &v : arg)
                                   {
                                     s << v << ", ";
                                   }
                                   s << "}";
                                 }},
          t);
    return s;
  }

  static inline ostream &operator<<(ostream &s, const mtconnect::observation::DataSetEntry &t)
  {
    s << t.m_key << "=" << t.m_value << (t.m_removed ? ":removed" : "");
    return s;
  }

}  // namespace std

using namespace std;

namespace mtconnect {
  namespace observation {
    struct DataSetParserActions
    {
      inline static void add_entry_f(DataSet &ds, const DataSetEntry &entry) { ds.emplace(entry); }
      inline static void add_value_entry_f(DataSetValue &ds, const DataSetEntry &entry)
      {
        if (holds_alternative<monostate>(ds))
        {
          ds = DataSet();
        }
        if (holds_alternative<DataSet>(ds))
        {
          get<DataSet>(ds).emplace(entry);
        }
        else
        {
          LOG(error) << "Incorrect type for data set entry of table";
        }
      }
      static void make_entry_f(DataSetEntry &entry, const string &key,
                               const boost::optional<DataSetValue> &v)
      {
        entry.m_key = key;
        if (v && !holds_alternative<monostate>(*v))
          entry.m_value = *v;
        else
          entry.m_removed = true;
      }
      static void make_entry_f(DataSetEntry &entry, const string &key,
                               const boost::optional<DataSet> &v)
      {
        entry.m_key = key;
        if (v)
          entry.m_value = *v;
        else
          entry.m_removed = true;
      }
      template <typename Iterator>
      static size_t pos_f(Iterator it)
      {
        return it.position();
      }
    };
    BOOST_PHOENIX_ADAPT_FUNCTION(void, add_entry, DataSetParserActions::add_entry_f, 2);
    BOOST_PHOENIX_ADAPT_FUNCTION(void, add_value_entry, DataSetParserActions::add_value_entry_f, 2);
    BOOST_PHOENIX_ADAPT_FUNCTION(void, make_entry, DataSetParserActions::make_entry_f, 3);
    BOOST_PHOENIX_ADAPT_FUNCTION(size_t, pos, DataSetParserActions::pos_f, 1);

    template <typename It>
    class DataSetParser : public qi::grammar<It, DataSet()>
    {
    protected:
      template<typename P, typename O, typename R>
      void logError(P &params, O &obj, R& result)
      {
        using namespace boost::fusion;

        auto &start = at_c<0>(params);
        auto &end = at_c<1>(params);
        //auto &what = at_c<2>(params);
        auto &expected = at_c<3>(params);

        std::string text(start, end);

        LOG(error) << "Error when parsing DataSet, expecting '" << expected << "' when parsing '"
                  << text << '\'';

      }

    public:
      DataSetParser(bool table) : DataSetParser::base_type(m_start)
      {
        using namespace qi;
        using phx::construct;
        using phx::val;
        using qi::_1;
        using qi::_2;
        using qi::as_string;
        using qi::double_;
        using qi::lexeme;
        using qi::int_parser;
        using qi::on_error;
        using spirit::ascii::char_;

        // Data set parser
        m_key %= lexeme[+(char_ - (space | char_("=|{}'\"")))];
        m_number %= (m_real | int_parser<int64_t, 10>()) >> &(space | char_("}'\"") | eoi);
        m_value %= (m_number | m_quoted | m_braced | m_simple);
        m_simple %= lexeme[+(char_ - (char_("\"'{}") | space))];

        m_quoted %= (omit[char_("\"'")[_a = _1]] >>
                    as_string[*((lit('\\') >> (char_(_a))) | char_ - lit(_a))]) > lit(_a);

        m_braced %= (lit('{') >>
                    as_string[*((lit('\\') >> char_('}')) | char_ - lit('}'))]) >
                    lit('}');

        m_entry = (m_key >> -("=" >> -m_value))[make_entry(_val, _1, _2)];

        // Table support with quoted and braced content
        m_quotedDataSet =
            (char_("\"'")[_a = _1] >> *space >> *(m_entry[add_entry(_val, _1)] >> *space)) > lit(_a);
        m_bracedDataSet =
            (lit('{') >> *space >> *(m_entry[add_entry(_val, _1)] >> *space)) > lit('}');
        m_tableValue %= (m_quotedDataSet | m_bracedDataSet);
        m_tableEntry = (m_key >> -("=" > &(space | lit('{') | '\'' | '"' ) >> -m_tableValue))[make_entry(_val, _1, _2)];

        if (table)
        {
          m_start = *space >> *(m_tableEntry[add_entry(_val, _1)] >> *space) >> eoi;
        }
        else
        {
          m_start = *space >> *(m_entry[add_entry(_val, _1)] >> *space) >> eoi;
        }

        BOOST_SPIRIT_DEBUG_NODES((m_start)(m_quoted)(m_braced)(m_key)(m_value)(m_entry)(m_simple)(
            m_quoted)(m_tableValue)(m_quotedDataSet)(m_bracedDataSet)(m_tableEntry));

        m_start.name("top");
        m_simple.name("simple");
        m_quoted.name("quoted");
        m_entry.name("entry");
        m_value.name("value");
        m_simple.name("simple");
        m_quoted.name("quoted");

        m_tableValue.name("table value");
        m_quotedDataSet.name("quoted data set");
        m_bracedDataSet.name("braced data set");
        m_tableEntry.name("table entry");

        using namespace boost::fusion;

        on_error<fail>(m_entry, [&](auto &params, auto &obj, auto &result) {
          logError(params, obj, result);
        });
        on_error<fail>(m_tableEntry, [&](auto &params, auto &obj, auto &result) {
          logError(params, obj, result);
        });
        on_error<fail>(m_start, [&](auto &params, auto &obj, auto &result) {
          logError(params, obj, result);
        });
      }

    protected:
      qi::rule<It, DataSet()> m_start;
      qi::real_parser<double, qi::strict_real_policies<double>> m_real;
      qi::rule<It, DataSetValue()> m_number;
      qi::rule<It, DataSetValue(), qi::locals<char>> m_quoted;
      qi::rule<It, DataSetValue()> m_braced;
      qi::rule<It, string()> m_key;
      qi::rule<It, string()> m_simple;
      qi::rule<It, DataSetValue()> m_value;
      qi::rule<It, DataSetEntry()> m_entry;

      qi::rule<It, DataSet(), qi::locals<char>> m_quotedDataSet;
      qi::rule<It, DataSet()> m_bracedDataSet;
      qi::rule<It, DataSet()> m_tableValue;
      qi::rule<It, DataSetEntry()> m_tableEntry;
    };

    // Split the data set entries by space delimiters and account for the
    // use of single and double quotes as well as curly braces
    bool DataSet::parse(const std::string &text, bool table)
    {
      using boost::spirit::ascii::space;

      using Iterator = std::string::const_iterator;
      DataSetParser<Iterator> parser(table);

      auto s = text.begin();
      auto e = text.end();

      bool r = qi::parse(s, e, parser, *this);
      if (r && s == e)
      {
        // cout << "Success: " << tree << endl;
        return true;
      }
      else
      {
        LOG(error) << "Failed to parse data set: " << text;
        return false;
      }
    }
  }  // namespace observation
}  // namespace mtconnect
<|endoftext|>


<commit_before>#include "cinder/app/AppNative.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/Context.h"
#include "cinder/Xml.h"
#include "cinder/Timeline.h"
#include "cinder/ImageIo.h"
#include "cinder/Thread.h"
#include "cinder/ConcurrentCircularBuffer.h"

/*	The heart of this sample is to show how to create a background thread that interacts with OpenGL.
	It launches a secondary thread which pulls down images from a Flickr group and puts them in a thread-safe buffer.
	We can allocate a gl::Context which shares resources (specifically Textures) with the primary gl::Context.
	Note that this Context should be created in the primary thread and passed as a parameter to the secondary thread.
*/

using namespace ci;
using namespace ci::app;
using namespace std;

class FlickrTestMTApp : public AppNative {
  public:
	void setup();
	void update();
	void draw();
	void shutdown();
	void loadImagesThreadFn( gl::ContextRef sharedGlContext );

	ConcurrentCircularBuffer<gl::TextureRef>	*mImages;

	bool					mShouldQuit;
	shared_ptr<thread>		mThread;
	gl::TextureRef			mTexture, mLastTexture;
	Anim<float>				mFade;
	double					mLastTime;
};

void FlickrTestMTApp::setup()
{
	mShouldQuit = false;
	mImages = new ConcurrentCircularBuffer<gl::TextureRef>( 5 ); // room for 5 images
	// create and launch the thread with a new gl::Context just for that thread
	gl::ContextRef backgroundCtx = gl::Context::create( gl::context() );
	mThread = shared_ptr<thread>( new thread( bind( &FlickrTestMTApp::loadImagesThreadFn, this, backgroundCtx ) ) );
	mLastTime = getElapsedSeconds() - 10; // force an initial update by make it "ten seconds ago"

	gl::enableAlphaBlending();
}

void FlickrTestMTApp::loadImagesThreadFn( gl::ContextRef context )
{
	ci::ThreadSetup threadSetup; // instantiate this if you're talking to Cinder from a secondary thread
	// we received as a parameter a gl::Context we can use safely that shares resources with the primary Context
	context->makeCurrent();
	vector<Url>	urls;

	// parse the image URLS from the XML feed and push them into 'urls'
	const Url sunFlickrGroup = Url( "http://api.flickr.com/services/feeds/groups_pool.gne?id=52242317293@N01&format=rss_200" );
	const XmlTree xml( loadUrl( sunFlickrGroup ) );
	for( auto item = xml.begin( "rss/channel/item" ); item != xml.end(); ++item ) {
		const XmlTree &urlXml = ( ( *item / "media:content" ) );
		urls.push_back( Url( urlXml["url"] ) );
	}

	// load images as Textures into our ConcurrentCircularBuffer
	// don't create gl::Textures on a background thread
	while( ( ! mShouldQuit ) && ( ! urls.empty() ) ) {
		try {
			mImages->pushFront( gl::Texture::create( loadImage( loadUrl( urls.back() ) ) ) );
			urls.pop_back();
		}
		catch( ci::Exception &exc ) {
			console() << "failed to create texture, what: " << exc.what() << std::endl;
		}
	}
}

void FlickrTestMTApp::update()
{
	double timeSinceLastImage = getElapsedSeconds() - mLastTime;
	if( ( timeSinceLastImage > 2.5 ) && mImages->isNotEmpty() ) {
		mLastTexture = mTexture; // the "last" texture is now the current text

		mImages->popBack( &mTexture );

		mLastTime = getElapsedSeconds();
		// blend from 0 to 1 over 1.5sec
		timeline().apply( &mFade, 0.0f, 1.0f, 1.5f );
	}
}

void FlickrTestMTApp::draw()
{
	gl::clear( Color( 0.1f, 0.1f, 0.2f ) );

	if( mLastTexture ) {
		gl::color( 1, 1, 1, 1.0f - mFade );
		Rectf textureBounds = mLastTexture->getBounds();
		Rectf drawBounds = textureBounds.getCenteredFit( getWindowBounds(), true );
		gl::draw( mLastTexture, drawBounds );
	}
	if( mTexture ) {
		gl::color( 1, 1, 1, mFade );
		Rectf textureBounds = mTexture->getBounds();
		Rectf drawBounds = textureBounds.getCenteredFit( getWindowBounds(), true );
		gl::draw( mTexture, drawBounds );
	}
}

void FlickrTestMTApp::shutdown()
{
	mShouldQuit = true;
	mImages->cancel();
	mThread->join();
}

CINDER_APP_NATIVE( FlickrTestMTApp, RendererGl )<commit_msg>FlickrTestMultithreaded build fix<commit_after>#include "cinder/app/AppNative.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/Context.h"
#include "cinder/gl/Texture.h"
#include "cinder/Xml.h"
#include "cinder/Timeline.h"
#include "cinder/ImageIo.h"
#include "cinder/Thread.h"
#include "cinder/ConcurrentCircularBuffer.h"

/*	The heart of this sample is to show how to create a background thread that interacts with OpenGL.
	It launches a secondary thread which pulls down images from a Flickr group and puts them in a thread-safe buffer.
	We can allocate a gl::Context which shares resources (specifically Textures) with the primary gl::Context.
	Note that this Context should be created in the primary thread and passed as a parameter to the secondary thread.
*/

using namespace ci;
using namespace ci::app;
using namespace std;

class FlickrTestMTApp : public AppNative {
  public:
	void setup();
	void update();
	void draw();
	void shutdown();
	void loadImagesThreadFn( gl::ContextRef sharedGlContext );

	ConcurrentCircularBuffer<gl::TextureRef>	*mImages;

	bool					mShouldQuit;
	shared_ptr<thread>		mThread;
	gl::TextureRef			mTexture, mLastTexture;
	Anim<float>				mFade;
	double					mLastTime;
};

void FlickrTestMTApp::setup()
{
	mShouldQuit = false;
	mImages = new ConcurrentCircularBuffer<gl::TextureRef>( 5 ); // room for 5 images
	// create and launch the thread with a new gl::Context just for that thread
	gl::ContextRef backgroundCtx = gl::Context::create( gl::context() );
	mThread = shared_ptr<thread>( new thread( bind( &FlickrTestMTApp::loadImagesThreadFn, this, backgroundCtx ) ) );
	mLastTime = getElapsedSeconds() - 10; // force an initial update by make it "ten seconds ago"

	gl::enableAlphaBlending();
}

void FlickrTestMTApp::loadImagesThreadFn( gl::ContextRef context )
{
	ci::ThreadSetup threadSetup; // instantiate this if you're talking to Cinder from a secondary thread
	// we received as a parameter a gl::Context we can use safely that shares resources with the primary Context
	context->makeCurrent();
	vector<Url>	urls;

	// parse the image URLS from the XML feed and push them into 'urls'
	const Url sunFlickrGroup = Url( "http://api.flickr.com/services/feeds/groups_pool.gne?id=52242317293@N01&format=rss_200" );
	const XmlTree xml( loadUrl( sunFlickrGroup ) );
	for( auto item = xml.begin( "rss/channel/item" ); item != xml.end(); ++item ) {
		const XmlTree &urlXml = ( ( *item / "media:content" ) );
		urls.push_back( Url( urlXml["url"] ) );
	}

	// load images as Textures into our ConcurrentCircularBuffer
	// don't create gl::Textures on a background thread
	while( ( ! mShouldQuit ) && ( ! urls.empty() ) ) {
		try {
			mImages->pushFront( gl::Texture::create( loadImage( loadUrl( urls.back() ) ) ) );
			urls.pop_back();
		}
		catch( ci::Exception &exc ) {
			console() << "failed to create texture, what: " << exc.what() << std::endl;
		}
	}
}

void FlickrTestMTApp::update()
{
	double timeSinceLastImage = getElapsedSeconds() - mLastTime;
	if( ( timeSinceLastImage > 2.5 ) && mImages->isNotEmpty() ) {
		mLastTexture = mTexture; // the "last" texture is now the current text

		mImages->popBack( &mTexture );

		mLastTime = getElapsedSeconds();
		// blend from 0 to 1 over 1.5sec
		timeline().apply( &mFade, 0.0f, 1.0f, 1.5f );
	}
}

void FlickrTestMTApp::draw()
{
	gl::clear( Color( 0.1f, 0.1f, 0.2f ) );

	if( mLastTexture ) {
		gl::color( 1, 1, 1, 1.0f - mFade );
		Rectf textureBounds = mLastTexture->getBounds();
		Rectf drawBounds = textureBounds.getCenteredFit( getWindowBounds(), true );
		gl::draw( mLastTexture, drawBounds );
	}
	if( mTexture ) {
		gl::color( 1, 1, 1, mFade );
		Rectf textureBounds = mTexture->getBounds();
		Rectf drawBounds = textureBounds.getCenteredFit( getWindowBounds(), true );
		gl::draw( mTexture, drawBounds );
	}
}

void FlickrTestMTApp::shutdown()
{
	mShouldQuit = true;
	mImages->cancel();
	mThread->join();
}

CINDER_APP_NATIVE( FlickrTestMTApp, RendererGl )<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. 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.
 */

#include <QApplication>
#include <QMenu>
#include <QTimer>

#include <OgreSceneManager.h>
#include <OgreCamera.h>

#include "rviz/display.h"
#include "rviz/view_controller.h"
#include "rviz/viewport_mouse_event.h"
#include "rviz/visualization_manager.h"
#include "rviz/window_manager_interface.h"

#include "rviz/render_panel.h"

namespace rviz
{

RenderPanel::RenderPanel( QWidget* parent )
  : QtOgreRenderWindow( parent )
  , mouse_x_( 0 )
  , mouse_y_( 0 )
  , focus_on_mouse_move_( true )
  , context_( 0 )
  , scene_manager_( 0 )
  , view_controller_( 0 )
  , context_menu_visible_(false)
  , fake_mouse_move_event_timer_( new QTimer() )
  , default_camera_(0)
{
  setFocusPolicy(Qt::WheelFocus);
  setFocus( Qt::OtherFocusReason );
}

RenderPanel::~RenderPanel()
{
  delete fake_mouse_move_event_timer_;
  if( scene_manager_ && default_camera_ )
  {
    scene_manager_->destroyCamera( default_camera_ );
  }
  if( scene_manager_ )
  {
    scene_manager_->removeListener( this );
  }
}

void RenderPanel::initialize(Ogre::SceneManager* scene_manager, DisplayContext* context)
{
  context_ = context;
  scene_manager_ = scene_manager;
  scene_manager_->addListener( this );

  std::stringstream ss;
  static int count = 0;
  ss << "RenderPanelCamera" << count++;
  default_camera_ = scene_manager_->createCamera(ss.str());
  default_camera_->setNearClipDistance(0.01f);
  default_camera_->setPosition(0, 10, 15);
  default_camera_->lookAt(0, 0, 0);

  setCamera( default_camera_ );

  connect( fake_mouse_move_event_timer_, SIGNAL( timeout() ), this, SLOT( sendMouseMoveEvent() ));
  fake_mouse_move_event_timer_->start( 33 /*milliseconds*/ );
}

void RenderPanel::sendMouseMoveEvent()
{
  QPoint cursor_pos = QCursor::pos();
  QPoint mouse_rel_widget = mapFromGlobal( cursor_pos );
  if( rect().contains( mouse_rel_widget ))
  {
    bool mouse_over_this = false;
    QWidget *w = QApplication::widgetAt( cursor_pos );
    while( w )
    {
      if( w == this )
      {
        mouse_over_this = true;
        break;
      }
      w = w->parentWidget();
    }
    if( !mouse_over_this )
    {
      return;
    }

    QMouseEvent fake_event( QEvent::MouseMove,
                            mouse_rel_widget,
                            Qt::NoButton,
                            QApplication::mouseButtons(),
                            QApplication::keyboardModifiers() );
    onRenderWindowMouseEvents( &fake_event );
  }
}
void RenderPanel::leaveEvent ( QEvent * event )
{
  setCursor( Qt::ArrowCursor );
  if ( context_ )
  {
    context_->setStatus("");
  }
}

void RenderPanel::onRenderWindowMouseEvents( QMouseEvent* event )
{
  int last_x = mouse_x_;
  int last_y = mouse_y_;

  mouse_x_ = event->x();
  mouse_y_ = event->y();

  if (context_)
  {
    if (focus_on_mouse_move_) {
      setFocus( Qt::MouseFocusReason );
    }

    ViewportMouseEvent vme(this, getViewport(), event, last_x, last_y);
    context_->handleMouseEvent(vme);
    event->accept();
  }
}

void RenderPanel::wheelEvent( QWheelEvent* event )
{
  int last_x = mouse_x_;
  int last_y = mouse_y_;

  mouse_x_ = event->x();
  mouse_y_ = event->y();

  if (context_)
  {
    ViewportMouseEvent vme(this, getViewport(), event, last_x, last_y);
    context_->handleMouseEvent(vme);
    event->accept();
  }
}

void RenderPanel::keyPressEvent( QKeyEvent* event )
{
  if( context_ )
  {
    context_->handleChar( event, this );
  }
}

void RenderPanel::setViewController( ViewController* controller )
{
  view_controller_ = controller;

  if( view_controller_ )
  {
    setCamera( view_controller_->getCamera() );
    view_controller_->activate();
  }
  else
  {
    setCamera( NULL );
  }
}

void RenderPanel::showContextMenu( boost::shared_ptr<QMenu> menu )
{
  boost::mutex::scoped_lock lock(context_menu_mutex_);
  context_menu_ = menu;
  context_menu_visible_ = true;

  QApplication::postEvent( this, new QContextMenuEvent( QContextMenuEvent::Mouse, QPoint() ));
}

void RenderPanel::onContextMenuHide()
{
  context_menu_visible_ = false;
}

bool RenderPanel::contextMenuVisible()
{
  return context_menu_visible_;
}

void RenderPanel::contextMenuEvent( QContextMenuEvent* event )
{
  boost::shared_ptr<QMenu> context_menu;
  {
    boost::mutex::scoped_lock lock(context_menu_mutex_);
    context_menu.swap(context_menu_);
  }

  if ( context_menu )
  {
    connect( context_menu.get(), SIGNAL( aboutToHide() ), this, SLOT( onContextMenuHide() ) );
    context_menu->exec( QCursor::pos() );
  }
}

void RenderPanel::sceneManagerDestroyed( Ogre::SceneManager* destroyed_scene_manager )
{
  if( destroyed_scene_manager == scene_manager_ )
  {
    scene_manager_ = NULL;
    default_camera_ = NULL;
    setCamera( NULL );
  }
}

bool RenderPanel::getFocusOnMouseMove() const
{
  return focus_on_mouse_move_;
}

void RenderPanel::setFocusOnMouseMove(bool enabled)
{
  focus_on_mouse_move_ = enabled;
}

} // namespace rviz
<commit_msg>fix fake events: use actual keyboard modifiers<commit_after>/*
 * Copyright (c) 2008, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. 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.
 */

#include <QApplication>
#include <QMenu>
#include <QTimer>

#include <OgreSceneManager.h>
#include <OgreCamera.h>

#include "rviz/display.h"
#include "rviz/view_controller.h"
#include "rviz/viewport_mouse_event.h"
#include "rviz/visualization_manager.h"
#include "rviz/window_manager_interface.h"

#include "rviz/render_panel.h"

namespace rviz
{

RenderPanel::RenderPanel( QWidget* parent )
  : QtOgreRenderWindow( parent )
  , mouse_x_( 0 )
  , mouse_y_( 0 )
  , focus_on_mouse_move_( true )
  , context_( 0 )
  , scene_manager_( 0 )
  , view_controller_( 0 )
  , context_menu_visible_(false)
  , fake_mouse_move_event_timer_( new QTimer() )
  , default_camera_(0)
{
  setFocusPolicy(Qt::WheelFocus);
  setFocus( Qt::OtherFocusReason );
}

RenderPanel::~RenderPanel()
{
  delete fake_mouse_move_event_timer_;
  if( scene_manager_ && default_camera_ )
  {
    scene_manager_->destroyCamera( default_camera_ );
  }
  if( scene_manager_ )
  {
    scene_manager_->removeListener( this );
  }
}

void RenderPanel::initialize(Ogre::SceneManager* scene_manager, DisplayContext* context)
{
  context_ = context;
  scene_manager_ = scene_manager;
  scene_manager_->addListener( this );

  std::stringstream ss;
  static int count = 0;
  ss << "RenderPanelCamera" << count++;
  default_camera_ = scene_manager_->createCamera(ss.str());
  default_camera_->setNearClipDistance(0.01f);
  default_camera_->setPosition(0, 10, 15);
  default_camera_->lookAt(0, 0, 0);

  setCamera( default_camera_ );

  connect( fake_mouse_move_event_timer_, SIGNAL( timeout() ), this, SLOT( sendMouseMoveEvent() ));
  fake_mouse_move_event_timer_->start( 33 /*milliseconds*/ );
}

void RenderPanel::sendMouseMoveEvent()
{
  QPoint cursor_pos = QCursor::pos();
  QPoint mouse_rel_widget = mapFromGlobal( cursor_pos );
  if( rect().contains( mouse_rel_widget ))
  {
    bool mouse_over_this = false;
    QWidget *w = QApplication::widgetAt( cursor_pos );
    while( w )
    {
      if( w == this )
      {
        mouse_over_this = true;
        break;
      }
      w = w->parentWidget();
    }
    if( !mouse_over_this )
    {
      return;
    }

    QMouseEvent fake_event( QEvent::MouseMove,
                            mouse_rel_widget,
                            Qt::NoButton,
                            QApplication::mouseButtons(),
                            QApplication::queryKeyboardModifiers() );
    onRenderWindowMouseEvents( &fake_event );
  }
}
void RenderPanel::leaveEvent ( QEvent * event )
{
  setCursor( Qt::ArrowCursor );
  if ( context_ )
  {
    context_->setStatus("");
  }
}

void RenderPanel::onRenderWindowMouseEvents( QMouseEvent* event )
{
  int last_x = mouse_x_;
  int last_y = mouse_y_;

  mouse_x_ = event->x();
  mouse_y_ = event->y();

  if (context_)
  {
    if (focus_on_mouse_move_) {
      setFocus( Qt::MouseFocusReason );
    }

    ViewportMouseEvent vme(this, getViewport(), event, last_x, last_y);
    context_->handleMouseEvent(vme);
    event->accept();
  }
}

void RenderPanel::wheelEvent( QWheelEvent* event )
{
  int last_x = mouse_x_;
  int last_y = mouse_y_;

  mouse_x_ = event->x();
  mouse_y_ = event->y();

  if (context_)
  {
    ViewportMouseEvent vme(this, getViewport(), event, last_x, last_y);
    context_->handleMouseEvent(vme);
    event->accept();
  }
}

void RenderPanel::keyPressEvent( QKeyEvent* event )
{
  if( context_ )
  {
    context_->handleChar( event, this );
  }
}

void RenderPanel::setViewController( ViewController* controller )
{
  view_controller_ = controller;

  if( view_controller_ )
  {
    setCamera( view_controller_->getCamera() );
    view_controller_->activate();
  }
  else
  {
    setCamera( NULL );
  }
}

void RenderPanel::showContextMenu( boost::shared_ptr<QMenu> menu )
{
  boost::mutex::scoped_lock lock(context_menu_mutex_);
  context_menu_ = menu;
  context_menu_visible_ = true;

  QApplication::postEvent( this, new QContextMenuEvent( QContextMenuEvent::Mouse, QPoint() ));
}

void RenderPanel::onContextMenuHide()
{
  context_menu_visible_ = false;
}

bool RenderPanel::contextMenuVisible()
{
  return context_menu_visible_;
}

void RenderPanel::contextMenuEvent( QContextMenuEvent* event )
{
  boost::shared_ptr<QMenu> context_menu;
  {
    boost::mutex::scoped_lock lock(context_menu_mutex_);
    context_menu.swap(context_menu_);
  }

  if ( context_menu )
  {
    connect( context_menu.get(), SIGNAL( aboutToHide() ), this, SLOT( onContextMenuHide() ) );
    context_menu->exec( QCursor::pos() );
  }
}

void RenderPanel::sceneManagerDestroyed( Ogre::SceneManager* destroyed_scene_manager )
{
  if( destroyed_scene_manager == scene_manager_ )
  {
    scene_manager_ = NULL;
    default_camera_ = NULL;
    setCamera( NULL );
  }
}

bool RenderPanel::getFocusOnMouseMove() const
{
  return focus_on_mouse_move_;
}

void RenderPanel::setFocusOnMouseMove(bool enabled)
{
  focus_on_mouse_move_ = enabled;
}

} // namespace rviz
<|endoftext|>


<commit_before><commit_msg>CLW: another attempt to fix the unique Series ID problem. There was a bug rewritting the series UID I was writing. Adding a new variable fixed it.<commit_after><|endoftext|>


<commit_before>#include <sstream>
#include <math.h>
#include <boost/lexical_cast.hpp>
#include "labelconstructor.h"
#include "paraverlabels.h"
#include "histogram.h"
#include "paraverconfig.h"
string LabelConstructor::objectLabel( TObjectOrder globalOrder,
                                      TWindowLevel level,
                                      Trace *whichTrace )
{
  stringstream label;

  if ( level == WORKLOAD )
    label << LEVEL_WORKLOAD;
  else if ( level == APPLICATION )
    label << LEVEL_APPLICATION << ' ' << globalOrder + 1;
  else if ( level == TASK )
  {
    TApplOrder appl;
    TTaskOrder task;
    whichTrace->getTaskLocation( globalOrder, appl, task );
    label << LEVEL_TASK << ' ' << appl + 1 << '.' << task + 1;
  }
  else if ( level == THREAD )
  {
    TApplOrder appl;
    TTaskOrder task;
    TThreadOrder thread;
    whichTrace->getThreadLocation( globalOrder, appl, task, thread );
    label << LEVEL_THREAD << ' ' << appl + 1 << '.' << task + 1 << '.' << thread + 1;
  }
  else if ( level == SYSTEM )
    label << LEVEL_SYSTEM;
  else if ( level == NODE )
    label << LEVEL_NODE << ' ' << globalOrder + 1;
  else if ( level == CPU )
  {
    TNodeOrder node;
    TCPUOrder cpu;
    whichTrace->getCPULocation( globalOrder, node, cpu );
    label << LEVEL_CPU << ' ' << node + 1 << '.' << cpu + 1;
  }

  return label.str();
}

string LabelConstructor::histoColumnLabel( THistogramColumn whichColumn,
    const Histogram *whichHisto,
    THistogramLimit min,
    THistogramLimit max,
    THistogramLimit delta )
{
  stringstream label;
  double tmp;

  if ( modf( min, &tmp ) != 0.0 || delta != 1.0 )
  {
    // Column range values
    label << '[' << ( whichColumn * delta ) + min << "..";
    if ( ( ( whichColumn * delta ) + min + delta ) > max )
    {
      label << max;
      label << ']';
    }
    else
    {
      label << ( whichColumn * delta ) + min + delta;
      label << ')';
    }
  }
  else
  {
    // Discrete integer value
    label << ( whichColumn * delta ) + min;
  }

  return label.str();
}

inline string chomp( INT64& number )
{
  INT64 remainder = number % 1000;
  number /= 1000;

  if( number == 0 )
    return boost::lexical_cast<std::string>( remainder );
  else if( remainder > 99 )
    return boost::lexical_cast<std::string>( remainder );
  else if( remainder > 9 )
    return "0" + boost::lexical_cast<std::string>( remainder );
  else if( remainder > 0 )
    return "00" + boost::lexical_cast<std::string>( remainder );
  return "000";
}

string LabelConstructor::histoCellLabel( const Histogram *whichHisto,
    TSemanticValue value )
{
  stringstream label;

  if ( whichHisto->getScientificNotation() )
    label << scientific;
  else
    label << fixed;

  label.precision( ParaverConfig::getInstance()->getPrecision() );

  if ( whichHisto->getThousandSeparator() &&
       !whichHisto->getScientificNotation() )
  {
    string strNum;
    TSemanticValue origValue = value;
    INT64 intValue = INT64( value );

    if( origValue >= 1.0 )
    {
      while ( intValue > 0.0 )
        strNum = chomp( intValue ) + "," + strNum;
      strNum.erase( strNum.size() - 1, 1 );
      label << strNum;
    }

    stringstream tmp;
    tmp.precision( ParaverConfig::getInstance()->getPrecision() );
    value -= INT64( origValue );
    tmp << value;
    strNum = tmp.str();
    if( origValue >= 1.0 )
      strNum.erase( strNum.begin() );

    label << strNum;
  }
  else
    label << value;

  if ( whichHisto->getShowUnits() &&
       !whichHisto->itsCommunicationStat( whichHisto->getCurrentStat() ) )
    label << " " << whichHisto->getUnitsLabel( whichHisto->getCurrentStat() );

  return label.str();
}

string LabelConstructor::histoTotalLabel( THistoTotals whichTotal )
{
  switch( whichTotal )
  {
    case TOTAL:
      return "Total";
    case AVERAGE:
      return "Average";
    case MAXIMUM:
      return "Maximum";
    case MINIMUM:
      return "Minimum";
    case STDEV:
      return "StDev";
    case AVGDIVMAX:
      return "Avg/Max";
    case NUMTOTALS:
      return "";
  }

  return "";
}

string LabelConstructor::timeLabel( TTime value, TTimeUnit unit )
{
  stringstream label;

  label << fixed;
  label.precision( ParaverConfig::getInstance()->getPrecision() );

  label << value;
  label << " " << LABEL_TIMEUNIT[ unit ];

  return label.str();
}
<commit_msg>*** empty log message ***<commit_after>#include <sstream>
#include <math.h>
#include <boost/lexical_cast.hpp>
#include "labelconstructor.h"
#include "paraverlabels.h"
#include "histogram.h"
#include "paraverconfig.h"
string LabelConstructor::objectLabel( TObjectOrder globalOrder,
                                      TWindowLevel level,
                                      Trace *whichTrace )
{
  stringstream label;

  if ( level == WORKLOAD )
    label << LEVEL_WORKLOAD;
  else if ( level == APPLICATION )
    label << LEVEL_APPLICATION << ' ' << globalOrder + 1;
  else if ( level == TASK )
  {
    TApplOrder appl;
    TTaskOrder task;
    whichTrace->getTaskLocation( globalOrder, appl, task );
    label << LEVEL_TASK << ' ' << appl + 1 << '.' << task + 1;
  }
  else if ( level == THREAD )
  {
    TApplOrder appl;
    TTaskOrder task;
    TThreadOrder thread;
    whichTrace->getThreadLocation( globalOrder, appl, task, thread );
    label << LEVEL_THREAD << ' ' << appl + 1 << '.' << task + 1 << '.' << thread + 1;
  }
  else if ( level == SYSTEM )
    label << LEVEL_SYSTEM;
  else if ( level == NODE )
    label << LEVEL_NODE << ' ' << globalOrder + 1;
  else if ( level == CPU )
  {
    TNodeOrder node;
    TCPUOrder cpu;
    whichTrace->getCPULocation( globalOrder, node, cpu );
    label << LEVEL_CPU << ' ' << node + 1 << '.' << cpu + 1;
  }

  return label.str();
}

string LabelConstructor::histoColumnLabel( THistogramColumn whichColumn,
    const Histogram *whichHisto,
    THistogramLimit min,
    THistogramLimit max,
    THistogramLimit delta )
{
  stringstream label;
  double tmp;

  if ( modf( min, &tmp ) != 0.0 || delta != 1.0 )
  {
    // Column range values
    label << '[' << ( whichColumn * delta ) + min << "..";
    if ( ( ( whichColumn * delta ) + min + delta ) > max )
    {
      label << max;
      label << ']';
    }
    else
    {
      label << ( whichColumn * delta ) + min + delta;
      label << ')';
    }
  }
  else
  {
    // Discrete integer value
    label << ( whichColumn * delta ) + min;
  }

  return label.str();
}

inline string chomp( INT64& number )
{
  INT64 remainder = number % 1000;
  number /= 1000;

  if( number == 0 )
    return boost::lexical_cast<std::string>( remainder );
  else if( remainder > 99 )
    return boost::lexical_cast<std::string>( remainder );
  else if( remainder > 9 )
    return "0" + boost::lexical_cast<std::string>( remainder );
  else if( remainder > 0 )
    return "00" + boost::lexical_cast<std::string>( remainder );
  return "000";
}

string LabelConstructor::histoCellLabel( const Histogram *whichHisto,
    TSemanticValue value )
{
  stringstream label;

  if( value == numeric_limits<double>::infinity() )
    return "inf";

  if ( whichHisto->getScientificNotation() )
    label << scientific;
  else
    label << fixed;

  label.precision( ParaverConfig::getInstance()->getPrecision() );

  if ( whichHisto->getThousandSeparator() &&
       !whichHisto->getScientificNotation() )
  {
    string strNum;
    TSemanticValue origValue = value;
    INT64 intValue = INT64( value );

    if( origValue >= 1.0 )
    {
      while ( intValue > 0.0 )
        strNum = chomp( intValue ) + "," + strNum;
      strNum.erase( strNum.size() - 1, 1 );
      label << strNum;
    }

    stringstream tmp;
    tmp.precision( ParaverConfig::getInstance()->getPrecision() );
    value -= INT64( origValue );
    tmp << value;
    strNum = tmp.str();
    if( origValue >= 1.0 )
      strNum.erase( strNum.begin() );

    label << strNum;
  }
  else
    label << value;

  if ( whichHisto->getShowUnits() &&
       !whichHisto->itsCommunicationStat( whichHisto->getCurrentStat() ) )
    label << " " << whichHisto->getUnitsLabel( whichHisto->getCurrentStat() );

  return label.str();
}

string LabelConstructor::histoTotalLabel( THistoTotals whichTotal )
{
  switch( whichTotal )
  {
    case TOTAL:
      return "Total";
    case AVERAGE:
      return "Average";
    case MAXIMUM:
      return "Maximum";
    case MINIMUM:
      return "Minimum";
    case STDEV:
      return "StDev";
    case AVGDIVMAX:
      return "Avg/Max";
    case NUMTOTALS:
      return "";
  }

  return "";
}

string LabelConstructor::timeLabel( TTime value, TTimeUnit unit )
{
  stringstream label;

  label << fixed;
  label.precision( ParaverConfig::getInstance()->getPrecision() );

  label << value;
  label << " " << LABEL_TIMEUNIT[ unit ];

  return label.str();
}
<|endoftext|>


<commit_before>#ifndef MANIFOLDS_FUNCTIONS_TUPLE_UTILITIES_HH
#define MANIFOLDS_FUNCTIONS_TUPLE_UTILITIES_HH

#include <tuple>
#include <utility>

namespace manifolds {

  template <class Tuple, std::size_t ... befores,
	    std::size_t ... afters>
  auto remove_element_helper(const Tuple & t,
			     std::integer_sequence<
			     std::size_t, befores...>,
			     std::integer_sequence<
			     std::size_t, afters...>)
  {
    static const std::size_t offset = sizeof...(befores)+1;
    auto r = std::make_tuple(std::get<befores>(t)...,
			     std::get<afters+offset>(t)...);
    return r;
  }

  template <int index, class Tuple>
  auto remove_element(const Tuple & t)
  {
    typedef std::make_index_sequence<index> befores;
    typedef std::make_integer_sequence<
      std::size_t, std::tuple_size<Tuple>::value-index-1>
      afters;
    return remove_element_helper(t, befores(), afters());
  }

  template <int index, class Tuple, class E,
	    std::size_t ... befores,
	    std::size_t ... afters>
  auto insert_element_helper(const Tuple & t,
			     const E & e,
			     std::integer_sequence<
			     std::size_t, befores...>,
			     std::integer_sequence<
			     std::size_t, afters...>)
  {
    auto before = std::make_tuple(std::get<befores>(t)...);
    auto middle = std::make_tuple(e);
    auto after  = std::make_tuple(std::get<afters+index>(t)...);
    return std::tuple_cat(before, middle, after);
  }

  template <int index, class Tuple, class E>
  auto insert_element(const Tuple & t, const E & e)
  {
    return insert_element_helper<index>
      (t, e, std::make_index_sequence<index>(),
       std::make_index_sequence<
       std::tuple_size<Tuple>::value - index>());
  }
}

#endif
<commit_msg>more helpers<commit_after>#ifndef MANIFOLDS_FUNCTIONS_TUPLE_UTILITIES_HH
#define MANIFOLDS_FUNCTIONS_TUPLE_UTILITIES_HH

#include <tuple>
#include <utility>

#include "function.hh"

#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/sort.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/pop_front.hpp>

namespace manifolds {

  template <class Tuple, std::size_t ... befores,
	    std::size_t ... afters>
  auto remove_element_helper(const Tuple & t,
			     std::integer_sequence<
			     std::size_t, befores...>,
			     std::integer_sequence<
			     std::size_t, afters...>)
  {
    static const std::size_t offset = sizeof...(befores)+1;
    auto r = std::make_tuple(std::get<befores>(t)...,
			     std::get<afters+offset>(t)...);
    return r;
  }

  template <int index, class Tuple>
  auto remove_element(const Tuple & t)
  {
    typedef std::make_index_sequence<index> befores;
    typedef std::make_integer_sequence<
      std::size_t, std::tuple_size<Tuple>::value-index-1>
      afters;
    return remove_element_helper(t, befores(), afters());
  }

  template <class Tuple>
  auto remove_element(const Tuple & t,
		      boost::mpl::vector<>)
  {
    return t;
  }

  template <class Tuple, class Vector>
  auto remove_elements(const Tuple & t, Vector)
  {
    return remove_element<
      boost::mpl::at_c<Vector, 0>::type::value>
      (remove_elements(t, typename boost::mpl::pop_front<
		       Vector>::type()));
  }

  template <int ... indices, class Tuple>
  auto remove_elements(const Tuple & t)
  {
    typedef typename boost::mpl::sort<
      boost::mpl::vector_c<int,indices...>
      >::type sorted_list;
    return remove_elements(t, sorted_list());
  }

  template <int index, class Tuple, class E,
	    std::size_t ... befores,
	    std::size_t ... afters>
  auto insert_element_helper(const Tuple & t,
			     const E & e,
			     std::integer_sequence<
			     std::size_t, befores...>,
			     std::integer_sequence<
			     std::size_t, afters...>)
  {
    auto before = std::make_tuple(std::get<befores>(t)...);
    auto middle = std::make_tuple(e);
    auto after  = std::make_tuple(std::get<afters+index>(t)...);
    return std::tuple_cat(before, middle, after);
  }

  template <int index, class Tuple, class E>
  auto insert_element(const Tuple & t, const E & e)
  {
    return insert_element_helper<index>
      (t, e, std::make_index_sequence<index>(),
       std::make_index_sequence<
       std::tuple_size<Tuple>::value - index>());
  }

  template <class Tuple, class E>
  auto push_back(const Tuple & t, const E & e)
  {
    return insert_element<
      std::tuple_size<Tuple>::value>(t, e);
  }

  template <class T>
  struct array_size;

  template <class T, std::size_t n>
  struct array_size<std::array<T,n>> :
    int_<n>{};

  template <class T, std::size_t n>
  struct array_size<T[n]> :
    int_<n>{};

  template <class T, std::size_t n>
  struct array_size<T(&)[n]> :
    int_<n>{};

  template <class T, std::size_t n>
  struct array_size<const T(&)[n]> :
    int_<n>{};
}

#endif
<|endoftext|>


<commit_before><commit_msg>Add Maximum Bipartite Matching<commit_after><|endoftext|>


<commit_before><commit_msg>Update ModbusSensor.cpp<commit_after><|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013-2014 Sound Metrics Corporation. All Rights Reserved.
//
// 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 "SlidingWindowFrameAssembler.h"
#include "frame_stream.h"
#include <boost/asio/buffer.hpp>
#include <myboost/scoped_guard.h>

namespace Aris {
namespace Network {

using namespace boost;
using namespace boost::asio;

namespace {
SlidingWindowFrameAssembler::Metrics
operator+(const SlidingWindowFrameAssembler::Metrics &a,
          const SlidingWindowFrameAssembler::Metrics &b) {
  auto m = a;
  m.uniqueFrameIndexCount += b.uniqueFrameIndexCount;
  m.finishedFrameCount += b.finishedFrameCount;
  m.completeFrameCount += b.completeFrameCount;
  m.skippedFrameCount += b.skippedFrameCount;
  m.totalExpectedFrameSize += b.totalExpectedFrameSize;
  m.totalReceivedFrameSize += b.totalReceivedFrameSize;
  m.totalPacketsReceived += b.totalPacketsReceived;
  m.totalPacketsAccepted += b.totalPacketsAccepted;
  m.totalPacketsIgnored += b.totalPacketsIgnored;
  m.invalidPacketCount += b.invalidPacketCount;

  return m;
}
}

SlidingWindowFrameAssembler::SlidingWindowFrameAssembler(
    boost::function<void(int, int)> sendAck,
    boost::function<void(FrameBuilder &)> onFrameFinished)
    : sendAck(sendAck), onFrameFinished(onFrameFinished), currentFrameIndex(-1),
      lastFinishedFrameIndex(-1), expectedDataOffset(0) {
  Metrics emptyMetrics = {};
  metrics = emptyMetrics;
}

void SlidingWindowFrameAssembler::ProcessPacket(const_buffer data) {

  bool acceptedPacket = false, invalidPacket = false;
  uint32_t skippedFrameCount = 0;
  scoped_guard updateMetrics([&]() {
    Metrics update = {};
    update.skippedFrameCount = skippedFrameCount;
    update.totalPacketsReceived = 1;
    update.totalPacketsAccepted = acceptedPacket ? 1 : 0;
    update.totalPacketsIgnored = acceptedPacket ? 0 : 1;
    update.invalidPacketCount = invalidPacket ? 1 : 0;
    UpdateMetrics(update);
  });

  recursive_mutex::scoped_lock lock(stateGuard);

  frame_stream::FramePart framePart;
  if (!framePart.ParseFromArray(buffer_cast<const uint8_t *>(data),
                                buffer_size(data))) {
    invalidPacket = true;
    // TODO log
    return;
  }

  const int incomingFrameIndex = framePart.frame_index();
  const int incomingDataOffset = framePart.data_offset();

  if (incomingFrameIndex > currentFrameIndex) {
    // sender moved on to the next frame
    Flush();
    skippedFrameCount = incomingFrameIndex - currentFrameIndex - 1;
    currentFrameIndex = incomingFrameIndex;
    expectedDataOffset = 0;
  } else if (incomingFrameIndex <= lastFinishedFrameIndex) {
    return; // duplicate packet from finished frame
  }

  if (!currentFrame) {
    if (incomingDataOffset == 0) {
      currentFrame = std::unique_ptr<FrameBuilder>(new FrameBuilder(
          incomingFrameIndex,
          buffer(framePart.header().c_str(), framePart.header().size()),
          buffer(framePart.data().c_str(), framePart.data().size()),
          framePart.total_data_size()));
      expectedDataOffset = framePart.data().size();
      acceptedPacket = true;
    } else {
      // Ack will go out asking for the first part of the frame to be resent.
    }
  } else {
    if (incomingDataOffset == expectedDataOffset) {
      currentFrame->AppendFrameData(
          incomingDataOffset,
          buffer(framePart.data().c_str(), framePart.data().size()));
      expectedDataOffset += framePart.data().size();
      acceptedPacket = true;
    } else {
      // Missed a part.
    }
  }

  // NOTE: we're always acking each packet for now; this should change when we
  // develop strategies for retrying packets.
  sendAck(incomingFrameIndex, expectedDataOffset);

  if (expectedDataOffset == framePart.total_data_size())
    Flush();
}

void SlidingWindowFrameAssembler::Flush() {
  recursive_mutex::scoped_lock lock(stateGuard);

  if (currentFrame) {
    std::unique_ptr<FrameBuilder> frame;
    frame.swap(currentFrame);
    assert(!currentFrame);

    UpdateMetrics(GetMetricsForFinishedFrame(*frame));

    lastFinishedFrameIndex = frame->FrameIndex();
    onFrameFinished(*frame);
  }
}

SlidingWindowFrameAssembler::Metrics SlidingWindowFrameAssembler::GetMetrics() {
  recursive_mutex::scoped_lock lock(metricsGuard);
  return metrics;
}

void SlidingWindowFrameAssembler::UpdateMetrics(const Metrics &update) {
  recursive_mutex::scoped_lock lock(metricsGuard);
  metrics = metrics + update;
}

/* static */
SlidingWindowFrameAssembler::Metrics
SlidingWindowFrameAssembler::GetMetricsForFinishedFrame(
    const FrameBuilder &frame) {
  Metrics metrics = {};
  metrics.uniqueFrameIndexCount = 1;
  metrics.finishedFrameCount = 1;
  metrics.completeFrameCount = frame.IsComplete() ? 1 : 0;
  metrics.totalExpectedFrameSize = frame.ExpectedSize();
  metrics.totalReceivedFrameSize = frame.BytesReceived();

  return metrics;
}
}
}
<commit_msg>Remove reference to myboost.<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013-2014 Sound Metrics Corporation. All Rights Reserved.
//
// 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 "SlidingWindowFrameAssembler.h"
#include "frame_stream.h"
#include <boost/asio/buffer.hpp>
#include <boost/function.hpp>

namespace {
// Execute the lambda expression at the end of the scope.
class scoped_guard : boost::noncopyable
{
    boost::function<void()> lambda;

public:
    scoped_guard(boost::function<void()> action)
        : lambda(action)
    {
    }

    ~scoped_guard()
    {
        try {
            lambda();
        }
        catch (...) {
            // Ignore.
        }
    }
};
}

namespace Aris {
namespace Network {

using namespace boost;
using namespace boost::asio;

namespace {
SlidingWindowFrameAssembler::Metrics
operator+(const SlidingWindowFrameAssembler::Metrics &a,
          const SlidingWindowFrameAssembler::Metrics &b) {
  auto m = a;
  m.uniqueFrameIndexCount += b.uniqueFrameIndexCount;
  m.finishedFrameCount += b.finishedFrameCount;
  m.completeFrameCount += b.completeFrameCount;
  m.skippedFrameCount += b.skippedFrameCount;
  m.totalExpectedFrameSize += b.totalExpectedFrameSize;
  m.totalReceivedFrameSize += b.totalReceivedFrameSize;
  m.totalPacketsReceived += b.totalPacketsReceived;
  m.totalPacketsAccepted += b.totalPacketsAccepted;
  m.totalPacketsIgnored += b.totalPacketsIgnored;
  m.invalidPacketCount += b.invalidPacketCount;

  return m;
}
}

SlidingWindowFrameAssembler::SlidingWindowFrameAssembler(
    boost::function<void(int, int)> sendAck,
    boost::function<void(FrameBuilder &)> onFrameFinished)
    : sendAck(sendAck), onFrameFinished(onFrameFinished), currentFrameIndex(-1),
      lastFinishedFrameIndex(-1), expectedDataOffset(0) {
  Metrics emptyMetrics = {};
  metrics = emptyMetrics;
}

void SlidingWindowFrameAssembler::ProcessPacket(const_buffer data) {

  bool acceptedPacket = false, invalidPacket = false;
  uint32_t skippedFrameCount = 0;
  scoped_guard updateMetrics([&]() {
    Metrics update = {};
    update.skippedFrameCount = skippedFrameCount;
    update.totalPacketsReceived = 1;
    update.totalPacketsAccepted = acceptedPacket ? 1 : 0;
    update.totalPacketsIgnored = acceptedPacket ? 0 : 1;
    update.invalidPacketCount = invalidPacket ? 1 : 0;
    UpdateMetrics(update);
  });

  recursive_mutex::scoped_lock lock(stateGuard);

  frame_stream::FramePart framePart;
  if (!framePart.ParseFromArray(buffer_cast<const uint8_t *>(data),
                                buffer_size(data))) {
    invalidPacket = true;
    // TODO log
    return;
  }

  const int incomingFrameIndex = framePart.frame_index();
  const int incomingDataOffset = framePart.data_offset();

  if (incomingFrameIndex > currentFrameIndex) {
    // sender moved on to the next frame
    Flush();
    skippedFrameCount = incomingFrameIndex - currentFrameIndex - 1;
    currentFrameIndex = incomingFrameIndex;
    expectedDataOffset = 0;
  } else if (incomingFrameIndex <= lastFinishedFrameIndex) {
    return; // duplicate packet from finished frame
  }

  if (!currentFrame) {
    if (incomingDataOffset == 0) {
      currentFrame = std::unique_ptr<FrameBuilder>(new FrameBuilder(
          incomingFrameIndex,
          buffer(framePart.header().c_str(), framePart.header().size()),
          buffer(framePart.data().c_str(), framePart.data().size()),
          framePart.total_data_size()));
      expectedDataOffset = framePart.data().size();
      acceptedPacket = true;
    } else {
      // Ack will go out asking for the first part of the frame to be resent.
    }
  } else {
    if (incomingDataOffset == expectedDataOffset) {
      currentFrame->AppendFrameData(
          incomingDataOffset,
          buffer(framePart.data().c_str(), framePart.data().size()));
      expectedDataOffset += framePart.data().size();
      acceptedPacket = true;
    } else {
      // Missed a part.
    }
  }

  // NOTE: we're always acking each packet for now; this should change when we
  // develop strategies for retrying packets.
  sendAck(incomingFrameIndex, expectedDataOffset);

  if (expectedDataOffset == framePart.total_data_size())
    Flush();
}

void SlidingWindowFrameAssembler::Flush() {
  recursive_mutex::scoped_lock lock(stateGuard);

  if (currentFrame) {
    std::unique_ptr<FrameBuilder> frame;
    frame.swap(currentFrame);
    assert(!currentFrame);

    UpdateMetrics(GetMetricsForFinishedFrame(*frame));

    lastFinishedFrameIndex = frame->FrameIndex();
    onFrameFinished(*frame);
  }
}

SlidingWindowFrameAssembler::Metrics SlidingWindowFrameAssembler::GetMetrics() {
  recursive_mutex::scoped_lock lock(metricsGuard);
  return metrics;
}

void SlidingWindowFrameAssembler::UpdateMetrics(const Metrics &update) {
  recursive_mutex::scoped_lock lock(metricsGuard);
  metrics = metrics + update;
}

/* static */
SlidingWindowFrameAssembler::Metrics
SlidingWindowFrameAssembler::GetMetricsForFinishedFrame(
    const FrameBuilder &frame) {
  Metrics metrics = {};
  metrics.uniqueFrameIndexCount = 1;
  metrics.finishedFrameCount = 1;
  metrics.completeFrameCount = frame.IsComplete() ? 1 : 0;
  metrics.totalExpectedFrameSize = frame.ExpectedSize();
  metrics.totalReceivedFrameSize = frame.BytesReceived();

  return metrics;
}
}
}
<|endoftext|>


<commit_before>// @(#)root/base:$Id$
// Author: Fons Rademakers   04/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TRefCnt                                                             //
//                                                                      //
//  Definitions for TRefCnt, base class for reference counted objects.  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TRefCnt.h"

// This definition is compiled in case nothing else is,
// in order to quiet down some fussy librarians
int gDummy_ref_cpp;

////////////////////////////////////////////////////////////////////////////////
/// Leave fRefs alone

TRefCnt::TRefCnt(EReferenceFlag)
{
}
<commit_msg>Doxygen<commit_after>// @(#)root/base:$Id$
// Author: Fons Rademakers   04/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/** \class TRefCnt
Definitions for TRefCnt, base class for reference counted objects.
*/

#include "TRefCnt.h"

// This definition is compiled in case nothing else is,
// in order to quiet down some fussy librarians
int gDummy_ref_cpp;

////////////////////////////////////////////////////////////////////////////////
/// Leave fRefs alone

TRefCnt::TRefCnt(EReferenceFlag)
{
}
<|endoftext|>


<commit_before>/// @file
/// @author uentity
/// @date 23.08.2016
/// @brief BlueSky kernel implementation
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#include <bs/kernel.h>
#include "kernel_impl.h"

namespace blue_sky {

kernel::kernel() : pimpl_(new kernel_impl) {}

kernel::~kernel() {}

void kernel::init() {}

void kernel::cleanup() {}

spdlog::logger& kernel::get_log(const char* name) {
	return kernel_impl::get_log(name);
}

int kernel::load_plugin(const std::string& fname, bool init_py_subsyst) {
	return pimpl_->load_plugin(fname, init_py_subsyst);
}

int kernel::load_plugins(void* py_root_module) {
	return pimpl_->load_plugins(py_root_module);
}

void kernel::unload_plugin(const plugin_descriptor& pd) {
	pimpl_->unload_plugin(pd);
}

void kernel::unload_plugins() {
	pimpl_->unload_plugins();
}

const type_descriptor& kernel::demand_type(const type_descriptor& obj_type) {
	return pimpl_->demand_type({obj_type}).td();
}

bool kernel::register_type(const type_descriptor& td, const plugin_descriptor* pd) {
	return pimpl_->register_type(td, pd);
}

bool kernel::register_type(const type_descriptor& td, const std::string& plug_name) {
	return pimpl_->register_type(td, plug_name);
}

kernel::types_enum kernel::registered_types() const {
	types_enum res;
	for(const auto& elem : pimpl_->types_) {
		res.emplace_back(elem);
	}
	return res;
}

kernel::types_enum kernel::plugin_types(const plugin_descriptor& pd) const {
	return plugin_types(pd.name);
}

kernel::types_enum kernel::plugin_types(const std::string& plugin_name) const {
	using plug_name_key = detail::kernel_plugins_subsyst::plug_name_key;

	types_enum res;
	auto plt = pimpl_->types_.get< plug_name_key >().equal_range(plugin_name);
	std::copy(plt.first, plt.second, std::back_inserter(res));
	return res;
}

kernel::plugins_enum kernel::loaded_plugins() const {
	plugins_enum res;
	for(const auto& plug_ptr : pimpl_->loaded_plugins_)
		res.emplace_back(plug_ptr.first);
	//res.emplace_back(&pimpl_->kernel_pd_);
	//res.emplace_back(&pimpl_->runtime_pd_);
	return res;
}

int kernel::register_instance(const sp_obj& obj) {
	return pimpl_->register_instance(obj);
}

int kernel::free_instance(const sp_obj& obj) {
	return pimpl_->free_instance(obj);
}

kernel::instances_enum kernel::instances(const BS_TYPE_INFO& ti) const {
	return pimpl_->instances(ti);
}

type_tuple kernel::find_type(const std::string& type_name) const {
	return pimpl_->find_type(type_name);
}

str_any_array& kernel::pert_str_any_array(const type_descriptor& master) {
	return pimpl_->pert_str_any_array(master);
}

idx_any_array& kernel::pert_idx_any_array(const type_descriptor& master) {
	return pimpl_->pert_idx_any_array(master);
}

} /* namespace blue_sky */

<commit_msg>kernel: add minimal last_error() implementation<commit_after>/// @file
/// @author uentity
/// @date 23.08.2016
/// @brief BlueSky kernel implementation
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#include <bs/kernel.h>
#include <bs/misc.h>
#include "kernel_impl.h"

namespace blue_sky {

kernel::kernel() : pimpl_(new kernel_impl) {}

kernel::~kernel() {}

void kernel::init() {}

void kernel::cleanup() {}

spdlog::logger& kernel::get_log(const char* name) {
	return kernel_impl::get_log(name);
}

int kernel::load_plugin(const std::string& fname, bool init_py_subsyst) {
	return pimpl_->load_plugin(fname, init_py_subsyst);
}

int kernel::load_plugins(void* py_root_module) {
	return pimpl_->load_plugins(py_root_module);
}

void kernel::unload_plugin(const plugin_descriptor& pd) {
	pimpl_->unload_plugin(pd);
}

void kernel::unload_plugins() {
	pimpl_->unload_plugins();
}

const type_descriptor& kernel::demand_type(const type_descriptor& obj_type) {
	return pimpl_->demand_type({obj_type}).td();
}

bool kernel::register_type(const type_descriptor& td, const plugin_descriptor* pd) {
	return pimpl_->register_type(td, pd);
}

bool kernel::register_type(const type_descriptor& td, const std::string& plug_name) {
	return pimpl_->register_type(td, plug_name);
}

kernel::types_enum kernel::registered_types() const {
	types_enum res;
	for(const auto& elem : pimpl_->types_) {
		res.emplace_back(elem);
	}
	return res;
}

kernel::types_enum kernel::plugin_types(const plugin_descriptor& pd) const {
	return plugin_types(pd.name);
}

kernel::types_enum kernel::plugin_types(const std::string& plugin_name) const {
	using plug_name_key = detail::kernel_plugins_subsyst::plug_name_key;

	types_enum res;
	auto plt = pimpl_->types_.get< plug_name_key >().equal_range(plugin_name);
	std::copy(plt.first, plt.second, std::back_inserter(res));
	return res;
}

kernel::plugins_enum kernel::loaded_plugins() const {
	plugins_enum res;
	for(const auto& plug_ptr : pimpl_->loaded_plugins_)
		res.emplace_back(plug_ptr.first);
	//res.emplace_back(&pimpl_->kernel_pd_);
	//res.emplace_back(&pimpl_->runtime_pd_);
	return res;
}

int kernel::register_instance(const sp_obj& obj) {
	return pimpl_->register_instance(obj);
}

int kernel::free_instance(const sp_obj& obj) {
	return pimpl_->free_instance(obj);
}

kernel::instances_enum kernel::instances(const BS_TYPE_INFO& ti) const {
	return pimpl_->instances(ti);
}

type_tuple kernel::find_type(const std::string& type_name) const {
	return pimpl_->find_type(type_name);
}

str_any_array& kernel::pert_str_any_array(const type_descriptor& master) {
	return pimpl_->pert_str_any_array(master);
}

idx_any_array& kernel::pert_idx_any_array(const type_descriptor& master) {
	return pimpl_->pert_idx_any_array(master);
}

std::string kernel::last_error() const {
	return last_system_message();
}

} /* namespace blue_sky */

<|endoftext|>


<commit_before>// Author: Wim Lavrijsen   November 2010

// Bindings
#include "PyROOT.h"
#include "TPyFitFunction.h"
#include "ObjectProxy.h"
#include "MethodProxy.h"
#include "PyBufferFactory.h"

// Standard
#include <stdexcept>

//______________________________________________________________________________
//                       Python wrapper for Fit functions
//                       ================================
//

//- data ---------------------------------------------------------------------
ClassImp(TPyMultiGenFunction)
ClassImp(TPyMultiGradFunction)

//- helper function ----------------------------------------------------------
static PyObject* DispatchCall( PyObject* pyself, const char* method,
   PyObject* arg1 = NULL, PyObject* arg2 = NULL, PyObject* arg3 = NULL )
{
// Forward <method> to python (need to refactor this with TPySelector).
   if ( ! pyself || pyself == Py_None ) {
      Py_INCREF( Py_None );
      return Py_None;
   }

   PyObject* result = 0;

// get the named method and check for python side overload by not accepting the
// binding's methodproxy
   PyObject* pymethod = PyObject_GetAttrString( (PyObject*)pyself, const_cast< char* >( method ) );
   if ( ! PyROOT::MethodProxy_CheckExact( pymethod ) ) {
      result = PyObject_CallFunctionObjArgs( pymethod, arg1, arg2, arg3, NULL );
   } else {
   // means the method has not been overridden ... simply accept its not there
      result = 0;
      PyErr_Format( PyExc_AttributeError,
         "method %s needs implementing in derived class", const_cast< char* >( method ) );
   }

   Py_XDECREF( pymethod );

   return result;
}

//- constructors/destructor --------------------------------------------------
TPyMultiGenFunction::TPyMultiGenFunction( PyObject* self ) : fPySelf( 0 )
{
// Construct a TPyMultiGenFunction derived with <self> as the underlying
   if ( self ) {
   // steal reference as this is us, as seen from python
      fPySelf = self;
   } else {
      Py_INCREF( Py_None );        // using None allows clearer diagnostics
      fPySelf = Py_None;
   }
}

//____________________________________________________________________________
TPyMultiGenFunction::~TPyMultiGenFunction()
{
// Destructor. Only deref if still holding on to Py_None (circular otherwise).
   if ( fPySelf == Py_None ) {
      Py_DECREF( fPySelf );
   }
}

//- public functions ---------------------------------------------------------
unsigned int TPyMultiGenFunction::NDim() const
{
// Simply forward the call to python self.
   PyObject* pyresult = DispatchCall( fPySelf, "NDim" );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGenFunction::NDim" );
   }

   unsigned int cppresult = (unsigned int)PyLong_AsLong( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//____________________________________________________________________________
double TPyMultiGenFunction::DoEval( const double* x ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGenFunction::DoEval" );
   }

   double cppresult = (double)PyFloat_AsDouble( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//- constructors/destructor --------------------------------------------------
TPyMultiGradFunction::TPyMultiGradFunction( PyObject* self )
{
// Construct a TPyMultiGradFunction derived with <self> as the underlying
   if ( self ) {
   // steal reference as this is us, as seen from python
      fPySelf = self;
   } else {
      Py_INCREF( Py_None );        // using None allows clearer diagnostics
      fPySelf = Py_None;
   }
}

//____________________________________________________________________________
TPyMultiGradFunction::~TPyMultiGradFunction()
{
// Destructor. Only deref if still holding on to Py_None (circular otherwise).
   if ( fPySelf == Py_None ) {
      Py_DECREF( fPySelf );
   }
}

//- public functions ---------------------------------------------------------
unsigned int TPyMultiGradFunction::NDim() const
{
// Simply forward the call to python self.
   PyObject* pyresult = DispatchCall( fPySelf, "NDim" );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::NDim" );
   }

   unsigned int cppresult = (unsigned int)PyLong_AsLong( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//____________________________________________________________________________
double TPyMultiGradFunction::DoEval( const double* x ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::DoEval" );
   }

   double cppresult = (double)PyFloat_AsDouble( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//____________________________________________________________________________
void TPyMultiGradFunction::Gradient( const double* x, double* grad ) const {
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* gbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)grad );
   PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf, gbuf );
   Py_DECREF( gbuf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::Gradient" );
   }

   Py_DECREF( pyresult );
}

//____________________________________________________________________________
void TPyMultiGradFunction::FdF( const double* x, double& f, double* df ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pyf = PyList_New( 1 );
   PyList_SetItem( pyf, 0, PyFloat_FromDouble( f ) );
   PyObject* dfbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)df );

   PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf, pyf, dfbuf );
   f = PyFloat_AsDouble( PyList_GetItem( pyf, 0 ) );

   Py_DECREF( dfbuf );
   Py_DECREF( pyf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::FdF" );
   }

   Py_DECREF( pyresult );
}

//____________________________________________________________________________
double TPyMultiGradFunction::DoDerivative( const double * x, unsigned int icoord ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pycoord = PyLong_FromLong( icoord );

   PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf, pycoord );
   Py_DECREF( pycoord );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::DoDerivative" );
   }

   double cppresult = (double)PyFloat_AsDouble( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

<commit_msg>fix typos in function to be called<commit_after>// Author: Wim Lavrijsen   November 2010

// Bindings
#include "PyROOT.h"
#include "TPyFitFunction.h"
#include "ObjectProxy.h"
#include "MethodProxy.h"
#include "PyBufferFactory.h"

// Standard
#include <stdexcept>

//______________________________________________________________________________
//                       Python wrapper for Fit functions
//                       ================================
//

//- data ---------------------------------------------------------------------
ClassImp(TPyMultiGenFunction)
ClassImp(TPyMultiGradFunction)

//- helper function ----------------------------------------------------------
static PyObject* DispatchCall( PyObject* pyself, const char* method,
   PyObject* arg1 = NULL, PyObject* arg2 = NULL, PyObject* arg3 = NULL )
{
// Forward <method> to python (need to refactor this with TPySelector).
   if ( ! pyself || pyself == Py_None ) {
      Py_INCREF( Py_None );
      return Py_None;
   }

   PyObject* result = 0;

// get the named method and check for python side overload by not accepting the
// binding's methodproxy
   PyObject* pymethod = PyObject_GetAttrString( (PyObject*)pyself, const_cast< char* >( method ) );
   if ( ! PyROOT::MethodProxy_CheckExact( pymethod ) ) {
      result = PyObject_CallFunctionObjArgs( pymethod, arg1, arg2, arg3, NULL );
   } else {
   // means the method has not been overridden ... simply accept its not there
      result = 0;
      PyErr_Format( PyExc_AttributeError,
         "method %s needs implementing in derived class", const_cast< char* >( method ) );
   }

   Py_XDECREF( pymethod );

   return result;
}

//- constructors/destructor --------------------------------------------------
TPyMultiGenFunction::TPyMultiGenFunction( PyObject* self ) : fPySelf( 0 )
{
// Construct a TPyMultiGenFunction derived with <self> as the underlying
   if ( self ) {
   // steal reference as this is us, as seen from python
      fPySelf = self;
   } else {
      Py_INCREF( Py_None );        // using None allows clearer diagnostics
      fPySelf = Py_None;
   }
}

//____________________________________________________________________________
TPyMultiGenFunction::~TPyMultiGenFunction()
{
// Destructor. Only deref if still holding on to Py_None (circular otherwise).
   if ( fPySelf == Py_None ) {
      Py_DECREF( fPySelf );
   }
}

//- public functions ---------------------------------------------------------
unsigned int TPyMultiGenFunction::NDim() const
{
// Simply forward the call to python self.
   PyObject* pyresult = DispatchCall( fPySelf, "NDim" );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGenFunction::NDim" );
   }

   unsigned int cppresult = (unsigned int)PyLong_AsLong( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//____________________________________________________________________________
double TPyMultiGenFunction::DoEval( const double* x ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGenFunction::DoEval" );
   }

   double cppresult = (double)PyFloat_AsDouble( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//- constructors/destructor --------------------------------------------------
TPyMultiGradFunction::TPyMultiGradFunction( PyObject* self )
{
// Construct a TPyMultiGradFunction derived with <self> as the underlying
   if ( self ) {
   // steal reference as this is us, as seen from python
      fPySelf = self;
   } else {
      Py_INCREF( Py_None );        // using None allows clearer diagnostics
      fPySelf = Py_None;
   }
}

//____________________________________________________________________________
TPyMultiGradFunction::~TPyMultiGradFunction()
{
// Destructor. Only deref if still holding on to Py_None (circular otherwise).
   if ( fPySelf == Py_None ) {
      Py_DECREF( fPySelf );
   }
}

//- public functions ---------------------------------------------------------
unsigned int TPyMultiGradFunction::NDim() const
{
// Simply forward the call to python self.
   PyObject* pyresult = DispatchCall( fPySelf, "NDim" );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::NDim" );
   }

   unsigned int cppresult = (unsigned int)PyLong_AsLong( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//____________________________________________________________________________
double TPyMultiGradFunction::DoEval( const double* x ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::DoEval" );
   }

   double cppresult = (double)PyFloat_AsDouble( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

//____________________________________________________________________________
void TPyMultiGradFunction::Gradient( const double* x, double* grad ) const {
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* gbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)grad );
   PyObject* pyresult = DispatchCall( fPySelf, "Gradient", xbuf, gbuf );
   Py_DECREF( gbuf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::Gradient" );
   }

   Py_DECREF( pyresult );
}

//____________________________________________________________________________
void TPyMultiGradFunction::FdF( const double* x, double& f, double* df ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pyf = PyList_New( 1 );
   PyList_SetItem( pyf, 0, PyFloat_FromDouble( f ) );
   PyObject* dfbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)df );

   PyObject* pyresult = DispatchCall( fPySelf, "FdF", xbuf, pyf, dfbuf );
   f = PyFloat_AsDouble( PyList_GetItem( pyf, 0 ) );

   Py_DECREF( dfbuf );
   Py_DECREF( pyf );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::FdF" );
   }

   Py_DECREF( pyresult );
}

//____________________________________________________________________________
double TPyMultiGradFunction::DoDerivative( const double * x, unsigned int icoord ) const
{
// Simply forward the call to python self.
   PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
   PyObject* pycoord = PyLong_FromLong( icoord );

   PyObject* pyresult = DispatchCall( fPySelf, "DoDerivative", xbuf, pycoord );
   Py_DECREF( pycoord );
   Py_DECREF( xbuf );

   if ( ! pyresult ) {
      PyErr_Print();
      throw std::runtime_error( "Failure in TPyMultiGradFunction::DoDerivative" );
   }

   double cppresult = (double)PyFloat_AsDouble( pyresult );
   Py_XDECREF( pyresult );

   return cppresult;
}

<|endoftext|>