<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/
#include <osg/BoundingSphere>
#include <osg/BoundingBox>

using namespace osg;

void BoundingSphere::expandBy(const Vec3& v)
{
    if (valid())
    {
        Vec3 dv = v-_center;
        float r = dv.length();
        if (r>_radius)
        {
            float dr = (r-_radius)*0.5f;
            _center += dv*(dr/r);
            _radius += dr;
        } // else do nothing as vertex is within sphere.
    }
    else
    {
        _center = v;
        _radius = 0.0f;
    }
}

void BoundingSphere::expandRadiusBy(const Vec3& v)
{
    if (valid())
    {
        float r = (v-_center).length();
        if (r>_radius) _radius = r;
        // else do nothing as vertex is within sphere.
    }
    else
    {
        _center = v;
        _radius = 0.0f;
    }
}

void BoundingSphere::expandBy(const BoundingSphere& sh)
{
    if (sh.valid())
    {
        if (valid())
        {
            Vec3 dv = sh._center-_center;
            float dv_len = dv.length();
            if (dv_len+sh._radius>_radius)
            {
                Vec3 e1 = _center-(dv*(_radius/dv_len));
                Vec3 e2 = sh._center+(dv*(sh._radius/dv_len));
                _center = (e1+e2)*0.5f;
                _radius = (e2-_center).length();

            }                    // else do nothing as vertex is within sphere.
        }
        else
        {
            _center = sh._center;
            _radius = sh._radius;
        }
    }
}

void BoundingSphere::expandRadiusBy(const BoundingSphere& sh)
{
    if (sh.valid())
    {
        if (valid())
        {
            float r = (sh._center-_center).length()+sh._radius;
            if (r>_radius) _radius = r;
            // else do nothing as vertex is within sphere.
        }
        else
        {
            _center = sh._center;
            _radius = sh._radius;
        }
    }
}

void BoundingSphere::expandBy(const BoundingBox& bb)
{
    if (bb.valid())
    {
        if (valid())
        {
            BoundingBox newbb(bb);

            for(unsigned int c=0;c<8;++c)
            {
                Vec3 v = bb.corner(c)-_center; // get the direction vector from corner
                v.normalize(); // normalise it.
                v *= -_radius; // move the vector in the opposite direction distance radius.
                v += _center; // move to absolute position.
                newbb.expandBy(v); // add it into the new bounding box.
            }

            _center = newbb.center();
            _radius = newbb.radius();

        }
        else
        {
            _center = bb.center();
            _radius = bb.radius();
        }
    }
}

void BoundingSphere::expandRadiusBy(const BoundingBox& bb)
{
    if (bb.valid())
    {
        if (valid())
        {
            for(unsigned int c=0;c<8;++c)
            {
                expandRadiusBy(bb.corner(c));
            }
        }
        else
        {
            _center = bb.center();
            _radius = bb.radius();
        }
    }
}
<commit_msg>From Brad Christiansen, fix expandBy(const BoundingSphere&) method to properly handle the instance of when the two bounding sphere's have a coincident center.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/
#include <osg/BoundingSphere>
#include <osg/BoundingBox>

using namespace osg;

void BoundingSphere::expandBy(const Vec3& v)
{
    if (valid())
    {
        Vec3 dv = v-_center;
        float r = dv.length();
        if (r>_radius)
        {
            float dr = (r-_radius)*0.5f;
            _center += dv*(dr/r);
            _radius += dr;
        } // else do nothing as vertex is within sphere.
    }
    else
    {
        _center = v;
        _radius = 0.0f;
    }
}

void BoundingSphere::expandRadiusBy(const Vec3& v)
{
    if (valid())
    {
        float r = (v-_center).length();
        if (r>_radius) _radius = r;
        // else do nothing as vertex is within sphere.
    }
    else
    {
        _center = v;
        _radius = 0.0f;
    }
}

void BoundingSphere::expandBy(const BoundingSphere& sh)
{
    if (sh.valid())
    {
        if (valid())
        {
            Vec3 dv = sh._center-_center;
            float dv_len = dv.length();

            if(dv_len == 0 && sh._radius>_radius) {
               _radius = sh._radius;
            }
            else if (dv_len+sh._radius>_radius)
            {
                Vec3 e1 = _center-(dv*(_radius/dv_len));
                Vec3 e2 = sh._center+(dv*(sh._radius/dv_len));
                _center = (e1+e2)*0.5f;
                _radius = (e2-_center).length();

            }                    // else do nothing as vertex is within sphere.
        }
        else
        {
            _center = sh._center;
            _radius = sh._radius;
        }
    }
}

void BoundingSphere::expandRadiusBy(const BoundingSphere& sh)
{
    if (sh.valid())
    {
        if (valid())
        {
            float r = (sh._center-_center).length()+sh._radius;
            if (r>_radius) _radius = r;
            // else do nothing as vertex is within sphere.
        }
        else
        {
            _center = sh._center;
            _radius = sh._radius;
        }
    }
}

void BoundingSphere::expandBy(const BoundingBox& bb)
{
    if (bb.valid())
    {
        if (valid())
        {
            BoundingBox newbb(bb);

            for(unsigned int c=0;c<8;++c)
            {
                Vec3 v = bb.corner(c)-_center; // get the direction vector from corner
                v.normalize(); // normalise it.
                v *= -_radius; // move the vector in the opposite direction distance radius.
                v += _center; // move to absolute position.
                newbb.expandBy(v); // add it into the new bounding box.
            }

            _center = newbb.center();
            _radius = newbb.radius();

        }
        else
        {
            _center = bb.center();
            _radius = bb.radius();
        }
    }
}

void BoundingSphere::expandRadiusBy(const BoundingBox& bb)
{
    if (bb.valid())
    {
        if (valid())
        {
            for(unsigned int c=0;c<8;++c)
            {
                expandRadiusBy(bb.corner(c));
            }
        }
        else
        {
            _center = bb.center();
            _radius = bb.radius();
        }
    }
}
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2015 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "ucb1.hpp"

#include <string>
#include <vector>
#include <cfloat>
#include "../common/exception.hpp"
#include "../framework/packer.hpp"
#include "../common/version.hpp"

namespace jubatus {
namespace core {
namespace bandit {

ucb1::ucb1(bool assume_unrewarded)
    : s_(assume_unrewarded) {
}

std::string ucb1::select_arm(const std::string& player_id) {
  const std::vector<std::string>& arms = s_.get_arm_ids();
  if (arms.empty()) {
    throw JUBATUS_EXCEPTION(
        common::exception::runtime_error("arm is not registered"));
  }

  int total_trial = 0;
  for (size_t i = 0; i < arms.size(); ++i) {
    const arm_info& a = s_.get_arm_info(player_id, arms[i]);
    if (a.trial_count == 0) {
      return arms[i];
    }
    total_trial += a.trial_count;
  }
  double log_total_trial = std::log(total_trial);

  double score_max = -DBL_MAX;
  std::string result;
  for (size_t i = 0; i < arms.size(); ++i) {
    const arm_info& a = s_.get_arm_info(player_id, arms[i]);
    double exp = a.weight / a.trial_count;
    double score = exp + std::sqrt(2 * log_total_trial / a.trial_count);
    if (score > score_max) {
      score_max = score;
      result = arms[i];
    }
  }
  s_.notify_selected(player_id, result);
  return result;
}

bool ucb1::register_arm(const std::string& arm_id) {
  return s_.register_arm(arm_id);
}
bool ucb1::delete_arm(const std::string& arm_id) {
  return s_.delete_arm(arm_id);
}

bool ucb1::register_reward(const std::string& player_id,
                                     const std::string& arm_id,
                                     double reward) {
  return s_.register_reward(player_id, arm_id, reward);
}

arm_info_map ucb1::get_arm_info(const std::string& player_id) const {
  return s_.get_arm_info_map(player_id);
}

bool ucb1::reset(const std::string& player_id) {
  return s_.reset(player_id);
}
void ucb1::clear() {
  s_.clear();
}

void ucb1::pack(framework::packer& pk) const {
  pk.pack(s_);
}
void ucb1::unpack(msgpack::object o) {
  o.convert(&s_);
}

void ucb1::get_diff(diff_t& diff) const {
  s_.get_diff(diff);
}
bool ucb1::put_diff(const diff_t& diff) {
  return s_.put_diff(diff);
}
void ucb1::mix(const diff_t& lhs, diff_t& rhs) const {
  s_.mix(lhs, rhs);
}
storage::version ucb1::get_version() const {
  return storage::version();
}

}  // namespace bandit
}  // namespace core
}  // namespace jubatus
<commit_msg>fix ucb1 trial_count increment<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2015 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "ucb1.hpp"

#include <string>
#include <vector>
#include <cfloat>
#include "../common/exception.hpp"
#include "../framework/packer.hpp"
#include "../common/version.hpp"

namespace jubatus {
namespace core {
namespace bandit {

ucb1::ucb1(bool assume_unrewarded)
    : s_(assume_unrewarded) {
}

std::string ucb1::select_arm(const std::string& player_id) {
  const std::vector<std::string>& arms = s_.get_arm_ids();
  if (arms.empty()) {
    throw JUBATUS_EXCEPTION(
        common::exception::runtime_error("arm is not registered"));
  }

  int total_trial = 0;
  for (size_t i = 0; i < arms.size(); ++i) {
    const arm_info& a = s_.get_arm_info(player_id, arms[i]);
    if (a.trial_count == 0) {
      s_.notify_selected(player_id, arms[i]);
      return arms[i];
    }
    total_trial += a.trial_count;
  }
  double log_total_trial = std::log(total_trial);

  double score_max = -DBL_MAX;
  std::string result;
  for (size_t i = 0; i < arms.size(); ++i) {
    const arm_info& a = s_.get_arm_info(player_id, arms[i]);
    double exp = a.weight / a.trial_count;
    double score = exp + std::sqrt(2 * log_total_trial / a.trial_count);
    if (score > score_max) {
      score_max = score;
      result = arms[i];
    }
  }
  s_.notify_selected(player_id, result);
  return result;
}

bool ucb1::register_arm(const std::string& arm_id) {
  return s_.register_arm(arm_id);
}
bool ucb1::delete_arm(const std::string& arm_id) {
  return s_.delete_arm(arm_id);
}

bool ucb1::register_reward(const std::string& player_id,
                                     const std::string& arm_id,
                                     double reward) {
  return s_.register_reward(player_id, arm_id, reward);
}

arm_info_map ucb1::get_arm_info(const std::string& player_id) const {
  return s_.get_arm_info_map(player_id);
}

bool ucb1::reset(const std::string& player_id) {
  return s_.reset(player_id);
}
void ucb1::clear() {
  s_.clear();
}

void ucb1::pack(framework::packer& pk) const {
  pk.pack(s_);
}
void ucb1::unpack(msgpack::object o) {
  o.convert(&s_);
}

void ucb1::get_diff(diff_t& diff) const {
  s_.get_diff(diff);
}
bool ucb1::put_diff(const diff_t& diff) {
  return s_.put_diff(diff);
}
void ucb1::mix(const diff_t& lhs, diff_t& rhs) const {
  s_.mix(lhs, rhs);
}
storage::version ucb1::get_version() const {
  return storage::version();
}

}  // namespace bandit
}  // namespace core
}  // namespace jubatus
<|endoftext|>


<commit_before>#ifndef INCLUDE_AL_GRAPHICS_TEXTURE_HPP
#define INCLUDE_AL_GRAPHICS_TEXTURE_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2006-2008. The Regents of the University of California (REGENTS).
	All Rights Reserved.

	Permission to use, copy, modify, distribute, and distribute modified versions
	of this software and its documentation without fee and without a signed
	licensing agreement, is hereby granted, provided that the above copyright
	notice, the list of contributors, this paragraph and the following two paragraphs
	appear in all copies, modifications, and distributions.

	IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
	SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
	OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
	BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

	REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
	PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
	HEREUNDER IS PROVIDED "AS IS". REGENTS HAS  NO OBLIGATION TO PROVIDE
	MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

	File description:
	Helper object for Graphics Textures

	File author(s):
	Wesley Smith, 2010, wesley.hoke@gmail.com
	Lance Putnam, 2010, putnam.lance@gmail.com
	Graham Wakefield, 2010, grrrwaaa@gmail.com
*/

#include "allocore/types/al_Array.hpp"
#include "allocore/types/al_Color.hpp"

#include "allocore/graphics/al_Graphics.hpp"
#include "allocore/graphics/al_GPUObject.hpp"

namespace al{

/**
	A simple wrapper around OpenGL Texture
*/
class Texture : public GPUObject {
public:

	typedef Graphics::Format Format;
	typedef Graphics::DataType DataType;

	enum Target {
		TEXTURE_1D				= GL_TEXTURE_1D,
		TEXTURE_2D				= GL_TEXTURE_2D,
		TEXTURE_3D				= GL_TEXTURE_3D
	};

	enum Wrap {
		CLAMP					= GL_CLAMP,
		CLAMP_TO_BORDER			= GL_CLAMP_TO_BORDER,
		CLAMP_TO_EDGE			= GL_CLAMP_TO_EDGE,
		MIRRORED_REPEAT			= GL_MIRRORED_REPEAT,
		REPEAT					= GL_REPEAT
	};

	enum Filter {
		NEAREST					= GL_NEAREST,
		LINEAR					= GL_LINEAR,
		NEAREST_MIPMAP_NEAREST	= GL_NEAREST_MIPMAP_NEAREST,
		LINEAR_MIPMAP_NEAREST	= GL_LINEAR_MIPMAP_NEAREST,
		NEAREST_MIPMAP_LINEAR	= GL_NEAREST_MIPMAP_LINEAR,
		LINEAR_MIPMAP_LINEAR	= GL_LINEAR_MIPMAP_LINEAR,
	};

	/**
		Construct a 2D Texture object.
	*/
	Texture(unsigned width=512, unsigned height=512, Graphics::Format format=Graphics::RGBA, Graphics::DataType type=Graphics::UBYTE);

	/**
		Construct a 3D Texture object.
	*/
	Texture(unsigned width, unsigned height, unsigned depth, Graphics::Format format=Graphics::RGBA, Graphics::DataType type=Graphics::UBYTE);

	virtual ~Texture(){}

	Format format() const { return mFormat; }
	Target target() const { return mTarget; }
	DataType type() const { return mType; }

	unsigned width() const { return mWidth; }
	unsigned height() const { return mHeight; }
	unsigned depth() const { return mDepth; }

	Filter filter() const { return mFilter; }

	/// Return number of components per pixel
	unsigned numComponents() const { return Graphics::numComponents(format()); }

	/// Return total number of elements (components x width x height x depth)
	unsigned numElems() const {
		return numPixels() * numComponents();
	}

	unsigned numPixels() const {
		return width() * (height()?height():1) * (depth()?depth():1);
	}

	Texture& format(Format v){ return update(v, mFormat, mPixelsUpdated); }
	Texture& target(Target v){ return update(v, mTarget, mPixelsUpdated); }
	Texture& type(DataType v){ return update(v, mType  , mPixelsUpdated); }

	Texture& width (unsigned v){ return update(v, mWidth, mPixelsUpdated); }
	Texture& height(unsigned v){ return update(v, mHeight,mPixelsUpdated); }
	Texture& depth (unsigned v){ return update(v, mDepth ,mPixelsUpdated); }

	Texture& filter(Filter v){ return update(v, mFilter, mParamsUpdated); }
	Texture& wrap(Wrap v){ return wrap(v,v,v); }
	Texture& wrap(Wrap S, Wrap T){ return wrap(S,T,mWrapR); }
	Texture& wrap(Wrap S, Wrap T, Wrap R);

	/// bind the texture (to a multitexture unit)
	void bind(int unit = 0);
	/// unbind the texture (from a multitexture unit)
	void unbind(int unit = 0);

	/// render the texture onto a quad on the XY plane
	void quad(Graphics& gl, double w=1, double h=1, double x=0, double y=0);

	/// return reference to the internal CPU-side cache
	/// DO NOT MODIFY THE LAYOUT OR DIMENSIONS OF THIS ARRAY
	Array& array() { return mArray; }

	/// Get raw pointer to client-side pixel data
	template<class T> T * data(){ return (T*)(data()); }
	char * data(){ return array().data.ptr; }

	/// Flags resubmission of pixel data upon next bind
	Texture& updatePixels(){ mPixelsUpdated=true; return *this; }

	/// Submit the texture using an Array as source
	/// NOTE: the graphics context (e.g. Window) must have been created
	/// if reconfigure is true,
	/// it will attempt to derive size & layout from the array
	void submit(const Array& src, bool reconfigure=false);

	/// Resize texture data on GPU and copy over pixels
	/// NOTE: the graphics context (e.g. Window) must have been created
	/// If pixels is NULL, then the only effect is to resize the texture
	/// remotely.
	void submit(const void * pixels, uint32_t align=4);

	/// just submit the existing data
	void submit() { dirty(); }

	/// allocate the internal Array for a CPU-side cache, copying from src
	void allocate(const Array& src, bool reconfigure=true);
	/// allocate memory for a CPU copy
	/// reconfigures the internal array
	void allocate(unsigned align=1);

	void deallocate();

	/// debug printing
	void print();

	/// mark pixels as dirtied (e.g. if modified array contents)
	/// to ensure they get submitted on the next bind():
	void dirty() { mPixelsUpdated = true; }

protected:
//	GLint mLevel;	// TODO: on a rainy day...
//	GLint mBorder;
	Target mTarget;				// TEXTURE_1D, TEXTURE_2D, etc.
	Format mFormat;				// RGBA, ALPHA, etc.
	DataType mType;				// UBYTE, FLOAT, etc.
	Wrap mWrapS, mWrapT, mWrapR;
	Filter mFilter;
	unsigned mWidth, mHeight, mDepth;
	GLint mUnpack;

	void * mPixels;				// pointer to client-side pixel data (0 if none)
	Array mArray;				// Array representation of client-side pixel data
//	void * mBuffer;				// internally allocated pixel buffer
	bool mParamsUpdated;
	bool mPixelsUpdated;

	virtual void onCreate(){
		//printf("Texture onCreate\n");
		glGenTextures(1, (GLuint *)&mID);
		sendParams();
		sendPixels();
		Graphics::error("creating texture");
	}

	virtual void onDestroy(){
		glDeleteTextures(1, (GLuint *)&mID);
	}

	/// ensures that the internal Array format matches the texture format
	void resetArray(unsigned align);

	void sendParams(bool force=true){
		if(mParamsUpdated || force){
			glBindTexture(target(), id());
			glTexParameterf(target(), GL_TEXTURE_MAG_FILTER, filter());
			glTexParameterf(target(), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
			glTexParameterf(target(), GL_TEXTURE_WRAP_S, mWrapS);
			glTexParameterf(target(), GL_TEXTURE_WRAP_T, mWrapT);
			glTexParameterf(target(), GL_TEXTURE_WRAP_R, mWrapR);
			glTexParameteri(target(), GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap
			glBindTexture(target(), 0);
			mParamsUpdated = false;
		}
	}

	void sendPixels(bool force=true){
		if(mPixelsUpdated || force){
			submit(mPixels);
			mPixelsUpdated = false;
		}
	}

	/// determines target (e.g. GL_TEXTURE_2D) from the dimensions
	void determineTarget();

	// Pattern for setting a variable that when changed sets a notification flag
	template<class T>
	Texture& update(const T& v, T& var, bool& flag){
		if(v!=var){ var=v; flag=true; }
		return *this;
	}
};

inline void Texture :: bind(int unit) {
	// ensure it is created:
	validate();
	sendParams(false);
	sendPixels(false);

	// multitexturing:
	glActiveTextureARB(GL_TEXTURE0_ARB + unit);

	// bind:
	glEnable(target());
	glBindTexture(target(), id());

	Graphics::error("binding texture");
}

inline void Texture :: unbind(int unit) {
	// multitexturing:
	glActiveTextureARB(GL_TEXTURE0_ARB + unit);
	glBindTexture(target(), 0);
	glDisable(target());
}

inline Texture& Texture :: wrap(Wrap S, Wrap T, Wrap R){
	if(S!=mWrapS || T!=mWrapT || R!=mWrapR){
		mWrapS = S; mWrapT = T; mWrapR = R;
		mParamsUpdated = true;
	}
	return *this;
}

} // al::

#endif
<commit_msg>add resize methods<commit_after>#ifndef INCLUDE_AL_GRAPHICS_TEXTURE_HPP
#define INCLUDE_AL_GRAPHICS_TEXTURE_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2006-2008. The Regents of the University of California (REGENTS).
	All Rights Reserved.

	Permission to use, copy, modify, distribute, and distribute modified versions
	of this software and its documentation without fee and without a signed
	licensing agreement, is hereby granted, provided that the above copyright
	notice, the list of contributors, this paragraph and the following two paragraphs
	appear in all copies, modifications, and distributions.

	IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
	SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
	OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
	BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

	REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
	PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
	HEREUNDER IS PROVIDED "AS IS". REGENTS HAS  NO OBLIGATION TO PROVIDE
	MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

	File description:
	Helper object for Graphics Textures

	File author(s):
	Wesley Smith, 2010, wesley.hoke@gmail.com
	Lance Putnam, 2010, putnam.lance@gmail.com
	Graham Wakefield, 2010, grrrwaaa@gmail.com
*/

#include "allocore/types/al_Array.hpp"
#include "allocore/types/al_Color.hpp"

#include "allocore/graphics/al_Graphics.hpp"
#include "allocore/graphics/al_GPUObject.hpp"

namespace al{

/**
	A simple wrapper around OpenGL Texture
*/
class Texture : public GPUObject {
public:

	typedef Graphics::Format Format;
	typedef Graphics::DataType DataType;

	enum Target {
		TEXTURE_1D				= GL_TEXTURE_1D,
		TEXTURE_2D				= GL_TEXTURE_2D,
		TEXTURE_3D				= GL_TEXTURE_3D
	};

	enum Wrap {
		CLAMP					= GL_CLAMP,
		CLAMP_TO_BORDER			= GL_CLAMP_TO_BORDER,
		CLAMP_TO_EDGE			= GL_CLAMP_TO_EDGE,
		MIRRORED_REPEAT			= GL_MIRRORED_REPEAT,
		REPEAT					= GL_REPEAT
	};

	enum Filter {
		NEAREST					= GL_NEAREST,
		LINEAR					= GL_LINEAR,
		NEAREST_MIPMAP_NEAREST	= GL_NEAREST_MIPMAP_NEAREST,
		LINEAR_MIPMAP_NEAREST	= GL_LINEAR_MIPMAP_NEAREST,
		NEAREST_MIPMAP_LINEAR	= GL_NEAREST_MIPMAP_LINEAR,
		LINEAR_MIPMAP_LINEAR	= GL_LINEAR_MIPMAP_LINEAR,
	};

	/**
		Construct a 2D Texture object.
	*/
	Texture(unsigned width=512, unsigned height=512, Graphics::Format format=Graphics::RGBA, Graphics::DataType type=Graphics::UBYTE);

	/**
		Construct a 3D Texture object.
	*/
	Texture(unsigned width, unsigned height, unsigned depth, Graphics::Format format=Graphics::RGBA, Graphics::DataType type=Graphics::UBYTE);

	virtual ~Texture(){}

	Format format() const { return mFormat; }
	Target target() const { return mTarget; }
	DataType type() const { return mType; }

	unsigned width() const { return mWidth; }
	unsigned height() const { return mHeight; }
	unsigned depth() const { return mDepth; }

	Filter filter() const { return mFilter; }

	/// Return number of components per pixel
	unsigned numComponents() const { return Graphics::numComponents(format()); }

	/// Return total number of elements (components x width x height x depth)
	unsigned numElems() const {
		return numPixels() * numComponents();
	}

	unsigned numPixels() const {
		return width() * (height()?height():1) * (depth()?depth():1);
	}

	Texture& format(Format v){ return update(v, mFormat, mPixelsUpdated); }
	Texture& target(Target v){ return update(v, mTarget, mPixelsUpdated); }
	Texture& type(DataType v){ return update(v, mType  , mPixelsUpdated); }

	Texture& width (unsigned v){ return update(v, mWidth, mPixelsUpdated); }
	Texture& height(unsigned v){ return update(v, mHeight,mPixelsUpdated); }
	Texture& depth (unsigned v){ return update(v, mDepth ,mPixelsUpdated); }

	Texture& resize(unsigned w){ return width(w); }
	Texture& resize(unsigned w, unsigned h){ return width(w).height(h); }
	Texture& resize(unsigned w, unsigned h, unsigned d){ return width(w).height(h).depth(d); }

	Texture& filter(Filter v){ return update(v, mFilter, mParamsUpdated); }
	Texture& wrap(Wrap v){ return wrap(v,v,v); }
	Texture& wrap(Wrap S, Wrap T){ return wrap(S,T,mWrapR); }
	Texture& wrap(Wrap S, Wrap T, Wrap R);

	/// bind the texture (to a multitexture unit)
	void bind(int unit = 0);
	/// unbind the texture (from a multitexture unit)
	void unbind(int unit = 0);

	/// render the texture onto a quad on the XY plane
	void quad(Graphics& gl, double w=1, double h=1, double x=0, double y=0);

	/// return reference to the internal CPU-side cache
	/// DO NOT MODIFY THE LAYOUT OR DIMENSIONS OF THIS ARRAY
	Array& array() { return mArray; }

	/// Get raw pointer to client-side pixel data
	template<class T> T * data(){ return (T*)(data()); }
	char * data(){ return array().data.ptr; }

	/// Flags resubmission of pixel data upon next bind
	Texture& updatePixels(){ mPixelsUpdated=true; return *this; }

	/// Submit the texture using an Array as source
	/// NOTE: the graphics context (e.g. Window) must have been created
	/// if reconfigure is true,
	/// it will attempt to derive size & layout from the array
	void submit(const Array& src, bool reconfigure=false);

	/// Resize texture data on GPU and copy over pixels
	/// NOTE: the graphics context (e.g. Window) must have been created
	/// If pixels is NULL, then the only effect is to resize the texture
	/// remotely.
	void submit(const void * pixels, uint32_t align=4);

	/// just submit the existing data
	void submit() { dirty(); }

	/// allocate the internal Array for a CPU-side cache, copying from src
	void allocate(const Array& src, bool reconfigure=true);
	/// allocate memory for a CPU copy
	/// reconfigures the internal array
	void allocate(unsigned align=1);

	void deallocate();

	/// debug printing
	void print();

	/// mark pixels as dirtied (e.g. if modified array contents)
	/// to ensure they get submitted on the next bind():
	void dirty() { mPixelsUpdated = true; }

protected:
//	GLint mLevel;	// TODO: on a rainy day...
//	GLint mBorder;
	Target mTarget;				// TEXTURE_1D, TEXTURE_2D, etc.
	Format mFormat;				// RGBA, ALPHA, etc.
	DataType mType;				// UBYTE, FLOAT, etc.
	Wrap mWrapS, mWrapT, mWrapR;
	Filter mFilter;
	unsigned mWidth, mHeight, mDepth;
	GLint mUnpack;

	void * mPixels;				// pointer to client-side pixel data (0 if none)
	Array mArray;				// Array representation of client-side pixel data
//	void * mBuffer;				// internally allocated pixel buffer
	bool mParamsUpdated;
	bool mPixelsUpdated;

	virtual void onCreate(){
		//printf("Texture onCreate\n");
		glGenTextures(1, (GLuint *)&mID);
		sendParams();
		sendPixels();
		Graphics::error("creating texture");
	}

	virtual void onDestroy(){
		glDeleteTextures(1, (GLuint *)&mID);
	}

	/// ensures that the internal Array format matches the texture format
	void resetArray(unsigned align);

	/// send any pending parameter updates to GPU or do immediately if forced
	void sendParams(bool force=true);

	/// send any pending pixels updates to GPU or do immediately if forced
	void sendPixels(bool force=true);

	/// determines target (e.g. GL_TEXTURE_2D) from the dimensions
	void determineTarget();

	// Pattern for setting a variable that when changed sets a notification flag
	template<class T>
	Texture& update(const T& v, T& var, bool& flag){
		if(v!=var){ var=v; flag=true; }
		return *this;
	}
};

inline Texture& Texture :: wrap(Wrap S, Wrap T, Wrap R){
	if(S!=mWrapS || T!=mWrapT || R!=mWrapR){
		mWrapS = S; mWrapT = T; mWrapR = R;
		mParamsUpdated = true;
	}
	return *this;
}

} // al::

#endif
<|endoftext|>


<commit_before>//   Copyright 2015 Patrick Putnam
//
//   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 <stdio.h>
#include <cuda.h>
#include <iostream>

#include <boost/random/mersenne_twister.hpp>

#include "clotho/utility/timer.hpp"

#include "square.h"

typedef clotho::utility::timer  timer_type;
typedef boost::random::mt19937  rng_type;

typedef Square::int_type        int_type;

void square_it( int_type N ) {

    timer_type t;
    int_type * a = new int_type[ N ];

    for(int_type i = 0; i < N; ++i ) {
        a[i] = i*i;
    }

    delete [] a;
    t.stop();
    std::cout << "host lapse:   " << t.elapsed().count() << std::endl;
}

void square_list_rand( int_type N ) {
    timer_type t;

    int_type * a = new int_type[ N ];
    rng_type rand(1234);

    for(int_type i = 0; i < N; ++i ) {
        unsigned int r = rand();

        a[i] = r * r;
    }

    t.stop();
    std::cout << "host random lapse: " << t.elapsed().count() << std::endl;

    std::cerr << "BEGIN HOST" << std::endl;
    for( unsigned int i = 0; i < N; ++i ) {
        std::cerr << i << " -> " << a[i] << std::endl;
    }
    delete [] a;
}

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

    timer_type t;
    Square s;
    t.stop();

    std::cout << "Init: " << t.elapsed().count() << std::endl;

    //t.start();
    //s();
    //t.stop();

    //std::cout << "device lapse: " << t.elapsed().count() << std::endl;

    t.start();
    s.random_list();
    t.stop();
    std::cout << "device random lapse: " << t.elapsed().count() << std::endl;
    std::cerr << s;

    square_it( s.size() );

    square_list_rand( s.size() );

    return 0;
}
<commit_msg>Updated to include command line options<commit_after>//   Copyright 2015 Patrick Putnam
//
//   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 <stdio.h>
#include <cuda.h>
#include <iostream>

#include <boost/program_options.hpp>
#include <boost/random/mersenne_twister.hpp>

#include "clotho/utility/timer.hpp"

#include "square.h"

namespace po=boost::program_options;

typedef clotho::utility::timer  timer_type;
typedef boost::random::mt19937  rng_type;

typedef Square::int_type        int_type;

const std::string HELP_K = "help";

const std::string SEED_K = "seed";
const std::string LEN_K = "len";
const std::string ROUNDS_K = "rounds";
const std::string PRINT_GPU_K = "print-gpu";
const std::string PRINT_CPU_K = "print-cpu";

int parse_commandline( int argc, char ** argv, po::variables_map & vm ) {
    po::options_description gen( "General" );
    gen.add_options()
    ( (HELP_K + ",h").c_str(), "Print this" )
    ;

    po::options_description params( "Parameters" );
    params.add_options()
    ((SEED_K + ",s").c_str(), po::value< unsigned int >()->default_value(1234), "Host random number generator seed value" )
    ((LEN_K + ",l").c_str(), po::value< unsigned int >()->default_value( 2000 ), "List size" )
    ((ROUNDS_K + ",r").c_str(), po::value< unsigned int >()->default_value( 1 ), "Number of rounds to repeat")
    ((PRINT_GPU_K + ",p").c_str(), "Print GPGPU generated lists" )
    ((PRINT_CPU_K + ",P").c_str(), "Print CPU generated lists" )
    ;

    po::options_description cmdline;

    cmdline.add(gen).add(params);

    po::store( po::command_line_parser( argc, argv ).options(cmdline).run(), vm );

    int res = 0;
    if( vm.count( HELP_K ) ) {
        std::cout << cmdline << std::endl;
        res = 1;
    }

    return res;
}

void square_it( int_type N ) {

    timer_type t;
    int_type * a = new int_type[ N ];

    for(int_type i = 0; i < N; ++i ) {
        a[i] = i*i;
    }

    delete [] a;
    t.stop();
    std::cout << "host lapse:   " << t.elapsed().count() << std::endl;
}

template < class Engine >
void square_list_rand( Engine & eng, int_type N ) {
    timer_type t;

    int_type * a = new int_type[ N ];

    for(int_type i = 0; i < N; ++i ) {
        unsigned int r = eng();

        a[i] = r * r;
    }

    t.stop();
    std::cout << "host random lapse: " << t.elapsed().count() << std::endl;

    //std::cerr << "BEGIN HOST" << std::endl;
    //for( unsigned int i = 0; i < N; ++i ) {
    //    std::cerr << i << " -> " << a[i] << std::endl;
    //}
    delete [] a;
}

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

    po::variables_map vm;
    if( parse_commandline(argc, argv, vm ) ) {
        return -1;
    }

    rng_type rgen(vm[SEED_K].as<unsigned int>());
    unsigned int list_len = vm[LEN_K].as<unsigned int>();
    unsigned int rounds = vm[ROUNDS_K].as<unsigned int>();

    bool print_gpu = (vm.count(PRINT_GPU_K) > 0);
//    bool print_cpu = (vm.count(PRINT_CPU_K) > 0);

    timer_type t;
    Square s( rgen );
    t.stop();

    std::cout << "Init: " << t.elapsed().count() << std::endl;

    std::cout << "Testing GPGPU based RNG ..." << std::endl;
    unsigned int i = 0;
    while( i < rounds ) {
        t.start();
        s(list_len);
        t.stop();

        std::cout << "Round " << (++i) <<  ": device random lapse: " << t.elapsed().count() << std::endl;
        if( print_gpu )        std::cerr << s;
    }

    std::cout << "Testing CPU based RNG ..." << std::endl;
    i = 0;
    while( i < rounds ) {
        std::cout << "Round " << (++i) << ": ";
        square_list_rand( rgen, list_len );
    }

    return 0;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright 2009-2015 Jörg Müller
 *
 * 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 "generator/Sawtooth.h"
#include "generator/Sine.h"
#include "generator/Silence.h"
#include "generator/Square.h"
#include "generator/Triangle.h"
#include "file/File.h"
#include "util/StreamBuffer.h"
#include "fx/Accumulator.h"
#include "fx/ADSR.h"
#include "fx/Delay.h"
#include "fx/Envelope.h"
#include "fx/Fader.h"
#include "fx/Highpass.h"
#include "fx/IIRFilter.h"
#include "fx/Limiter.h"
#include "fx/Loop.h"
#include "fx/Lowpass.h"
#include "fx/Pitch.h"
#include "fx/Reverse.h"
#include "fx/Sum.h"
#include "fx/Threshold.h"
#include "fx/Volume.h"
#include "fx/SoundList.h"
#include "fx/MutableSound.h"
#include "sequence/Double.h"
#include "sequence/Superpose.h"
#include "sequence/PingPong.h"
#include "respec/LinearResample.h"
#include "respec/ChannelMapper.h"
#include "util/Buffer.h"
#include "Exception.h"

#include <cassert>

using namespace aud;

#define AUD_CAPI_IMPLEMENTATION
#include "AUD_Sound.h"

AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size)
{
	assert(buffer);
	return new AUD_Sound(new File(buffer, size));
}

AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new StreamBuffer(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_file(const char* filename)
{
	assert(filename);
	return new AUD_Sound(new File(filename));
}

AUD_API AUD_Sound* AUD_Sound_sawtooth(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Sawtooth(frequency, rate));
}

AUD_API AUD_Sound*AUD_Sound_silence()
{
	return new AUD_Sound(new Silence());
}

AUD_API AUD_Sound* AUD_Sound_sine(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Sine(frequency, rate));
}

AUD_API AUD_Sound* AUD_Sound_square(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Square(frequency, rate));
}

AUD_API AUD_Sound* AUD_Sound_triangle(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Triangle(frequency, rate));
}

AUD_API AUD_Sound* AUD_Sound_accumulate(AUD_Sound* sound, int additive)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Accumulator(*sound, additive));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_ADSR(AUD_Sound* sound, float attack, float decay, float sustain, float release)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new ADSR(*sound, attack, decay, sustain, release));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_delay(AUD_Sound* sound, float delay)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Delay(*sound, delay));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_envelope(AUD_Sound* sound, float attack, float release, float threshold, float arthreshold)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Envelope(*sound, attack, release, threshold, arthreshold));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_fadein(AUD_Sound* sound, float start, float length)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Fader(*sound, FADE_IN, start, length));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_fadeout(AUD_Sound* sound, float start, float length)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Fader(*sound, FADE_OUT, start, length));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_filter(AUD_Sound* sound, float* b, int b_length, float* a, int a_length)
{
	assert(sound);

	try
	{
		std::vector<float> a_coeff, b_coeff;

		if(b)
			for(int i = 0; i < b_length; i++)
				b_coeff.push_back(b[i]);

		if(a)
		{
			for(int i = 0; i < a_length; i++)
				a_coeff.push_back(a[i]);

			if(*a == 0.0f)
				a_coeff[0] = 1.0f;
		}

		return new AUD_Sound(new IIRFilter(*sound, b_coeff, a_coeff));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_highpass(AUD_Sound* sound, float frequency, float Q)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Highpass(*sound, frequency, Q));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_limit(AUD_Sound* sound, float start, float end)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Limiter(*sound, start, end));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_loop(AUD_Sound* sound, int count)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Loop(*sound, count));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Lowpass(*sound, frequency, Q));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_pitch(AUD_Sound* sound, float factor)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Pitch(*sound, factor));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels channels)
{
	assert(sound);

	try
	{
		DeviceSpecs specs;
		specs.channels = static_cast<Channels>(channels);
		specs.rate = RATE_INVALID;
		specs.format = FORMAT_INVALID;
		return new AUD_Sound(new ChannelMapper(*sound, specs));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_reverse(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Reverse(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_sum(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Sum(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_threshold(AUD_Sound* sound, float threshold)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Threshold(*sound, threshold));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_volume(AUD_Sound* sound, float volume)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Volume(*sound, volume));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_join(AUD_Sound* first, AUD_Sound* second)
{
	assert(first);
	assert(second);

	try
	{
		return new AUD_Sound(new Double(*first, *second));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_mix(AUD_Sound* first, AUD_Sound* second)
{
	assert(first);
	assert(second);

	try
	{
		return new AUD_Sound(new Superpose(*first, *second));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_pingpong(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new PingPong(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API void AUD_Sound_free(AUD_Sound* sound)
{
	assert(sound);
	delete sound;
}

AUD_API AUD_Sound* AUD_Sound_copy(AUD_Sound* sound)
{
	return new std::shared_ptr<ISound>(*sound);
}

extern AUD_API AUD_Sound* AUD_Sound_list(int random)
{
	try
	{
		return new AUD_Sound(new SoundList(random));
	}
	catch (Exception&)
	{
		return nullptr;
	}
}

extern AUD_API int AUD_Sound_list_addSound(AUD_Sound* list, AUD_Sound* sound)
{
	assert(sound);
	assert(list);

	std::shared_ptr<SoundList> s = std::dynamic_pointer_cast<SoundList>(*list);
	if (s.get())
	{
		s->addSound(*sound);
		return 1;
	}
	else
		return 0;

}

extern AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new MutableSound(*sound));
	}
	catch (Exception&)
	{
		return nullptr;
	}
}
<commit_msg>Fix in C api<commit_after>/*******************************************************************************
 * Copyright 2009-2015 Jörg Müller
 *
 * 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 "generator/Sawtooth.h"
#include "generator/Sine.h"
#include "generator/Silence.h"
#include "generator/Square.h"
#include "generator/Triangle.h"
#include "file/File.h"
#include "util/StreamBuffer.h"
#include "fx/Accumulator.h"
#include "fx/ADSR.h"
#include "fx/Delay.h"
#include "fx/Envelope.h"
#include "fx/Fader.h"
#include "fx/Highpass.h"
#include "fx/IIRFilter.h"
#include "fx/Limiter.h"
#include "fx/Loop.h"
#include "fx/Lowpass.h"
#include "fx/Pitch.h"
#include "fx/Reverse.h"
#include "fx/Sum.h"
#include "fx/Threshold.h"
#include "fx/Volume.h"
#include "fx/SoundList.h"
#include "fx/MutableSound.h"
#include "sequence/Double.h"
#include "sequence/Superpose.h"
#include "sequence/PingPong.h"
#include "respec/LinearResample.h"
#include "respec/ChannelMapper.h"
#include "util/Buffer.h"
#include "Exception.h"

#include <cassert>

using namespace aud;

#define AUD_CAPI_IMPLEMENTATION
#include "AUD_Sound.h"

AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size)
{
	assert(buffer);
	return new AUD_Sound(new File(buffer, size));
}

AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new StreamBuffer(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_file(const char* filename)
{
	assert(filename);
	return new AUD_Sound(new File(filename));
}

AUD_API AUD_Sound* AUD_Sound_sawtooth(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Sawtooth(frequency, rate));
}

AUD_API AUD_Sound*AUD_Sound_silence()
{
	return new AUD_Sound(new Silence());
}

AUD_API AUD_Sound* AUD_Sound_sine(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Sine(frequency, rate));
}

AUD_API AUD_Sound* AUD_Sound_square(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Square(frequency, rate));
}

AUD_API AUD_Sound* AUD_Sound_triangle(float frequency, AUD_SampleRate rate)
{
	return new AUD_Sound(new Triangle(frequency, rate));
}

AUD_API AUD_Sound* AUD_Sound_accumulate(AUD_Sound* sound, int additive)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Accumulator(*sound, additive));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_ADSR(AUD_Sound* sound, float attack, float decay, float sustain, float release)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new ADSR(*sound, attack, decay, sustain, release));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_delay(AUD_Sound* sound, float delay)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Delay(*sound, delay));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_envelope(AUD_Sound* sound, float attack, float release, float threshold, float arthreshold)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Envelope(*sound, attack, release, threshold, arthreshold));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_fadein(AUD_Sound* sound, float start, float length)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Fader(*sound, FADE_IN, start, length));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_fadeout(AUD_Sound* sound, float start, float length)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Fader(*sound, FADE_OUT, start, length));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_filter(AUD_Sound* sound, float* b, int b_length, float* a, int a_length)
{
	assert(sound);

	try
	{
		std::vector<float> a_coeff, b_coeff;

		if(b)
			for(int i = 0; i < b_length; i++)
				b_coeff.push_back(b[i]);

		if(a)
		{
			for(int i = 0; i < a_length; i++)
				a_coeff.push_back(a[i]);

			if(*a == 0.0f)
				a_coeff[0] = 1.0f;
		}

		return new AUD_Sound(new IIRFilter(*sound, b_coeff, a_coeff));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_highpass(AUD_Sound* sound, float frequency, float Q)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Highpass(*sound, frequency, Q));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_limit(AUD_Sound* sound, float start, float end)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Limiter(*sound, start, end));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_loop(AUD_Sound* sound, int count)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Loop(*sound, count));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Lowpass(*sound, frequency, Q));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_pitch(AUD_Sound* sound, float factor)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Pitch(*sound, factor));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels channels)
{
	assert(sound);

	try
	{
		DeviceSpecs specs;
		specs.channels = static_cast<Channels>(channels);
		specs.rate = RATE_INVALID;
		specs.format = FORMAT_INVALID;
		return new AUD_Sound(new ChannelMapper(*sound, specs));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_reverse(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Reverse(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_sum(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Sum(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_threshold(AUD_Sound* sound, float threshold)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Threshold(*sound, threshold));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_volume(AUD_Sound* sound, float volume)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new Volume(*sound, volume));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_join(AUD_Sound* first, AUD_Sound* second)
{
	assert(first);
	assert(second);

	try
	{
		return new AUD_Sound(new Double(*first, *second));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_mix(AUD_Sound* first, AUD_Sound* second)
{
	assert(first);
	assert(second);

	try
	{
		return new AUD_Sound(new Superpose(*first, *second));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API AUD_Sound* AUD_Sound_pingpong(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new PingPong(*sound));
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API void AUD_Sound_free(AUD_Sound* sound)
{
	assert(sound);
	delete sound;
}

AUD_API AUD_Sound* AUD_Sound_copy(AUD_Sound* sound)
{
	return new std::shared_ptr<ISound>(*sound);
}

AUD_API AUD_Sound* AUD_Sound_list(int random)
{
	try
	{
		return new AUD_Sound(new SoundList(random));
	}
	catch (Exception&)
	{
		return nullptr;
	}
}

AUD_API int AUD_Sound_list_addSound(AUD_Sound* list, AUD_Sound* sound)
{
	assert(sound);
	assert(list);

	std::shared_ptr<SoundList> s = std::dynamic_pointer_cast<SoundList>(*list);
	if (s.get())
	{
		s->addSound(*sound);
		return 1;
	}
	else
		return 0;

}

AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound)
{
	assert(sound);

	try
	{
		return new AUD_Sound(new MutableSound(*sound));
	}
	catch (Exception&)
	{
		return nullptr;
	}
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief StaticRawFifoQueue class header
 *
 * \author Copyright (C) 2015-2019 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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 http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_
#define INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_

#include "RawFifoQueue.hpp"

#include "distortos/internal/memory/dummyDeleter.hpp"

namespace distortos
{

/**
 * \brief StaticRawFifoQueue class is a variant of RawFifoQueue that has automatic storage for queue's contents.
 *
 * This class is a replacement for StaticRawFifoQueue with old API and removed StaticRawFifoQueueFromSize. To use this
 * new API modify your code in following way:
 * - old `"StaticRawFifoQueue<T, QueueSize>"` -> `"StaticRawFifoQueue<sizeof(T), QueueSize>"`;
 * - removed `"StaticRawFifoQueueFromSize<ElementSize, QueueSize>"` -> `"StaticRawFifoQueue<ElementSize, QueueSize>"`;
 *
 * Transition schedule:
 * 1. v0.5.0 - `StaticRawFifoQueue<T, QueueSize>` and `StaticRawFifoQueueFromSize<ElementSize, QueueSize>` are converted
 * to deprecated aliases to `StaticRawFifoQueue2<ElementSize, QueueSize>`;
 * 2. v0.6.0 - "old" `StaticRawFifoQueue<T, QueueSize>` and `StaticRawFifoQueueFromSize<ElementSize, QueueSize>` aliases
 * are removed, `StaticRawFifoQueue2<ElementSize, QueueSize>` is renamed to
 * `StaticRawFifoQueue<ElementSize, QueueSize>`, deprecated `StaticRawFifoQueue2<ElementSize, QueueSize>` alias is
 * added;
 * 3. v0.7.0 - deprecated `StaticRawFifoQueue2<ElementSize, QueueSize>` alias is removed;
 *
 * \tparam ElementSize is the size of single queue element, bytes
 * \tparam QueueSize is the maximum number of elements in queue
 *
 * \ingroup queues
 */

template<size_t ElementSize, size_t QueueSize>
class StaticRawFifoQueue : public RawFifoQueue
{
public:

	/**
	 * \brief StaticRawFifoQueue's constructor
	 */

	explicit StaticRawFifoQueue() :
			RawFifoQueue{{storage_.data(), internal::dummyDeleter<uint8_t>}, ElementSize, QueueSize}
	{

	}

	/**
	 * \return maximum number of elements in queue
	 */

	constexpr static size_t getCapacity()
	{
		return QueueSize;
	}

	/**
	 * \return size of single queue element, bytes
	 */

	constexpr static size_t getElementSize()
	{
		return ElementSize;
	}

private:

	/// storage for queue's contents
	std::array<uint8_t, ElementSize * QueueSize> storage_;
};

/**
 * \brief StaticRawFifoQueue2 class is a variant of RawFifoQueue that has automatic storage for queue's contents.
 *
 * \deprecated scheduled to be removed after v0.6.0, use `StaticRawFifoQueue<ElementSize, QueueSize>`
 *
 * \tparam ElementSize is the size of single queue element, bytes
 * \tparam QueueSize is the maximum number of elements in queue
 *
 * \ingroup queues
 */

template<size_t ElementSize, size_t QueueSize>
using StaticRawFifoQueue2 __attribute__ ((deprecated("Use StaticRawFifoQueue<ElementSize, QueueSize>"))) =
		StaticRawFifoQueue<ElementSize, QueueSize>;

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_
<commit_msg>Remove deprecated StaticRawFifoQueue2 type alias<commit_after>/**
 * \file
 * \brief StaticRawFifoQueue class header
 *
 * \author Copyright (C) 2015-2019 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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 http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_
#define INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_

#include "RawFifoQueue.hpp"

#include "distortos/internal/memory/dummyDeleter.hpp"

namespace distortos
{

/**
 * \brief StaticRawFifoQueue class is a variant of RawFifoQueue that has automatic storage for queue's contents.
 *
 * \tparam ElementSize is the size of single queue element, bytes
 * \tparam QueueSize is the maximum number of elements in queue
 *
 * \ingroup queues
 */

template<size_t ElementSize, size_t QueueSize>
class StaticRawFifoQueue : public RawFifoQueue
{
public:

	/**
	 * \brief StaticRawFifoQueue's constructor
	 */

	explicit StaticRawFifoQueue() :
			RawFifoQueue{{storage_.data(), internal::dummyDeleter<uint8_t>}, ElementSize, QueueSize}
	{

	}

	/**
	 * \return maximum number of elements in queue
	 */

	constexpr static size_t getCapacity()
	{
		return QueueSize;
	}

	/**
	 * \return size of single queue element, bytes
	 */

	constexpr static size_t getElementSize()
	{
		return ElementSize;
	}

private:

	/// storage for queue's contents
	std::array<uint8_t, ElementSize * QueueSize> storage_;
};

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2009 Aristid Breitkreuz, Ash Berlin, Ruediger Sonderfeld

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.
*/

#ifndef FLUSSFPERD_CLASS_DESCRIPTION_HPP
#define FLUSSFPERD_CLASS_DESCRIPTION_HPP

#ifndef PREPROC_DEBUG
#include "class.hpp"
#include "native_object_base.hpp"
#endif
#include "detail/limit.hpp"
#include <boost/preprocessor.hpp>

/* 2-tuple seq */

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS2(x, y) \
  ((x, y)) \
  FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS(x, y) \
  ((x, y)) \
  FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS2

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS_ELIM
#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS2_ELIM

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ(x) \
  BOOST_PP_CAT(FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS x, _ELIM)

/* 3-tuple seq */

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS2(x, y, z) \
  ((x, y, z)) \
  FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS(x, y, z) \
  ((x, y, z)) \
  FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS2

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS_ELIM
#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS2_ELIM

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ(x) \
  BOOST_PP_CAT(FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS x, _ELIM)

/* -- */

#define FLUSSPFERD_CD_PARAM_FOLD(s, state, elem) \
  BOOST_PP_ARRAY_REPLACE( \
    state, \
    BOOST_PP_EXPAND( \
      BOOST_PP_CAT(FLUSSPFERD_CD_PARAM__, \
        BOOST_PP_TUPLE_ELEM(2, 0, elem))), \
    BOOST_PP_TUPLE_ELEM(2, 1, elem)) \
  /* */

#define FLUSSPFERD_CD_PARAM_INITIAL \
  (13, ( \
    ~cpp_name~,                        /* name */ \
    ::flusspferd::native_object_base,  /* base class */ \
    ~constructor_name~,                /* constructor name */ \
    0,                                 /* constructor arity */ \
    true,                              /* constructible */ \
    ~full_name~,                       /* full name */ \
    (~, none, ~),                      /* methods */ \
    (~, none, ~),                      /* constructor methods */ \
    (~, none, ~),                      /* properties */ \
    (~, none, ~),                      /* constructor properties */ \
    false,                             /* custom enumerate */ \
    0,                                 /* augment constructor (custom func.)*/\
    0                                  /* augment prototype (custom func.) */ \
  )) \
  /* */

#define FLUSSPFERD_CD_PARAM__cpp_name                 0
#define FLUSSPFERD_CD_PARAM__base                     1
#define FLUSSPFERD_CD_PARAM__constructor_name         2
#define FLUSSPFERD_CD_PARAM__constructor_arity        3
#define FLUSSPFERD_CD_PARAM__constructible            4
#define FLUSSPFERD_CD_PARAM__full_name                5
#define FLUSSPFERD_CD_PARAM__methods                  6
#define FLUSSPFERD_CD_PARAM__constructor_methods      7
#define FLUSSPFERD_CD_PARAM__properties               8
#define FLUSSPFERD_CD_PARAM__constructor_properties   9
#define FLUSSPFERD_CD_PARAM__custom_enumerate        10
#define FLUSSPFERD_CD_PARAM__augment_constructor     11
#define FLUSSPFERD_CD_PARAM__augment_prototype       12

#define FLUSSPFERD_CD_PARAM(tuple_seq) \
  BOOST_PP_SEQ_FOLD_LEFT( \
    FLUSSPFERD_CD_PARAM_FOLD, \
    FLUSSPFERD_CD_PARAM_INITIAL, \
    FLUSSPFERD_PP_GEN_TUPLE2SEQ(tuple_seq) \
  ) \
  /* */

#define FLUSSPFERD_CLASS_DESCRIPTION_A(array) \
  BOOST_PP_EXPAND(FLUSSPFERD_CLASS_DESCRIPTION_P BOOST_PP_ARRAY_DATA(array)) \
  /* */

#define FLUSSPFERD_CLASS_DESCRIPTION_P( \
  p_cpp_name, \
  p_base, \
  p_constructor_name, \
  p_constructor_arity, \
  p_constructible, \
  p_full_name, \
  p_methods, \
  p_constructor_methods, \
  p_properties, \
  p_constructor_properties, \
  p_custom_enumerate, \
  p_augment_constructor, \
  p_augment_prototype \
) \
  template<typename Class> \
  class BOOST_PP_CAT(p_cpp_name, _base) : public p_base { \
  public: \
    typedef BOOST_PP_CAT(p_cpp_name, _base) base_type; \
    struct class_info : ::flusspferd::class_info { \
      typedef boost::mpl::bool_< (p_constructible) > constructible; \
      static char const *constructor_name() { \
        return (p_constructor_name); \
      } \
      typedef ::boost::mpl::size_t< (p_constructor_arity) > constructor_arity; \
      static char const *full_name() { \
        return (p_full_name); \
      } \
      static ::flusspferd::object create_prototype() { \
        ::flusspferd::object obj = ::flusspferd::create_object( \
            ::flusspferd::prototype< p_base >() \
          ); \
        FLUSSPFERD_CD_METHODS(p_methods) \
        FLUSSPFERD_CD_PROPERTIES(p_properties) \
        BOOST_PP_EXPR_IF( \
          p_augment_prototype, \
          Class :: augment_prototype(obj);) \
        return obj; \
      } \
      static void augment_constructor(::flusspferd::object &obj) { \
        (void)obj; \
        FLUSSPFERD_CD_METHODS(p_constructor_methods) \
        FLUSSPFERD_CD_PROPERTIES(p_constructor_properties) \
        BOOST_PP_EXPR_IF( \
          p_augment_constructor, \
          Class :: augment_constructor(obj);) \
      } \
      typedef boost::mpl::bool_< (p_custom_enumerate) > custom_enumerate; \
    }; \
    BOOST_PP_REPEAT( \
      BOOST_PP_INC(FLUSSPFERD_PARAM_LIMIT), \
      FLUSSPFERD_CD_CTOR_FWD, \
      (BOOST_PP_CAT(p_cpp_name, _base), p_base)) \
  }; \
  class p_cpp_name \
  : \
    public BOOST_PP_CAT(p_cpp_name, _base) < p_cpp_name > \
  /* */

#define FLUSSPFERD_CD_CTOR_FWD(z, n, d) \
  BOOST_PP_EXPR_IF(n, template<) \
  BOOST_PP_ENUM_PARAMS(n, typename P) \
  BOOST_PP_EXPR_IF(n, >) \
  BOOST_PP_TUPLE_ELEM(2, 0, d) \
  ( \
    BOOST_PP_ENUM_BINARY_PARAMS(n, P, const &p) \
  ) \
  : \
    BOOST_PP_TUPLE_ELEM(2, 1, d) \
    ( \
      BOOST_PP_ENUM_PARAMS(n, p) \
    ) \
  { } \
  /* */

#define FLUSSPFERD_CD_METHODS(p_methods) \
  BOOST_PP_SEQ_FOR_EACH( \
    FLUSSPFERD_CD_METHOD, \
    ~, \
    FLUSSPFERD_PP_GEN_TUPLE3SEQ(p_methods)) \
  /* */

#define FLUSSPFERD_CD_METHOD(r, d, p_method) \
  BOOST_PP_CAT( \
    FLUSSPFERD_CD_METHOD__, \
    BOOST_PP_TUPLE_ELEM(3, 1, p_method) \
  ) ( \
    BOOST_PP_TUPLE_ELEM(3, 0, p_method), \
    BOOST_PP_TUPLE_ELEM(3, 2, p_method) \
  ) \
  /* */

#define FLUSSPFERD_CD_METHOD__bind(p_method_name, p_bound) \
  ::flusspferd::create_native_method( \
      obj, \
      (p_method_name), \
      & Class :: p_bound); \
  /* */

#define FLUSSPFERD_CD_METHOD__bind_static(p_method_name, p_bound) \
  ::flusspferd::create_native_function( \
      obj, \
      (p_method_name), \
      & Class :: p_bound); \
  /* */

#define FLUSSPFERD_CD_METHOD__alias(p_method_name, p_alias) \
  obj.define_property( \
    (p_method_name), \
    obj.get_property((p_alias)), \
    ::flusspferd::dont_enumerate); \
  /* */

#define FLUSSPFERD_CD_METHOD__none(p_method_name, p_param) \
  /* */

#define FLUSSPFERD_CD_PROPERTIES(p_properties) \
  BOOST_PP_SEQ_FOR_EACH( \
    FLUSSPFERD_CD_PROPERTY, \
    ~, \
    FLUSSPFERD_PP_GEN_TUPLE3SEQ(p_properties)) \
  /* */

#define FLUSSPFERD_CD_PROPERTY(r, d, p_property) \
  BOOST_PP_CAT( \
    FLUSSPFERD_CD_PROPERTY__, \
    BOOST_PP_TUPLE_ELEM(3, 1, p_property) \
  ) ( \
    BOOST_PP_TUPLE_ELEM(3, 0, p_property), \
    BOOST_PP_TUPLE_ELEM(3, 2, p_property) \
  ) \
  /* */

#define FLUSSPFERD_CD_PROPERTY__getter_setter(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    ::flusspferd::property_attributes( \
      ::flusspferd::permanent_shared_property, \
      ::flusspferd::create_native_method( \
        ::flusspferd::object(), \
        "$get_" p_property_name, \
        & Class :: \
        BOOST_PP_TUPLE_ELEM(2, 0, p_param) \
      ), \
      ::flusspferd::create_native_method( \
        ::flusspferd::object(), \
        "$set_" p_property_name, \
        & Class :: \
        BOOST_PP_TUPLE_ELEM(2, 1, p_param) \
      ) \
    ) \
  ); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__getter(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    ::flusspferd::property_attributes( \
      ::flusspferd::permanent_shared_property \
      | ::flusspferd::read_only_property, \
      ::flusspferd::create_native_method( \
        ::flusspferd::object(), \
        "$get_" p_property_name, \
        & Class :: p_param \
      ) \
    ) \
  ); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__constant(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    (p_param), \
    ::flusspferd::read_only_property | ::flusspferd::permanent_property); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__variable(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    (p_param)); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__none(p_property_name, p_param) \
  /* */

#define FLUSSPFERD_CLASS_DESCRIPTION(tuple_seq) \
  FLUSSPFERD_CLASS_DESCRIPTION_A(FLUSSPFERD_CD_PARAM(tuple_seq)) \
  /* */

#endif
<commit_msg>core: add stub docs for FLUSSPFERD_CLASS_DESCRIPTION<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2009 Aristid Breitkreuz, Ash Berlin, Ruediger Sonderfeld

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.
*/

#ifndef FLUSSFPERD_CLASS_DESCRIPTION_HPP
#define FLUSSFPERD_CLASS_DESCRIPTION_HPP

#ifndef PREPROC_DEBUG
#include "class.hpp"
#include "native_object_base.hpp"
#endif
#include "detail/limit.hpp"
#include <boost/preprocessor.hpp>

#ifndef IN_DOXYGEN

/* 2-tuple seq */

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS2(x, y) \
  ((x, y)) \
  FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS(x, y) \
  ((x, y)) \
  FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS2

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS_ELIM
#define FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS2_ELIM

#define FLUSSPFERD_PP_GEN_TUPLE2SEQ(x) \
  BOOST_PP_CAT(FLUSSPFERD_PP_GEN_TUPLE2SEQ_PROCESS x, _ELIM)

/* 3-tuple seq */

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS2(x, y, z) \
  ((x, y, z)) \
  FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS(x, y, z) \
  ((x, y, z)) \
  FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS2

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS_ELIM
#define FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS2_ELIM

#define FLUSSPFERD_PP_GEN_TUPLE3SEQ(x) \
  BOOST_PP_CAT(FLUSSPFERD_PP_GEN_TUPLE3SEQ_PROCESS x, _ELIM)

/* -- */

#define FLUSSPFERD_CD_PARAM_FOLD(s, state, elem) \
  BOOST_PP_ARRAY_REPLACE( \
    state, \
    BOOST_PP_EXPAND( \
      BOOST_PP_CAT(FLUSSPFERD_CD_PARAM__, \
        BOOST_PP_TUPLE_ELEM(2, 0, elem))), \
    BOOST_PP_TUPLE_ELEM(2, 1, elem)) \
  /* */

#define FLUSSPFERD_CD_PARAM_INITIAL \
  (13, ( \
    ~cpp_name~,                        /* name */ \
    ::flusspferd::native_object_base,  /* base class */ \
    ~constructor_name~,                /* constructor name */ \
    0,                                 /* constructor arity */ \
    true,                              /* constructible */ \
    ~full_name~,                       /* full name */ \
    (~, none, ~),                      /* methods */ \
    (~, none, ~),                      /* constructor methods */ \
    (~, none, ~),                      /* properties */ \
    (~, none, ~),                      /* constructor properties */ \
    false,                             /* custom enumerate */ \
    0,                                 /* augment constructor (custom func.)*/\
    0                                  /* augment prototype (custom func.) */ \
  )) \
  /* */

#define FLUSSPFERD_CD_PARAM__cpp_name                 0
#define FLUSSPFERD_CD_PARAM__base                     1
#define FLUSSPFERD_CD_PARAM__constructor_name         2
#define FLUSSPFERD_CD_PARAM__constructor_arity        3
#define FLUSSPFERD_CD_PARAM__constructible            4
#define FLUSSPFERD_CD_PARAM__full_name                5
#define FLUSSPFERD_CD_PARAM__methods                  6
#define FLUSSPFERD_CD_PARAM__constructor_methods      7
#define FLUSSPFERD_CD_PARAM__properties               8
#define FLUSSPFERD_CD_PARAM__constructor_properties   9
#define FLUSSPFERD_CD_PARAM__custom_enumerate        10
#define FLUSSPFERD_CD_PARAM__augment_constructor     11
#define FLUSSPFERD_CD_PARAM__augment_prototype       12

#define FLUSSPFERD_CD_PARAM(tuple_seq) \
  BOOST_PP_SEQ_FOLD_LEFT( \
    FLUSSPFERD_CD_PARAM_FOLD, \
    FLUSSPFERD_CD_PARAM_INITIAL, \
    FLUSSPFERD_PP_GEN_TUPLE2SEQ(tuple_seq) \
  ) \
  /* */

#define FLUSSPFERD_CLASS_DESCRIPTION_A(array) \
  BOOST_PP_EXPAND(FLUSSPFERD_CLASS_DESCRIPTION_P BOOST_PP_ARRAY_DATA(array)) \
  /* */

#define FLUSSPFERD_CLASS_DESCRIPTION_P( \
  p_cpp_name, \
  p_base, \
  p_constructor_name, \
  p_constructor_arity, \
  p_constructible, \
  p_full_name, \
  p_methods, \
  p_constructor_methods, \
  p_properties, \
  p_constructor_properties, \
  p_custom_enumerate, \
  p_augment_constructor, \
  p_augment_prototype \
) \
  template<typename Class> \
  class BOOST_PP_CAT(p_cpp_name, _base) : public p_base { \
  public: \
    typedef BOOST_PP_CAT(p_cpp_name, _base) base_type; \
    struct class_info : ::flusspferd::class_info { \
      typedef boost::mpl::bool_< (p_constructible) > constructible; \
      static char const *constructor_name() { \
        return (p_constructor_name); \
      } \
      typedef ::boost::mpl::size_t< (p_constructor_arity) > constructor_arity; \
      static char const *full_name() { \
        return (p_full_name); \
      } \
      static ::flusspferd::object create_prototype() { \
        ::flusspferd::object obj = ::flusspferd::create_object( \
            ::flusspferd::prototype< p_base >() \
          ); \
        FLUSSPFERD_CD_METHODS(p_methods) \
        FLUSSPFERD_CD_PROPERTIES(p_properties) \
        BOOST_PP_EXPR_IF( \
          p_augment_prototype, \
          Class :: augment_prototype(obj);) \
        return obj; \
      } \
      static void augment_constructor(::flusspferd::object &obj) { \
        (void)obj; \
        FLUSSPFERD_CD_METHODS(p_constructor_methods) \
        FLUSSPFERD_CD_PROPERTIES(p_constructor_properties) \
        BOOST_PP_EXPR_IF( \
          p_augment_constructor, \
          Class :: augment_constructor(obj);) \
      } \
      typedef boost::mpl::bool_< (p_custom_enumerate) > custom_enumerate; \
    }; \
    BOOST_PP_REPEAT( \
      BOOST_PP_INC(FLUSSPFERD_PARAM_LIMIT), \
      FLUSSPFERD_CD_CTOR_FWD, \
      (BOOST_PP_CAT(p_cpp_name, _base), p_base)) \
  }; \
  class p_cpp_name \
  : \
    public BOOST_PP_CAT(p_cpp_name, _base) < p_cpp_name > \
  /* */

#define FLUSSPFERD_CD_CTOR_FWD(z, n, d) \
  BOOST_PP_EXPR_IF(n, template<) \
  BOOST_PP_ENUM_PARAMS(n, typename P) \
  BOOST_PP_EXPR_IF(n, >) \
  BOOST_PP_TUPLE_ELEM(2, 0, d) \
  ( \
    BOOST_PP_ENUM_BINARY_PARAMS(n, P, const &p) \
  ) \
  : \
    BOOST_PP_TUPLE_ELEM(2, 1, d) \
    ( \
      BOOST_PP_ENUM_PARAMS(n, p) \
    ) \
  { } \
  /* */

#define FLUSSPFERD_CD_METHODS(p_methods) \
  BOOST_PP_SEQ_FOR_EACH( \
    FLUSSPFERD_CD_METHOD, \
    ~, \
    FLUSSPFERD_PP_GEN_TUPLE3SEQ(p_methods)) \
  /* */

#define FLUSSPFERD_CD_METHOD(r, d, p_method) \
  BOOST_PP_CAT( \
    FLUSSPFERD_CD_METHOD__, \
    BOOST_PP_TUPLE_ELEM(3, 1, p_method) \
  ) ( \
    BOOST_PP_TUPLE_ELEM(3, 0, p_method), \
    BOOST_PP_TUPLE_ELEM(3, 2, p_method) \
  ) \
  /* */

#define FLUSSPFERD_CD_METHOD__bind(p_method_name, p_bound) \
  ::flusspferd::create_native_method( \
      obj, \
      (p_method_name), \
      & Class :: p_bound); \
  /* */

#define FLUSSPFERD_CD_METHOD__bind_static(p_method_name, p_bound) \
  ::flusspferd::create_native_function( \
      obj, \
      (p_method_name), \
      & Class :: p_bound); \
  /* */

#define FLUSSPFERD_CD_METHOD__alias(p_method_name, p_alias) \
  obj.define_property( \
    (p_method_name), \
    obj.get_property((p_alias)), \
    ::flusspferd::dont_enumerate); \
  /* */

#define FLUSSPFERD_CD_METHOD__none(p_method_name, p_param) \
  /* */

#define FLUSSPFERD_CD_PROPERTIES(p_properties) \
  BOOST_PP_SEQ_FOR_EACH( \
    FLUSSPFERD_CD_PROPERTY, \
    ~, \
    FLUSSPFERD_PP_GEN_TUPLE3SEQ(p_properties)) \
  /* */

#define FLUSSPFERD_CD_PROPERTY(r, d, p_property) \
  BOOST_PP_CAT( \
    FLUSSPFERD_CD_PROPERTY__, \
    BOOST_PP_TUPLE_ELEM(3, 1, p_property) \
  ) ( \
    BOOST_PP_TUPLE_ELEM(3, 0, p_property), \
    BOOST_PP_TUPLE_ELEM(3, 2, p_property) \
  ) \
  /* */

#define FLUSSPFERD_CD_PROPERTY__getter_setter(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    ::flusspferd::property_attributes( \
      ::flusspferd::permanent_shared_property, \
      ::flusspferd::create_native_method( \
        ::flusspferd::object(), \
        "$get_" p_property_name, \
        & Class :: \
        BOOST_PP_TUPLE_ELEM(2, 0, p_param) \
      ), \
      ::flusspferd::create_native_method( \
        ::flusspferd::object(), \
        "$set_" p_property_name, \
        & Class :: \
        BOOST_PP_TUPLE_ELEM(2, 1, p_param) \
      ) \
    ) \
  ); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__getter(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    ::flusspferd::property_attributes( \
      ::flusspferd::permanent_shared_property \
      | ::flusspferd::read_only_property, \
      ::flusspferd::create_native_method( \
        ::flusspferd::object(), \
        "$get_" p_property_name, \
        & Class :: p_param \
      ) \
    ) \
  ); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__constant(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    (p_param), \
    ::flusspferd::read_only_property | ::flusspferd::permanent_property); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__variable(p_property_name, p_param) \
  obj.define_property( \
    (p_property_name), \
    (p_param)); \
  /* */

#define FLUSSPFERD_CD_PROPERTY__none(p_property_name, p_param) \
  /* */

#define FLUSSPFERD_CLASS_DESCRIPTION(tuple_seq) \
  FLUSSPFERD_CLASS_DESCRIPTION_A(FLUSSPFERD_CD_PARAM(tuple_seq)) \
  /* */

#else // IN_DOXYGEN

/**
 * Bla.
 *
 * @ingroup classes
 */
#define FLUSSPFERD_CLASS_DESCRIPTION(named_parameter_list) ...

#endif // IN_DOXYGEN

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Open Source Robotics Foundation
 *
 * 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.
 *
*/

#ifndef __IGN_TRANSPORT_TOPICSINFO_HH_INCLUDED__
#define __IGN_TRANSPORT_TOPICSINFO_HH_INCLUDED__

#include <czmq.h>
#include <google/protobuf/message.h>
#include <list>
#include <string>
#include <vector>
#include "ignition/transport/SubscriptionHandler.hh"
#include "ignition/transport/TransportTypes.hh"

namespace ignition
{
  namespace transport
  {
    // Info about a topic for pub/sub
    class TopicInfo
    {
      /// \brief Constructor.
      public: TopicInfo();

      /// \brief Destructor.
      public: virtual ~TopicInfo();

      /// \brief List of addresses known for a topic.
      public: Topics_L addresses;

      /// \brief Am I connected to the topic?
      public: bool connected;

      /// \brief Am I advertising this topic?
      public: bool advertisedByMe;

      /// brief Am I subscribed to the topic?
      public: bool subscribed;

      /// brief Is a service call pending?
      public: bool requested;

      /// brief Callback to handle service calls requested by other nodes.
      public: ReqCallback reqCb;

      /// brief Callback to manage the service call's response requested by me.
      public: RepCallback repCb;

      /// \brief Beacon used to periodically advertise this topic.
      public: zbeacon_t *beacon;

      /// brief List that stores the pending service call requests. Every
      /// element of the list contains the serialized parameters for each
      /// request.
      public: std::list<std::string> pendingReqs;

      public: unsigned int numSubscribers;

      public: ISubscriptionHandler_M subscriptionHandlers;
    };

    class TopicsInfo
    {
      /// \brief Constructor.
      public: TopicsInfo();

      /// \brief Destructor.
      public: virtual ~TopicsInfo();

      /// \brief Return if there is some information about a topic stored.
      /// \param[in] _topic Topic name.
      /// \return true If there is information about the topic.
      public: bool HasTopic(const std::string &_topic);

      /// \brief Get the known list of addresses associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[out] _addresses List of addresses
      /// \return true when we have info about this topic.
      public: bool GetAdvAddresses(const std::string &_topic,
                                   std::vector<std::string> &_addresses);

      /// \brief Return if an address is registered associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _address Address to check.
      /// \return true if the address is registered with the topic.
      public: bool HasAdvAddress(const std::string &_topic,
                                 const std::string &_address);

      /// \brief Return true if we are connected to a node
      /// advertising the topic.
      /// \param[in] _topic Topic name.
      /// \return true if we are connected.
      public: bool Connected(const std::string &_topic);

      /// \brief Return true if we are subscribed to a node advertising
      /// the topic.
      /// \param[in] _topic Topic name.
      /// \return true if we are subscribed.
      public: bool Subscribed(const std::string &_topic);

      /// \brief Return true if I am advertising the topic.
      /// \param[in] _topic Topic name.
      /// \return true if the topic is advertised by me.
      public: bool AdvertisedByMe(const std::string &_topic);

      /// \brief Return true if I am requesting the service call associated to
      /// the topic.
      /// \param[in] _topic Topic name.
      /// \return true if the service call associated to the topic is requested.
      public: bool Requested(const std::string &_topic);

      /// \brief Get the beacon used to advertise the topic
      /// \param[in] _topic Topic name.
      /// \param[out] _beacon Beacon used to advertise the topic.
      /// \return true if there is a beacon associated to the topicS.
      public: bool GetBeacon(const std::string &_topic, zbeacon_t **_beacon);

      /// \brief Get the REQ callback associated to a topic subscription.
      /// \param[in] _topic Topic name.
      /// \param[out] A pointer to the REQ function registered for a topic.
      /// \return true if there is a REQ callback registered for the topic.
      public: bool GetReqCallback(const std::string &_topic,
                                  transport::ReqCallback &_cb);

      /// \brief Get the REP callback associated to a topic subscription.
      /// \param[in] _topic Topic name.
      /// \param[out] A pointer to the REP function registered for a topic.
      /// \return true if there is a REP callback registered for the topic.
      public: bool GetRepCallback(const std::string &_topic,
                                  transport::RepCallback &_cb);

      /// \brief Returns if there are any pending requests in the queue.
      /// \param[in] _topic Topic name.
      /// \return true if there is any pending request in the queue.
      public: bool PendingReqs(const std::string &_topic);

      /// \brief Add a new address associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _address New address
      public: void AddAdvAddress(const std::string &_topic,
                                 const std::string &_address);

      /// \brief Remove an address associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[int] _address Address to remove.
      public: void RemoveAdvAddress(const std::string &_topic,
                                    const std::string &_address);

      /// \brief Set a new connected value to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned to the connected member.
      public: void SetConnected(const std::string &_topic, const bool _value);

      /// \brief Set a new subscribed value to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned to the subscribed member.
      public: void SetSubscribed(const std::string &_topic, const bool _value);

      /// \brief Set a new service call request to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned to the requested member.
      public: void SetRequested(const std::string &_topic, const bool _value);

      /// \brief Set a new advertised value to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned in advertisedByMe member.
      public: void SetAdvertisedByMe(const std::string &_topic,
                                     const bool _value);

      /// \brief Set the beacon used to advertise the topic
      /// \param[in] _topic Topic name.
      /// \param[in] _beacon Beacon used to advertise the topic.
      /// \return true if there is a beacon associated to the topicS.
      public: void SetBeacon(const std::string &_topic,
                             zbeacon_t *_beacon);

      /// \brief Set a new REQ callback associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _cb New callback.
      public: void SetReqCallback(const std::string &_topic,
                                  const transport::ReqCallback &_cb);

      /// \brief Set a new REP callback associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _cb New callback.
      public: void SetRepCallback(const std::string &_topic,
                                  const transport::RepCallback &_cb);

      /// \brief Add a new service call request to the queue.
      /// \param[in] _topic Topic name.
      /// \param[in] _data Parameters of the request.
      public: void AddReq(const std::string &_topic, const std::string &_data);

      /// \brief Add a new service call request to the queue.
      /// \param[in] _topic Topic name.
      /// \param[out] _data Parameters of the request.
      /// \return true if a request was removed.
      public: bool DelReq(const std::string &_topic, std::string &_data);

      /// \brief Check if a topic has a remote subscriber in this node.
      /// \param[in] _topic Topic name.
      /// \return true if a topic has a remote subscriber in this node.
      public: bool HasRemoteSubscribers(const std::string &_topic);

      /// \brief Increment the counter of remote susbscribers for a topic.
      /// \param[in] _topic Topic name.
      public: void AddRemoteSubscriber(const std::string &_topic);

      /// \brief Get the subscription handlers for a topic. A subscription
      /// handler stores the callback and types associated to a subscription.
      /// \param[in] _topic Topic name.
      /// \param[out] _handlers Subscription handlers.
      public: void GetSubscriptionHandlers(const std::string &_topic,
                                  transport::ISubscriptionHandler_M &_handlers);

      /// \brief Add a subscription handler to a topic. A subscription handler
      /// stores the callback and types associated to a subscription.
      /// \param[in] _topic Topic name.
      /// \param[in] _handlers Subscription handler.
      public: void AddSubscriptionHandler(const std::string &_topic,
                                        const ISubscriptionHandlerPtr &_msgPtr);

      /// \brief Check if a topic has a subscription handler.
      /// \param[in] _topic Topic name.
      /// \return true if the topic has a subscription handler registered.
      public: bool HasSubscriptionHandler(const std::string &_topic);

      /// \brief Get a reference to the topics map.
      /// \return Reference to the topic map.
      public: transport::Topics_M& GetTopicsInfo();

      /// \brief Check if the topic exists. If not, the topic is created.
      /// \param[in] _topic Topic name.
      private: void CheckAndCreate(const std::string &_topic);

      // Hash with the topic/topicInfo information for pub/sub.
      private: transport::Topics_M topicsInfo;
    };
  }
}

#endif
<commit_msg>Adding some doxygen.<commit_after>/*
 * Copyright (C) 2014 Open Source Robotics Foundation
 *
 * 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.
 *
*/

#ifndef __IGN_TRANSPORT_TOPICSINFO_HH_INCLUDED__
#define __IGN_TRANSPORT_TOPICSINFO_HH_INCLUDED__

#include <czmq.h>
#include <google/protobuf/message.h>
#include <list>
#include <string>
#include <vector>
#include "ignition/transport/SubscriptionHandler.hh"
#include "ignition/transport/TransportTypes.hh"

namespace ignition
{
  namespace transport
  {
    // Info about a topic for pub/sub
    class TopicInfo
    {
      /// \brief Constructor.
      public: TopicInfo();

      /// \brief Destructor.
      public: virtual ~TopicInfo();

      /// \brief List of addresses known for a topic.
      public: Topics_L addresses;

      /// \brief Am I connected to the topic?
      public: bool connected;

      /// \brief Am I advertising this topic?
      public: bool advertisedByMe;

      /// brief Am I subscribed to the topic?
      public: bool subscribed;

      /// brief Is a service call pending?
      public: bool requested;

      /// brief Callback to handle service calls requested by other nodes.
      public: ReqCallback reqCb;

      /// brief Callback to manage the service call's response requested by me.
      public: RepCallback repCb;

      /// \brief Beacon used to periodically advertise this topic.
      public: zbeacon_t *beacon;

      /// \brief List that stores the pending service call requests. Every
      /// element of the list contains the serialized parameters for each
      /// request.
      public: std::list<std::string> pendingReqs;

      /// \brief Registers the number of subscribers to this topic.
      public: unsigned int numSubscribers;

      /// \brief Stores all the subscribers information for this topic.
      public: ISubscriptionHandler_M subscriptionHandlers;
    };

    class TopicsInfo
    {
      /// \brief Constructor.
      public: TopicsInfo();

      /// \brief Destructor.
      public: virtual ~TopicsInfo();

      /// \brief Return if there is some information about a topic stored.
      /// \param[in] _topic Topic name.
      /// \return true If there is information about the topic.
      public: bool HasTopic(const std::string &_topic);

      /// \brief Get the known list of addresses associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[out] _addresses List of addresses
      /// \return true when we have info about this topic.
      public: bool GetAdvAddresses(const std::string &_topic,
                                   std::vector<std::string> &_addresses);

      /// \brief Return if an address is registered associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _address Address to check.
      /// \return true if the address is registered with the topic.
      public: bool HasAdvAddress(const std::string &_topic,
                                 const std::string &_address);

      /// \brief Return true if we are connected to a node
      /// advertising the topic.
      /// \param[in] _topic Topic name.
      /// \return true if we are connected.
      public: bool Connected(const std::string &_topic);

      /// \brief Return true if we are subscribed to a node advertising
      /// the topic.
      /// \param[in] _topic Topic name.
      /// \return true if we are subscribed.
      public: bool Subscribed(const std::string &_topic);

      /// \brief Return true if I am advertising the topic.
      /// \param[in] _topic Topic name.
      /// \return true if the topic is advertised by me.
      public: bool AdvertisedByMe(const std::string &_topic);

      /// \brief Return true if I am requesting the service call associated to
      /// the topic.
      /// \param[in] _topic Topic name.
      /// \return true if the service call associated to the topic is requested.
      public: bool Requested(const std::string &_topic);

      /// \brief Get the beacon used to advertise the topic
      /// \param[in] _topic Topic name.
      /// \param[out] _beacon Beacon used to advertise the topic.
      /// \return true if there is a beacon associated to the topicS.
      public: bool GetBeacon(const std::string &_topic, zbeacon_t **_beacon);

      /// \brief Get the REQ callback associated to a topic subscription.
      /// \param[in] _topic Topic name.
      /// \param[out] A pointer to the REQ function registered for a topic.
      /// \return true if there is a REQ callback registered for the topic.
      public: bool GetReqCallback(const std::string &_topic,
                                  transport::ReqCallback &_cb);

      /// \brief Get the REP callback associated to a topic subscription.
      /// \param[in] _topic Topic name.
      /// \param[out] A pointer to the REP function registered for a topic.
      /// \return true if there is a REP callback registered for the topic.
      public: bool GetRepCallback(const std::string &_topic,
                                  transport::RepCallback &_cb);

      /// \brief Returns if there are any pending requests in the queue.
      /// \param[in] _topic Topic name.
      /// \return true if there is any pending request in the queue.
      public: bool PendingReqs(const std::string &_topic);

      /// \brief Add a new address associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _address New address
      public: void AddAdvAddress(const std::string &_topic,
                                 const std::string &_address);

      /// \brief Remove an address associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[int] _address Address to remove.
      public: void RemoveAdvAddress(const std::string &_topic,
                                    const std::string &_address);

      /// \brief Set a new connected value to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned to the connected member.
      public: void SetConnected(const std::string &_topic, const bool _value);

      /// \brief Set a new subscribed value to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned to the subscribed member.
      public: void SetSubscribed(const std::string &_topic, const bool _value);

      /// \brief Set a new service call request to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned to the requested member.
      public: void SetRequested(const std::string &_topic, const bool _value);

      /// \brief Set a new advertised value to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _value New value to be assigned in advertisedByMe member.
      public: void SetAdvertisedByMe(const std::string &_topic,
                                     const bool _value);

      /// \brief Set the beacon used to advertise the topic
      /// \param[in] _topic Topic name.
      /// \param[in] _beacon Beacon used to advertise the topic.
      /// \return true if there is a beacon associated to the topicS.
      public: void SetBeacon(const std::string &_topic,
                             zbeacon_t *_beacon);

      /// \brief Set a new REQ callback associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _cb New callback.
      public: void SetReqCallback(const std::string &_topic,
                                  const transport::ReqCallback &_cb);

      /// \brief Set a new REP callback associated to a given topic.
      /// \param[in] _topic Topic name.
      /// \param[in] _cb New callback.
      public: void SetRepCallback(const std::string &_topic,
                                  const transport::RepCallback &_cb);

      /// \brief Add a new service call request to the queue.
      /// \param[in] _topic Topic name.
      /// \param[in] _data Parameters of the request.
      public: void AddReq(const std::string &_topic, const std::string &_data);

      /// \brief Add a new service call request to the queue.
      /// \param[in] _topic Topic name.
      /// \param[out] _data Parameters of the request.
      /// \return true if a request was removed.
      public: bool DelReq(const std::string &_topic, std::string &_data);

      /// \brief Check if a topic has a remote subscriber in this node.
      /// \param[in] _topic Topic name.
      /// \return true if a topic has a remote subscriber in this node.
      public: bool HasRemoteSubscribers(const std::string &_topic);

      /// \brief Increment the counter of remote susbscribers for a topic.
      /// \param[in] _topic Topic name.
      public: void AddRemoteSubscriber(const std::string &_topic);

      /// \brief Get the subscription handlers for a topic. A subscription
      /// handler stores the callback and types associated to a subscription.
      /// \param[in] _topic Topic name.
      /// \param[out] _handlers Subscription handlers.
      public: void GetSubscriptionHandlers(const std::string &_topic,
                                  transport::ISubscriptionHandler_M &_handlers);

      /// \brief Add a subscription handler to a topic. A subscription handler
      /// stores the callback and types associated to a subscription.
      /// \param[in] _topic Topic name.
      /// \param[in] _handlers Subscription handler.
      public: void AddSubscriptionHandler(const std::string &_topic,
                                        const ISubscriptionHandlerPtr &_msgPtr);

      /// \brief Check if a topic has a subscription handler.
      /// \param[in] _topic Topic name.
      /// \return true if the topic has a subscription handler registered.
      public: bool HasSubscriptionHandler(const std::string &_topic);

      /// \brief Get a reference to the topics map.
      /// \return Reference to the topic map.
      public: transport::Topics_M& GetTopicsInfo();

      /// \brief Check if the topic exists. If not, the topic is created.
      /// \param[in] _topic Topic name.
      private: void CheckAndCreate(const std::string &_topic);

      // Hash with the topic/topicInfo information for pub/sub.
      private: transport::Topics_M topicsInfo;
    };
  }
}

#endif
<|endoftext|>