From 3b4a308ff647def75e647ac8f97e1e48b57672c3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 24 Jul 2007 19:26:47 +0000 Subject: Consistently rename all C++ files .cpp/.hpp. Fix (some) inclusion guard names to not clash with other libs. git-svn-id: http://svn.drobilla.net/lad/raul@613 a436a847-0d15-0410-975c-d299462d15a1 --- raul/Array.h | 110 -------- raul/Array.hpp | 110 ++++++++ raul/Atom.h | 136 ---------- raul/Atom.hpp | 136 ++++++++++ raul/AtomLiblo.h | 80 ------ raul/AtomLiblo.hpp | 80 ++++++ raul/AtomRedland.h | 107 -------- raul/AtomRedland.hpp | 107 ++++++++ raul/AtomicInt.h | 84 ------- raul/AtomicInt.hpp | 84 +++++++ raul/AtomicPtr.h | 53 ---- raul/AtomicPtr.hpp | 53 ++++ raul/Deletable.h | 38 --- raul/Deletable.hpp | 38 +++ raul/DoubleBuffer.h | 97 ------- raul/DoubleBuffer.hpp | 97 +++++++ raul/JackDriver.h | 122 --------- raul/JackDriver.hpp | 122 +++++++++ raul/LashClient.h | 60 ----- raul/LashClient.hpp | 60 +++++ raul/LashProject.h | 60 ----- raul/LashProject.hpp | 60 +++++ raul/LashServerInterface.h | 63 ----- raul/LashServerInterface.hpp | 63 +++++ raul/List.h | 544 ---------------------------------------- raul/List.hpp | 544 ++++++++++++++++++++++++++++++++++++++++ raul/MIDISink.h | 41 --- raul/MIDISink.hpp | 41 +++ raul/Maid.h | 76 ------ raul/Maid.hpp | 76 ++++++ raul/Makefile.am | 70 +++--- raul/Namespaces.h | 37 --- raul/Namespaces.hpp | 37 +++ raul/Path.h | 128 ---------- raul/Path.hpp | 128 ++++++++++ raul/Process.h | 92 ------- raul/Process.hpp | 92 +++++++ raul/Quantizer.h | 36 --- raul/Quantizer.hpp | 36 +++ raul/RDFModel.h | 82 ------ raul/RDFModel.hpp | 82 ++++++ raul/RDFNode.h | 79 ------ raul/RDFNode.hpp | 79 ++++++ raul/RDFQuery.h | 68 ----- raul/RDFQuery.hpp | 68 +++++ raul/RDFWorld.h | 60 ----- raul/RDFWorld.hpp | 60 +++++ raul/RingBuffer.h | 163 ------------ raul/RingBuffer.hpp | 163 ++++++++++++ raul/SMFReader.h | 71 ------ raul/SMFReader.hpp | 71 ++++++ raul/SMFWriter.h | 72 ------ raul/SMFWriter.hpp | 72 ++++++ raul/SRMWQueue.h | 224 ----------------- raul/SRMWQueue.hpp | 224 +++++++++++++++++ raul/SRSWQueue.h | 157 ------------ raul/SRSWQueue.hpp | 157 ++++++++++++ raul/Semaphore.h | 75 ------ raul/Semaphore.hpp | 75 ++++++ raul/SharedPtr.h | 63 ----- raul/SharedPtr.hpp | 63 +++++ raul/Slave.h | 67 ----- raul/Slave.hpp | 67 +++++ raul/StampedChunkRingBuffer.h | 83 ------ raul/StampedChunkRingBuffer.hpp | 83 ++++++ raul/Stateful.h | 42 ---- raul/Stateful.hpp | 42 ++++ raul/Thread.h | 107 -------- raul/Thread.hpp | 107 ++++++++ raul/TimeSlice.h | 159 ------------ raul/TimeSlice.hpp | 159 ++++++++++++ raul/WeakPtr.h | 26 -- raul/WeakPtr.hpp | 26 ++ raul/midi_events.h | 6 +- raul/midi_names.h | 14 +- raul/types.h | 35 --- raul/types.hpp | 35 +++ src/JackDriver.cpp | 2 +- src/LashClient.cpp | 2 +- src/LashProject.cpp | 2 +- src/LashServerInterface.cpp | 2 +- src/Maid.cpp | 4 +- src/Namespaces.cpp | 2 +- src/Path.cpp | 2 +- src/RDFModel.cpp | 8 +- src/RDFNode.cpp | 4 +- src/RDFQuery.cpp | 4 +- src/RDFWorld.cpp | 6 +- src/SMFReader.cpp | 4 +- src/SMFWriter.cpp | 2 +- src/Thread.cpp | 2 +- src/TimeSlice.cpp | 2 +- 92 files changed, 3670 insertions(+), 3662 deletions(-) delete mode 100644 raul/Array.h create mode 100644 raul/Array.hpp delete mode 100644 raul/Atom.h create mode 100644 raul/Atom.hpp delete mode 100644 raul/AtomLiblo.h create mode 100644 raul/AtomLiblo.hpp delete mode 100644 raul/AtomRedland.h create mode 100644 raul/AtomRedland.hpp delete mode 100644 raul/AtomicInt.h create mode 100644 raul/AtomicInt.hpp delete mode 100644 raul/AtomicPtr.h create mode 100644 raul/AtomicPtr.hpp delete mode 100644 raul/Deletable.h create mode 100644 raul/Deletable.hpp delete mode 100644 raul/DoubleBuffer.h create mode 100644 raul/DoubleBuffer.hpp delete mode 100644 raul/JackDriver.h create mode 100644 raul/JackDriver.hpp delete mode 100644 raul/LashClient.h create mode 100644 raul/LashClient.hpp delete mode 100644 raul/LashProject.h create mode 100644 raul/LashProject.hpp delete mode 100644 raul/LashServerInterface.h create mode 100644 raul/LashServerInterface.hpp delete mode 100644 raul/List.h create mode 100644 raul/List.hpp delete mode 100644 raul/MIDISink.h create mode 100644 raul/MIDISink.hpp delete mode 100644 raul/Maid.h create mode 100644 raul/Maid.hpp delete mode 100644 raul/Namespaces.h create mode 100644 raul/Namespaces.hpp delete mode 100644 raul/Path.h create mode 100644 raul/Path.hpp delete mode 100644 raul/Process.h create mode 100644 raul/Process.hpp delete mode 100644 raul/Quantizer.h create mode 100644 raul/Quantizer.hpp delete mode 100644 raul/RDFModel.h create mode 100644 raul/RDFModel.hpp delete mode 100644 raul/RDFNode.h create mode 100644 raul/RDFNode.hpp delete mode 100644 raul/RDFQuery.h create mode 100644 raul/RDFQuery.hpp delete mode 100644 raul/RDFWorld.h create mode 100644 raul/RDFWorld.hpp delete mode 100644 raul/RingBuffer.h create mode 100644 raul/RingBuffer.hpp delete mode 100644 raul/SMFReader.h create mode 100644 raul/SMFReader.hpp delete mode 100644 raul/SMFWriter.h create mode 100644 raul/SMFWriter.hpp delete mode 100644 raul/SRMWQueue.h create mode 100644 raul/SRMWQueue.hpp delete mode 100644 raul/SRSWQueue.h create mode 100644 raul/SRSWQueue.hpp delete mode 100644 raul/Semaphore.h create mode 100644 raul/Semaphore.hpp delete mode 100644 raul/SharedPtr.h create mode 100644 raul/SharedPtr.hpp delete mode 100644 raul/Slave.h create mode 100644 raul/Slave.hpp delete mode 100644 raul/StampedChunkRingBuffer.h create mode 100644 raul/StampedChunkRingBuffer.hpp delete mode 100644 raul/Stateful.h create mode 100644 raul/Stateful.hpp delete mode 100644 raul/Thread.h create mode 100644 raul/Thread.hpp delete mode 100644 raul/TimeSlice.h create mode 100644 raul/TimeSlice.hpp delete mode 100644 raul/WeakPtr.h create mode 100644 raul/WeakPtr.hpp delete mode 100644 raul/types.h create mode 100644 raul/types.hpp diff --git a/raul/Array.h b/raul/Array.h deleted file mode 100644 index aa6aa70..0000000 --- a/raul/Array.h +++ /dev/null @@ -1,110 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_ARRAY_H -#define RAUL_ARRAY_H - -#include -#include -#include "types.h" -#include "Deletable.h" - -namespace Raul { - - -/** An array. - * - * Has a stack-like push_back() too, for find_process_order... - */ -template -class Array : public Deletable -{ -public: - Array(size_t size = 0) : _size(size), _top(0), _elems(NULL) { - if (size > 0) - _elems = new T[size]; - } - - Array(size_t size, T initial_value) : _size(size), _top(0), _elems(NULL) { - if (size > 0) { - _elems = new T[size]; - for (size_t i=0; i < size; ++i) - _elems[i] = initial_value; - } - } - - Array(size_t size, const Array& contents) : _size(size), _top(size+1) { - _elems = new T[size]; - if (size <= contents.size()) - memcpy(_elems, contents._elems, size * sizeof(T)); - else - memcpy(_elems, contents._elems, contents.size() * sizeof(T)); - } - - ~Array() { - free(); - } - - void alloc(size_t num_elems) { - assert(num_elems > 0); - - delete[] _elems; - _size = num_elems; - _top = 0; - - _elems = new T[num_elems]; - } - - void alloc(size_t num_elems, T initial_value) { - assert(num_elems > 0); - - delete[] _elems; - _size = num_elems; - _top = 0; - - _elems = new T[num_elems]; - for (size_t i=0; i < _size; ++i) - _elems[i] = initial_value; - } - - void free() { - delete[] _elems; - _size = 0; - _top = 0; - } - - void push_back(T n) { - assert(_top < _size); - _elems[_top++] = n; - } - - inline size_t size() const { return _size; } - - inline T& operator[](size_t i) const { assert(i < _size); return _elems[i]; } - - inline T& at(size_t i) const { assert(i < _size); return _elems[i]; } - -private: - size_t _size; - size_t _top; // points to empty element above "top" element - T* _elems; -}; - - -} // namespace Raul - -#endif // RAUL_ARRAY_H diff --git a/raul/Array.hpp b/raul/Array.hpp new file mode 100644 index 0000000..b972b87 --- /dev/null +++ b/raul/Array.hpp @@ -0,0 +1,110 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_ARRAY_HPP +#define RAUL_ARRAY_HPP + +#include +#include +#include "types.hpp" +#include "Deletable.hpp" + +namespace Raul { + + +/** An array. + * + * Has a stack-like push_back() too, for find_process_order... + */ +template +class Array : public Deletable +{ +public: + Array(size_t size = 0) : _size(size), _top(0), _elems(NULL) { + if (size > 0) + _elems = new T[size]; + } + + Array(size_t size, T initial_value) : _size(size), _top(0), _elems(NULL) { + if (size > 0) { + _elems = new T[size]; + for (size_t i=0; i < size; ++i) + _elems[i] = initial_value; + } + } + + Array(size_t size, const Array& contents) : _size(size), _top(size+1) { + _elems = new T[size]; + if (size <= contents.size()) + memcpy(_elems, contents._elems, size * sizeof(T)); + else + memcpy(_elems, contents._elems, contents.size() * sizeof(T)); + } + + ~Array() { + free(); + } + + void alloc(size_t num_elems) { + assert(num_elems > 0); + + delete[] _elems; + _size = num_elems; + _top = 0; + + _elems = new T[num_elems]; + } + + void alloc(size_t num_elems, T initial_value) { + assert(num_elems > 0); + + delete[] _elems; + _size = num_elems; + _top = 0; + + _elems = new T[num_elems]; + for (size_t i=0; i < _size; ++i) + _elems[i] = initial_value; + } + + void free() { + delete[] _elems; + _size = 0; + _top = 0; + } + + void push_back(T n) { + assert(_top < _size); + _elems[_top++] = n; + } + + inline size_t size() const { return _size; } + + inline T& operator[](size_t i) const { assert(i < _size); return _elems[i]; } + + inline T& at(size_t i) const { assert(i < _size); return _elems[i]; } + +private: + size_t _size; + size_t _top; // points to empty element above "top" element + T* _elems; +}; + + +} // namespace Raul + +#endif // RAUL_ARRAY_HPP diff --git a/raul/Atom.h b/raul/Atom.h deleted file mode 100644 index 2b9d800..0000000 --- a/raul/Atom.h +++ /dev/null @@ -1,136 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_ATOM_H -#define RAUL_ATOM_H - -#include -#include -#include -#include - -namespace Raul { - - -/** An OSC atom (fundamental data types OSC messages are composed of). - * - * \ingroup raul - */ -class Atom { -public: - - //TODO: Add a bool type here that serializes nicely to Turtle "true" and "false" - - enum Type { - NIL, - INT, - FLOAT, - STRING, - BLOB - }; - - Atom() : _type(NIL), _blob_val(0) {} - Atom(int32_t val) : _type(INT), _int_val(val) {} - Atom(float val) : _type(FLOAT), _float_val(val) {} - Atom(const char* val) : _type(STRING), _string_val(strdup(val)) {} - Atom(const std::string& val) : _type(STRING), _string_val(strdup(val.c_str())) {} - - Atom(void* val) : _type(BLOB), _blob_size(sizeof(val)), _blob_val(malloc(_blob_size)) - { memcpy(_blob_val, val, sizeof(_blob_size)); } - - ~Atom() - { - if (_type == STRING) - free(_string_val); - else if (_type == BLOB) - free(_blob_val); - } - - // Gotta love C++ boilerplate: - - Atom(const Atom& copy) - : _type(copy._type) - , _blob_size(copy._blob_size) - { - switch (_type) { - case NIL: _blob_val = 0; break; - case INT: _int_val = copy._int_val; break; - case FLOAT: _float_val = copy._float_val; break; - case STRING: _string_val = strdup(copy._string_val); break; - - case BLOB: _blob_val = malloc(_blob_size); - memcpy(_blob_val, copy._blob_val, _blob_size); - break; - - default: break; - } - } - - Atom& operator=(const Atom& other) - { - if (_type == BLOB) - free(_blob_val); - else if (_type == STRING) - free(_string_val); - - _type = other._type; - _blob_size = other._blob_size; - - switch (_type) { - case NIL: _blob_val = 0; break; - case INT: _int_val = other._int_val; break; - case FLOAT: _float_val = other._float_val; break; - case STRING: _string_val = strdup(other._string_val); break; - - case BLOB: _blob_val = malloc(_blob_size); - memcpy(_blob_val, other._blob_val, _blob_size); - break; - - default: break; - } - return *this; - } - - /** Type of this atom. Always check this before attempting to get the - * value - attempting to get the incorrectly typed value is a fatal error. - */ - Type type() const { return _type; } - - inline int32_t get_int32() const { assert(_type == INT); return _int_val; } - inline float get_float() const { assert(_type == FLOAT); return _float_val; } - inline const char* get_string() const { assert(_type == STRING); return _string_val; } - inline const void* get_blob() const { assert(_type == BLOB); return _blob_val; } - - inline operator bool() const { return (_type != NIL); } - -private: - Type _type; - - size_t _blob_size; ///< always a multiple of 32 - - union { - int32_t _int_val; - float _float_val; - char* _string_val; - void* _blob_val; - }; -}; - - -} // namespace Raul - -#endif // RAUL_ATOM_H diff --git a/raul/Atom.hpp b/raul/Atom.hpp new file mode 100644 index 0000000..4b9e6a8 --- /dev/null +++ b/raul/Atom.hpp @@ -0,0 +1,136 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_ATOM_HPP +#define RAUL_ATOM_HPP + +#include +#include +#include +#include + +namespace Raul { + + +/** An OSC atom (fundamental data types OSC messages are composed of). + * + * \ingroup raul + */ +class Atom { +public: + + //TODO: Add a bool type here that serializes nicely to Turtle "true" and "false" + + enum Type { + NIL, + INT, + FLOAT, + STRING, + BLOB + }; + + Atom() : _type(NIL), _blob_val(0) {} + Atom(int32_t val) : _type(INT), _int_val(val) {} + Atom(float val) : _type(FLOAT), _float_val(val) {} + Atom(const char* val) : _type(STRING), _string_val(strdup(val)) {} + Atom(const std::string& val) : _type(STRING), _string_val(strdup(val.c_str())) {} + + Atom(void* val) : _type(BLOB), _blob_size(sizeof(val)), _blob_val(malloc(_blob_size)) + { memcpy(_blob_val, val, sizeof(_blob_size)); } + + ~Atom() + { + if (_type == STRING) + free(_string_val); + else if (_type == BLOB) + free(_blob_val); + } + + // Gotta love C++ boilerplate: + + Atom(const Atom& copy) + : _type(copy._type) + , _blob_size(copy._blob_size) + { + switch (_type) { + case NIL: _blob_val = 0; break; + case INT: _int_val = copy._int_val; break; + case FLOAT: _float_val = copy._float_val; break; + case STRING: _string_val = strdup(copy._string_val); break; + + case BLOB: _blob_val = malloc(_blob_size); + memcpy(_blob_val, copy._blob_val, _blob_size); + break; + + default: break; + } + } + + Atom& operator=(const Atom& other) + { + if (_type == BLOB) + free(_blob_val); + else if (_type == STRING) + free(_string_val); + + _type = other._type; + _blob_size = other._blob_size; + + switch (_type) { + case NIL: _blob_val = 0; break; + case INT: _int_val = other._int_val; break; + case FLOAT: _float_val = other._float_val; break; + case STRING: _string_val = strdup(other._string_val); break; + + case BLOB: _blob_val = malloc(_blob_size); + memcpy(_blob_val, other._blob_val, _blob_size); + break; + + default: break; + } + return *this; + } + + /** Type of this atom. Always check this before attempting to get the + * value - attempting to get the incorrectly typed value is a fatal error. + */ + Type type() const { return _type; } + + inline int32_t get_int32() const { assert(_type == INT); return _int_val; } + inline float get_float() const { assert(_type == FLOAT); return _float_val; } + inline const char* get_string() const { assert(_type == STRING); return _string_val; } + inline const void* get_blob() const { assert(_type == BLOB); return _blob_val; } + + inline operator bool() const { return (_type != NIL); } + +private: + Type _type; + + size_t _blob_size; ///< always a multiple of 32 + + union { + int32_t _int_val; + float _float_val; + char* _string_val; + void* _blob_val; + }; +}; + + +} // namespace Raul + +#endif // RAUL_ATOM_HPP diff --git a/raul/AtomLiblo.h b/raul/AtomLiblo.h deleted file mode 100644 index eecc417..0000000 --- a/raul/AtomLiblo.h +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_ATOM_LIBLO_H -#define RAUL_ATOM_LIBLO_H - -#include -#include "raul/Atom.h" - -namespace Raul { - - -/** Support for serializing an Atom to/from liblo messages. - * - * (Here to prevent a unnecessary liblo dependency for Atom). - * - * \ingroup raul - */ -class AtomLiblo { -public: - static void lo_message_add_atom(lo_message m, const Atom& atom) { - switch (atom.type()) { - //case NIL: - // (see below) - //break; - case Atom::INT: - lo_message_add_int32(m, atom.get_int32()); - break; - case Atom::FLOAT: - lo_message_add_float(m, atom.get_float()); - break; - case Atom::STRING: - lo_message_add_string(m, atom.get_string()); - break; - case Atom::BLOB: - // FIXME: is this okay? what does liblo do? - lo_message_add_blob(m, const_cast(atom.get_blob())); - break; - default: // This catches Atom::Type::NIL too - lo_message_add_nil(m); - break; - } - } - - static Atom lo_arg_to_atom(char type, lo_arg* arg) { - switch (type) { - case 'i': - return Atom(arg->i); - case 'f': - return Atom(arg->f); - case 's': - return Atom(&arg->s); - //case 'b' - // FIXME: How to get a blob from a lo_arg? - //return Atom(arg->b); - default: - return Atom(); - } - } - -}; - - -} // namespace Raul - -#endif // RAUL_ATOM_LIBLO_H diff --git a/raul/AtomLiblo.hpp b/raul/AtomLiblo.hpp new file mode 100644 index 0000000..88adf1a --- /dev/null +++ b/raul/AtomLiblo.hpp @@ -0,0 +1,80 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_ATOM_LIBLO_HPP +#define RAUL_ATOM_LIBLO_HPP + +#include +#include + +namespace Raul { + + +/** Support for serializing an Atom to/from liblo messages. + * + * (Here to prevent a unnecessary liblo dependency for Atom). + * + * \ingroup raul + */ +class AtomLiblo { +public: + static void lo_message_add_atom(lo_message m, const Atom& atom) { + switch (atom.type()) { + //case NIL: + // (see below) + //break; + case Atom::INT: + lo_message_add_int32(m, atom.get_int32()); + break; + case Atom::FLOAT: + lo_message_add_float(m, atom.get_float()); + break; + case Atom::STRING: + lo_message_add_string(m, atom.get_string()); + break; + case Atom::BLOB: + // FIXME: is this okay? what does liblo do? + lo_message_add_blob(m, const_cast(atom.get_blob())); + break; + default: // This catches Atom::Type::NIL too + lo_message_add_nil(m); + break; + } + } + + static Atom lo_arg_to_atom(char type, lo_arg* arg) { + switch (type) { + case 'i': + return Atom(arg->i); + case 'f': + return Atom(arg->f); + case 's': + return Atom(&arg->s); + //case 'b' + // FIXME: How to get a blob from a lo_arg? + //return Atom(arg->b); + default: + return Atom(); + } + } + +}; + + +} // namespace Raul + +#endif // RAUL_ATOM_LIBLO_HPP diff --git a/raul/AtomRedland.h b/raul/AtomRedland.h deleted file mode 100644 index ae4e3b4..0000000 --- a/raul/AtomRedland.h +++ /dev/null @@ -1,107 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_ATOM_REDLAND_H -#define RAUL_ATOM_REDLAND_H - -#include -#include -#include -#include -#include "raul/Atom.h" -using std::cerr; using std::endl; - -#define U(x) ((const unsigned char*)(x)) - -namespace Raul { - - -/** Support for serializing an Atom to/from RDF (via librdf). - * - * (Here to prevent a unnecessary reddland dependency for Atom). - * - * \ingroup raul - */ -class AtomRedland { -public: - /** Set this atom's value to the object (value) portion of an RDF triple. - * - * Caller is responsible for calling free(triple->object). - */ - static librdf_node* atom_to_rdf_node(librdf_world* world, - const Atom& atom) - { - std::ostringstream os; - - librdf_uri* type = NULL; - librdf_node* node = NULL; - std::string str; - - switch (atom.type()) { - case Atom::INT: - os << atom.get_int32(); - str = os.str(); - // xsd:integer -> pretty integer literals in Turtle - type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#integer")); - break; - case Atom::FLOAT: - os << atom.get_float(); - str = os.str(); - // xsd:decimal -> pretty decimal (float) literals in Turtle - type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#decimal")); - break; - case Atom::STRING: - str = atom.get_string(); - break; - case Atom::BLOB: - case Atom::NIL: - default: - cerr << "WARNING: Unserializable Atom!" << endl; - } - - if (str != "") - node = librdf_new_node_from_typed_literal(world, U(str.c_str()), NULL, type); - - return node; - } - -#if 0 - static Atom node_to_atom(librdf_node* node) { - /*switch (type) { - case 'i': - return Atom(arg->i); - case 'f': - return Atom(arg->f); - case 's': - return Atom(&arg->s); - //case 'b' - // FIXME: How to get a blob from a lo_arg? - //return Atom(arg->b); - default: - return Atom(); - }*/ - cerr << "FIXME: node_to_atom\n"; - return Atom(); - } -#endif - -}; - - -} // namespace Raul - -#endif // RAUL_ATOM_REDLAND_H diff --git a/raul/AtomRedland.hpp b/raul/AtomRedland.hpp new file mode 100644 index 0000000..09bf276 --- /dev/null +++ b/raul/AtomRedland.hpp @@ -0,0 +1,107 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_ATOM_REDLAND_HPP +#define RAUL_ATOM_REDLAND_HPP + +#include +#include +#include +#include +#include +using std::cerr; using std::endl; + +#define U(x) ((const unsigned char*)(x)) + +namespace Raul { + + +/** Support for serializing an Atom to/from RDF (via librdf). + * + * (Here to prevent a unnecessary reddland dependency for Atom). + * + * \ingroup raul + */ +class AtomRedland { +public: + /** Set this atom's value to the object (value) portion of an RDF triple. + * + * Caller is responsible for calling free(triple->object). + */ + static librdf_node* atom_to_rdf_node(librdf_world* world, + const Atom& atom) + { + std::ostringstream os; + + librdf_uri* type = NULL; + librdf_node* node = NULL; + std::string str; + + switch (atom.type()) { + case Atom::INT: + os << atom.get_int32(); + str = os.str(); + // xsd:integer -> pretty integer literals in Turtle + type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#integer")); + break; + case Atom::FLOAT: + os << atom.get_float(); + str = os.str(); + // xsd:decimal -> pretty decimal (float) literals in Turtle + type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#decimal")); + break; + case Atom::STRING: + str = atom.get_string(); + break; + case Atom::BLOB: + case Atom::NIL: + default: + cerr << "WARNING: Unserializable Atom!" << endl; + } + + if (str != "") + node = librdf_new_node_from_typed_literal(world, U(str.c_str()), NULL, type); + + return node; + } + +#if 0 + static Atom node_to_atom(librdf_node* node) { + /*switch (type) { + case 'i': + return Atom(arg->i); + case 'f': + return Atom(arg->f); + case 's': + return Atom(&arg->s); + //case 'b' + // FIXME: How to get a blob from a lo_arg? + //return Atom(arg->b); + default: + return Atom(); + }*/ + cerr << "FIXME: node_to_atom\n"; + return Atom(); + } +#endif + +}; + + +} // namespace Raul + +#endif // RAUL_ATOM_REDLAND_HPP diff --git a/raul/AtomicInt.h b/raul/AtomicInt.h deleted file mode 100644 index d83a63b..0000000 --- a/raul/AtomicInt.h +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_ATOMIC_INT_H -#define RAUL_ATOMIC_INT_H - -#include - -namespace Raul { - - -class AtomicInt { -public: - - inline AtomicInt(int val) - { g_atomic_int_set(&_val, val); } - - inline AtomicInt(const AtomicInt& copy) - { g_atomic_int_set(&_val, copy.get()); } - - inline int get() const - { return g_atomic_int_get(&_val); } - - inline void operator=(int val) - { g_atomic_int_set(&_val, val); } - - inline void operator+=(int val) - { g_atomic_int_add(&_val, val); } - - inline void operator-=(int val) - { g_atomic_int_add(&_val, -val); } - - inline bool operator==(int val) const - { return get() == val; } - - inline int operator+(int val) const - { return get() + val; } - - inline AtomicInt& operator++() // prefix - { g_atomic_int_inc(&_val); return *this; } - - inline AtomicInt& operator--() // prefix - { g_atomic_int_add(&_val, -1); return *this; } - - /** Set value to newval iff current value is oldval. - * @return whether set succeeded. - */ - inline bool compare_and_exchange(int oldval, int newval) - { return g_atomic_int_compare_and_exchange(&_val, oldval, newval); } - - /** Add val to value. - * @return value immediately before addition took place. - */ - inline int exchange_and_add(int val) - { return g_atomic_int_exchange_and_add(&_val, val); } - - /** Decrement value. - * @return true if value is now 0, otherwise false. - */ - inline bool decrement_and_test() - { return g_atomic_int_dec_and_test(&_val); } - -private: - volatile int _val; -}; - - -} // namespace Raul - -#endif // RAUL_ATOMIC_INT_H diff --git a/raul/AtomicInt.hpp b/raul/AtomicInt.hpp new file mode 100644 index 0000000..70191cb --- /dev/null +++ b/raul/AtomicInt.hpp @@ -0,0 +1,84 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_ATOMIC_INT_HPP +#define RAUL_ATOMIC_INT_HPP + +#include + +namespace Raul { + + +class AtomicInt { +public: + + inline AtomicInt(int val) + { g_atomic_int_set(&_val, val); } + + inline AtomicInt(const AtomicInt& copy) + { g_atomic_int_set(&_val, copy.get()); } + + inline int get() const + { return g_atomic_int_get(&_val); } + + inline void operator=(int val) + { g_atomic_int_set(&_val, val); } + + inline void operator+=(int val) + { g_atomic_int_add(&_val, val); } + + inline void operator-=(int val) + { g_atomic_int_add(&_val, -val); } + + inline bool operator==(int val) const + { return get() == val; } + + inline int operator+(int val) const + { return get() + val; } + + inline AtomicInt& operator++() // prefix + { g_atomic_int_inc(&_val); return *this; } + + inline AtomicInt& operator--() // prefix + { g_atomic_int_add(&_val, -1); return *this; } + + /** Set value to newval iff current value is oldval. + * @return whether set succeeded. + */ + inline bool compare_and_exchange(int oldval, int newval) + { return g_atomic_int_compare_and_exchange(&_val, oldval, newval); } + + /** Add val to value. + * @return value immediately before addition took place. + */ + inline int exchange_and_add(int val) + { return g_atomic_int_exchange_and_add(&_val, val); } + + /** Decrement value. + * @return true if value is now 0, otherwise false. + */ + inline bool decrement_and_test() + { return g_atomic_int_dec_and_test(&_val); } + +private: + volatile int _val; +}; + + +} // namespace Raul + +#endif // RAUL_ATOMIC_INT_HPP diff --git a/raul/AtomicPtr.h b/raul/AtomicPtr.h deleted file mode 100644 index bc24f59..0000000 --- a/raul/AtomicPtr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_ATOMIC_PTR_H -#define RAUL_ATOMIC_PTR_H - -#include - -namespace Raul { - - -template -class AtomicPtr { -public: - - inline AtomicPtr() - { g_atomic_pointer_set(&_val, NULL); } - - inline AtomicPtr(const AtomicPtr& copy) - { g_atomic_pointer_set(&_val, copy.get()); } - - inline T* get() const - { return (T*)g_atomic_pointer_get(&_val); } - - inline void operator=(T* val) - { g_atomic_pointer_set(&_val, val); } - - /** Set value to newval iff current value is oldval */ - inline bool compare_and_exchange(int oldval, int newval) - { return g_atomic_pointer_compare_and_exchange(&_val, oldval, newval); } - -private: - volatile T* _val; -}; - - -} // namespace Raul - -#endif // RAUL_ATOMIC_PTR_H diff --git a/raul/AtomicPtr.hpp b/raul/AtomicPtr.hpp new file mode 100644 index 0000000..82be18a --- /dev/null +++ b/raul/AtomicPtr.hpp @@ -0,0 +1,53 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_ATOMIC_PTR_HPP +#define RAUL_ATOMIC_PTR_HPP + +#include + +namespace Raul { + + +template +class AtomicPtr { +public: + + inline AtomicPtr() + { g_atomic_pointer_set(&_val, NULL); } + + inline AtomicPtr(const AtomicPtr& copy) + { g_atomic_pointer_set(&_val, copy.get()); } + + inline T* get() const + { return (T*)g_atomic_pointer_get(&_val); } + + inline void operator=(T* val) + { g_atomic_pointer_set(&_val, val); } + + /** Set value to newval iff current value is oldval */ + inline bool compare_and_exchange(int oldval, int newval) + { return g_atomic_pointer_compare_and_exchange(&_val, oldval, newval); } + +private: + volatile T* _val; +}; + + +} // namespace Raul + +#endif // RAUL_ATOMIC_PTR_HPP diff --git a/raul/Deletable.h b/raul/Deletable.h deleted file mode 100644 index 1e47279..0000000 --- a/raul/Deletable.h +++ /dev/null @@ -1,38 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_DELETABLE_H -#define RAUL_DELETABLE_H - -namespace Raul { - - -/** Something with a virtual destructor. - * - * \ingroup raul - */ -class Deletable -{ -public: - Deletable() {} - virtual ~Deletable() {} -}; - - -} // namespace Raul - -#endif // RAUL_DELETABLE_H diff --git a/raul/Deletable.hpp b/raul/Deletable.hpp new file mode 100644 index 0000000..6431c36 --- /dev/null +++ b/raul/Deletable.hpp @@ -0,0 +1,38 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_DELETABLE_HPP +#define RAUL_DELETABLE_HPP + +namespace Raul { + + +/** Something with a virtual destructor. + * + * \ingroup raul + */ +class Deletable +{ +public: + Deletable() {} + virtual ~Deletable() {} +}; + + +} // namespace Raul + +#endif // RAUL_DELETABLE_HPP diff --git a/raul/DoubleBuffer.h b/raul/DoubleBuffer.h deleted file mode 100644 index 8b0f340..0000000 --- a/raul/DoubleBuffer.h +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_DOUBLE_BUFFER_H -#define RAUL_DOUBLE_BUFFER_H - -#include -#include -#include - -namespace Raul { - -/** Double buffer. - * - * Can be thought of as a wrapper class to make a non-atomic type atomically - * settable (with no locking). - * - * Read/Write realtime safe, many writers safe - but set calls may fail. - * - * Space: 2*sizeof(T) + sizeof(int) + sizeof(void*) - */ -template -class DoubleBuffer : public boost::noncopyable { -public: - - inline DoubleBuffer(T val) - : _state(READ_WRITE) - { - _vals[0] = val; - _read_val = &_vals[0]; - } - - inline T& get() - { - return *_read_val.get(); - } - - inline bool set(T new_val) - { - if (_state.compare_and_exchange(READ_WRITE, READ_LOCK)) { - - // locked _vals[1] for write - _vals[1] = new_val; - _read_val = &_vals[1]; - _state = WRITE_READ; - return true; - - // concurrent calls here are fine. good, actually - caught - // the WRITE_READ state immediately after it was set above - - } else if (_state.compare_and_exchange(WRITE_READ, LOCK_READ)) { - - // locked _vals[0] for write - _vals[0] = new_val; - _read_val = &_vals[0]; - _state = READ_WRITE; - return true; - - } else { - - return false; - - } - } - -private: - enum States { - // vals[0] state _ vals[1] state - READ_WRITE = 0, - READ_LOCK, - WRITE_READ, - LOCK_READ - }; - - AtomicInt _state; - AtomicPtr _read_val; - T _vals[2]; -}; - - -} // namespace Raul - -#endif // RAUL_DOUBLE_BUFFER_H diff --git a/raul/DoubleBuffer.hpp b/raul/DoubleBuffer.hpp new file mode 100644 index 0000000..dd50e6a --- /dev/null +++ b/raul/DoubleBuffer.hpp @@ -0,0 +1,97 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_DOUBLE_BUFFER_HPP +#define RAUL_DOUBLE_BUFFER_HPP + +#include +#include +#include + +namespace Raul { + +/** Double buffer. + * + * Can be thought of as a wrapper class to make a non-atomic type atomically + * settable (with no locking). + * + * Read/Write realtime safe, many writers safe - but set calls may fail. + * + * Space: 2*sizeof(T) + sizeof(int) + sizeof(void*) + */ +template +class DoubleBuffer : public boost::noncopyable { +public: + + inline DoubleBuffer(T val) + : _state(READ_WRITE) + { + _vals[0] = val; + _read_val = &_vals[0]; + } + + inline T& get() + { + return *_read_val.get(); + } + + inline bool set(T new_val) + { + if (_state.compare_and_exchange(READ_WRITE, READ_LOCK)) { + + // locked _vals[1] for write + _vals[1] = new_val; + _read_val = &_vals[1]; + _state = WRITE_READ; + return true; + + // concurrent calls here are fine. good, actually - caught + // the WRITE_READ state immediately after it was set above + + } else if (_state.compare_and_exchange(WRITE_READ, LOCK_READ)) { + + // locked _vals[0] for write + _vals[0] = new_val; + _read_val = &_vals[0]; + _state = READ_WRITE; + return true; + + } else { + + return false; + + } + } + +private: + enum States { + // vals[0] state _ vals[1] state + READ_WRITE = 0, + READ_LOCK, + WRITE_READ, + LOCK_READ + }; + + AtomicInt _state; + AtomicPtr _read_val; + T _vals[2]; +}; + + +} // namespace Raul + +#endif // RAUL_DOUBLE_BUFFER_HPP diff --git a/raul/JackDriver.h b/raul/JackDriver.h deleted file mode 100644 index 844f109..0000000 --- a/raul/JackDriver.h +++ /dev/null @@ -1,122 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_JACKDRIVER_H -#define RAUL_JACKDRIVER_H - -#include -#include -#include -#include - -using std::string; - -namespace Raul { - - -/** Handles all externally driven functionality, registering ports etc. - * - * Jack callbacks and connect methods and things like that live here. - * Right now just for jack ports, but that will change... - */ -class JackDriver -{ -public: - JackDriver(); - virtual ~JackDriver(); - - void attach(const string& client_name, string server_name=""); - void detach(); - - void activate(); - void deactivate(); - - bool is_activated() const { return _is_activated; } - bool is_attached() const { return (_client != NULL); } - bool is_realtime() const { return _client && jack_is_realtime(_client); } - - void start_transport() { jack_transport_start(_client); } - void stop_transport() { jack_transport_stop(_client); } - - void rewind_transport() { - jack_position_t zero; - zero.frame = 0; - zero.valid = (jack_position_bits_t)0; - jack_transport_reposition(_client, &zero); - } - - jack_nframes_t buffer_size(); - bool set_buffer_size(jack_nframes_t size); - - inline jack_nframes_t sample_rate() { return jack_get_sample_rate(_client); } - - inline size_t xruns() { return _xruns; } - void reset_xruns(); - - inline float max_delay() { return jack_get_max_delayed_usecs(_client); } - inline void reset_delay() { jack_reset_max_delayed_usecs(_client); } - - jack_client_t* jack_client() { return _client; } - - -protected: - /** Process callback. Derived classes should do all audio processing here. */ - virtual void on_process(jack_nframes_t /*nframes*/) {} - - /** Graph order change callback. */ - virtual void on_graph_order_changed() {} - - /** Buffer size changed callback. - * At the time this is called, buffer_size() will still return the old - * size. Immediately afterwards, it will be set to the new value. - */ - virtual void on_buffer_size_changed(jack_nframes_t /*size*/) {} - - virtual void on_xrun() {} - virtual void on_shutdown() {} - virtual void on_error() {} - -protected: - jack_client_t* _client; - -private: - - static void error_cb(const char* msg); - - void destroy_all_ports(); - - void update_time(); - - static void jack_port_registration_cb(jack_port_id_t port_id, int registered, void* me); - static int jack_graph_order_cb(void* me); - static int jack_xrun_cb(void* me); - static int jack_buffer_size_cb(jack_nframes_t buffer_size, void* me); - static int jack_process_cb(jack_nframes_t nframes, void* me); - - static void jack_shutdown_cb(void* me); - - bool _is_activated; - jack_position_t _last_pos; - jack_nframes_t _buffer_size; - size_t _xruns; - float _xrun_delay; -}; - - -} // namespace Raul - -#endif // RAUL_JACKDRIVER_H diff --git a/raul/JackDriver.hpp b/raul/JackDriver.hpp new file mode 100644 index 0000000..d939cb4 --- /dev/null +++ b/raul/JackDriver.hpp @@ -0,0 +1,122 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_JACK_DRIVER_HPP +#define RAUL_JACK_DRIVER_HPP + +#include +#include +#include +#include + +using std::string; + +namespace Raul { + + +/** Handles all externally driven functionality, registering ports etc. + * + * Jack callbacks and connect methods and things like that live here. + * Right now just for jack ports, but that will change... + */ +class JackDriver +{ +public: + JackDriver(); + virtual ~JackDriver(); + + void attach(const string& client_name, string server_name=""); + void detach(); + + void activate(); + void deactivate(); + + bool is_activated() const { return _is_activated; } + bool is_attached() const { return (_client != NULL); } + bool is_realtime() const { return _client && jack_is_realtime(_client); } + + void start_transport() { jack_transport_start(_client); } + void stop_transport() { jack_transport_stop(_client); } + + void rewind_transport() { + jack_position_t zero; + zero.frame = 0; + zero.valid = (jack_position_bits_t)0; + jack_transport_reposition(_client, &zero); + } + + jack_nframes_t buffer_size(); + bool set_buffer_size(jack_nframes_t size); + + inline jack_nframes_t sample_rate() { return jack_get_sample_rate(_client); } + + inline size_t xruns() { return _xruns; } + void reset_xruns(); + + inline float max_delay() { return jack_get_max_delayed_usecs(_client); } + inline void reset_delay() { jack_reset_max_delayed_usecs(_client); } + + jack_client_t* jack_client() { return _client; } + + +protected: + /** Process callback. Derived classes should do all audio processing here. */ + virtual void on_process(jack_nframes_t /*nframes*/) {} + + /** Graph order change callback. */ + virtual void on_graph_order_changed() {} + + /** Buffer size changed callback. + * At the time this is called, buffer_size() will still return the old + * size. Immediately afterwards, it will be set to the new value. + */ + virtual void on_buffer_size_changed(jack_nframes_t /*size*/) {} + + virtual void on_xrun() {} + virtual void on_shutdown() {} + virtual void on_error() {} + +protected: + jack_client_t* _client; + +private: + + static void error_cb(const char* msg); + + void destroy_all_ports(); + + void update_time(); + + static void jack_port_registration_cb(jack_port_id_t port_id, int registered, void* me); + static int jack_graph_order_cb(void* me); + static int jack_xrun_cb(void* me); + static int jack_buffer_size_cb(jack_nframes_t buffer_size, void* me); + static int jack_process_cb(jack_nframes_t nframes, void* me); + + static void jack_shutdown_cb(void* me); + + bool _is_activated; + jack_position_t _last_pos; + jack_nframes_t _buffer_size; + size_t _xruns; + float _xrun_delay; +}; + + +} // namespace Raul + +#endif // RAUL_JACK_DRIVER_HPP diff --git a/raul/LashClient.h b/raul/LashClient.h deleted file mode 100644 index 1325bc8..0000000 --- a/raul/LashClient.h +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_LASH_CLIENT_H -#define RAUL_LASH_CLIENT_H - -#include -#include -#include -#include - -namespace Raul { - - -class LashClient : public boost::enable_shared_from_this { -public: - virtual ~LashClient(); - - static SharedPtr create( - lash_args_t* args, - const std::string& name, - int flags); - - lash_client_t* lash_client() { return _lash_client; }; - - bool enabled() { return lash_enabled(_lash_client); } - - void process_events(); - -protected: - LashClient(lash_client_t* client); - - virtual void handle_event(lash_event_t*) {} - virtual void handle_config(lash_config_t*) {} - - friend class LashProject; - virtual void project_closed(const std::string& /*name*/) {} - - lash_client_t* _lash_client; -}; - - -} // namespace Raul - -#endif // RAUL_LASH_CLIENT_H - diff --git a/raul/LashClient.hpp b/raul/LashClient.hpp new file mode 100644 index 0000000..69ab618 --- /dev/null +++ b/raul/LashClient.hpp @@ -0,0 +1,60 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_LASH_CLIENT_HPP +#define RAUL_LASH_CLIENT_HPP + +#include +#include +#include +#include + +namespace Raul { + + +class LashClient : public boost::enable_shared_from_this { +public: + virtual ~LashClient(); + + static SharedPtr create( + lash_args_t* args, + const std::string& name, + int flags); + + lash_client_t* lash_client() { return _lash_client; }; + + bool enabled() { return lash_enabled(_lash_client); } + + void process_events(); + +protected: + LashClient(lash_client_t* client); + + virtual void handle_event(lash_event_t*) {} + virtual void handle_config(lash_config_t*) {} + + friend class LashProject; + virtual void project_closed(const std::string& /*name*/) {} + + lash_client_t* _lash_client; +}; + + +} // namespace Raul + +#endif // RAUL_LASH_CLIENT_HPP + diff --git a/raul/LashProject.h b/raul/LashProject.h deleted file mode 100644 index 93a2163..0000000 --- a/raul/LashProject.h +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_LASH_PROJECT_H -#define RAUL_LASH_PROJECT_H - -#include -#include -#include -#include -#include - -namespace Raul { - - -class LashProject : public sigc::trackable { -public: - LashProject(SharedPtr client, const std::string& name); - - void save(); - void close(); - - const std::string& name() { return _name; } - const std::string& directory() { return _directory; } - - void set_directory(const std::string& filename); - void set_name(const std::string& name); - - sigc::signal signal_name; - sigc::signal signal_directory; - sigc::signal signal_save_file; - sigc::signal signal_restore_file; - - bool operator==(const std::string& name) { return _name == name; } - -private: - WeakPtr _client; - std::string _name; - std::string _directory; -}; - - -} // namespace Raul - -#endif // RAUL_LASH_PROJECT_H - diff --git a/raul/LashProject.hpp b/raul/LashProject.hpp new file mode 100644 index 0000000..ae641a5 --- /dev/null +++ b/raul/LashProject.hpp @@ -0,0 +1,60 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_LASH_PROJECT_HPP +#define RAUL_LASH_PROJECT_HPP + +#include +#include +#include +#include +#include + +namespace Raul { + + +class LashProject : public sigc::trackable { +public: + LashProject(SharedPtr client, const std::string& name); + + void save(); + void close(); + + const std::string& name() { return _name; } + const std::string& directory() { return _directory; } + + void set_directory(const std::string& filename); + void set_name(const std::string& name); + + sigc::signal signal_name; + sigc::signal signal_directory; + sigc::signal signal_save_file; + sigc::signal signal_restore_file; + + bool operator==(const std::string& name) { return _name == name; } + +private: + WeakPtr _client; + std::string _name; + std::string _directory; +}; + + +} // namespace Raul + +#endif // RAUL_LASH_PROJECT_HPP + diff --git a/raul/LashServerInterface.h b/raul/LashServerInterface.h deleted file mode 100644 index 9a2d332..0000000 --- a/raul/LashServerInterface.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_LASH_SERVER_INTERFACE_H -#define RAUL_LASH_SERVER_INTERFACE_H - -#include -#include -#include -#include -#include -#include -#include - - -namespace Raul { - - -class LashServerInterface : public LashClient, public sigc::trackable { -public: - static SharedPtr create( - lash_args_t* args, - const std::string& name, - int flags); - - sigc::signal signal_quit; - sigc::signal > signal_project_add; - sigc::signal > signal_project_remove; - - void restore_project(const std::string& filename); - - typedef std::list > Projects; - Projects& projects() { return _projects; } - - SharedPtr project(const std::string& name); - -private: - LashServerInterface(lash_client_t* client); - void handle_event(lash_event_t* ev); - void project_closed(const std::string& name); - - Projects _projects; -}; - - -} // namespace Raul - -#endif // RAUL_LASH_SERVER_INTERFACE_H - diff --git a/raul/LashServerInterface.hpp b/raul/LashServerInterface.hpp new file mode 100644 index 0000000..be47ef3 --- /dev/null +++ b/raul/LashServerInterface.hpp @@ -0,0 +1,63 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_LASH_SERVER_INTERFACE_HPP +#define RAUL_LASH_SERVER_INTERFACE_HPP + +#include +#include +#include +#include +#include +#include +#include + + +namespace Raul { + + +class LashServerInterface : public LashClient, public sigc::trackable { +public: + static SharedPtr create( + lash_args_t* args, + const std::string& name, + int flags); + + sigc::signal signal_quit; + sigc::signal > signal_project_add; + sigc::signal > signal_project_remove; + + void restore_project(const std::string& filename); + + typedef std::list > Projects; + Projects& projects() { return _projects; } + + SharedPtr project(const std::string& name); + +private: + LashServerInterface(lash_client_t* client); + void handle_event(lash_event_t* ev); + void project_closed(const std::string& name); + + Projects _projects; +}; + + +} // namespace Raul + +#endif // RAUL_LASH_SERVER_INTERFACE_HPP + diff --git a/raul/List.h b/raul/List.h deleted file mode 100644 index 79748ba..0000000 --- a/raul/List.h +++ /dev/null @@ -1,544 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_LIST_H -#define RAUL_LIST_H - -#include -#include -#include "Deletable.h" -#include "AtomicPtr.h" -#include "AtomicInt.h" - -namespace Raul { - - -/** A node in a List. - * - * This is exposed so the user can allocate ListNodes in different thread - * than the list reader, and insert (e.g. via an Event) it later in the - * reader thread. - */ -template -class ListNode : public Raul::Deletable -{ -public: - ListNode(T elem) : _elem(elem) {} - virtual ~ListNode() {} - - ListNode* next() const { return _next.get(); } - void next(ListNode* ln) { _next = ln; } - ListNode* prev() const { return _prev.get(); } - void prev(ListNode* ln) { _prev = ln; } - T& elem() { return _elem;} - const T& elem() const { return _elem; } - -private: - T _elem; - AtomicPtr _next; - AtomicPtr _prev; -}; - - - -/** A realtime safe, (partially) thread safe doubly-linked list. - * - * Elements can be added safely while another thread is reading the list. - * Like a typical ringbuffer, this is single-reader single-writer threadsafe - * only. See documentation for specific functions for specifics. - */ -template -class List : public Raul::Deletable -{ -public: - List() : _size(0), _end_iter(this), _const_end_iter(this) - { - _end_iter._listnode = NULL; - _const_end_iter._listnode = NULL; - } - ~List(); - - void push_back(ListNode* elem); // realtime safe - void push_back(T& elem); // NOT realtime safe - - void append(List& list); - - void clear(); - - /// Valid only in the write thread - unsigned size() const { return (unsigned)_size.get(); } - - /// Valid for any thread - bool empty() { return (_head.get() == NULL); } - - class iterator; - - /** Realtime safe const iterator for a List. */ - class const_iterator - { - public: - const_iterator(const List* const list); - const_iterator(const iterator& i) - : _list(i._list), _listnode(i._listnode) {} - - inline const T& operator*(); - inline const_iterator& operator++(); - inline bool operator!=(const const_iterator& iter) const; - inline bool operator!=(const iterator& iter) const; - inline bool operator==(const const_iterator& iter) const; - inline bool operator==(const iterator& iter) const; - - friend class List; - - private: - const List* const _list; - const ListNode* _listnode; - }; - - - /** Realtime safe iterator for a List. */ - class iterator - { - public: - iterator(List* const list); - - inline T& operator*(); - inline iterator& operator++(); - inline bool operator!=(const iterator& iter) const; - inline bool operator!=(const const_iterator& iter) const; - inline bool operator==(const iterator& iter) const; - inline bool operator==(const const_iterator& iter) const; - - friend class List; - friend class List::const_iterator; - - private: - const List* _list; - ListNode* _listnode; - }; - - - ListNode* erase(const iterator iter); - - iterator find(const T& val); - - iterator begin(); - const iterator end() const; - - const_iterator begin() const; - //const_iterator end() const; - -private: - AtomicPtr > _head; - AtomicPtr > _tail; ///< writer only - AtomicInt _size; - iterator _end_iter; - const_iterator _const_end_iter; -}; - - - - -template -List::~List() -{ - clear(); -} - - -/** Clear the list, deleting all ListNodes contained (but NOT their contents!) - * - * Not realtime safe. - */ -template -void -List::clear() -{ - ListNode* node = _head.get(); - ListNode* next = NULL; - - while (node) { - next = node->next(); - delete node; - node = next; - } - - _head = 0; - _tail = 0; - _size = 0; -} - - -/** Add an element to the list. - * - * Thread safe (may be called while another thread is reading the list). - * Realtime safe. - */ -template -void -List::push_back(ListNode* const ln) -{ - assert(ln); - - ln->next(NULL); - - if ( ! _head.get()) { // empty - ln->prev(NULL); - _tail = ln; - _head = ln; - } else { - ln->prev(_tail.get()); - _tail.get()->next(ln); - _tail = ln; - } - ++_size; -} - - -/** Add an element to the list. - * - * Thread safe (may be called while another thread is reading the list). - * NOT realtime safe (a ListNode is allocated). - */ -template -void -List::push_back(T& elem) -{ - ListNode* const ln = new ListNode(elem); - - assert(ln); - - ln->next(NULL); - - if ( ! _head.get()) { // empty - ln->prev(NULL); - _tail = ln; - _head = ln; - } else { - ln->prev(_tail.get()); - _tail.get()->next(ln); - _tail = ln; - } - ++_size; -} - - -/** Append a list to this list. - * - * This operation is fast ( O(1) ). - * The appended list is not safe to use concurrently with this call. - * - * The appended list will be empty after this call. - * - * Thread safe (may be called while another thread is reading the list). - * Realtime safe. - */ -template -void -List::append(List& list) -{ - ListNode* const my_head = _head.get(); - ListNode* const my_tail = _tail.get(); - ListNode* const other_head = list._head.get(); - ListNode* const other_tail = list._tail.get(); - - // Appending to an empty list - if (my_head == NULL && my_tail == NULL) { - _head = other_head; - _tail = other_tail; - _size = list._size; - } else if (other_head != NULL && other_tail != NULL) { - - other_head->prev(my_tail); - - // FIXME: atomicity an issue? _size < true size is probably fine... - // no gurantee an iteration runs exactly size times though. verify/document this. - // assuming comment above that says tail is writer only, this is fine - my_tail->next(other_head); - _tail = other_tail; - _size += list.size(); - } - - list._head = NULL; - list._tail = NULL; - list._size = 0; -} - - -/** Remove all elements equal to @val from the list. - * - * This function is realtime safe - it is the caller's responsibility to - * delete the returned ListNode, or there will be a leak. - */ -#if 0 -template -ListNode* -List::remove(const T val) -{ - // FIXME: atomicity? - ListNode* n = _head; - while (n) { - if (n->elem() == elem) - break; - n = n->next(); - } - if (n) { - if (n == _head) _head = _head->next(); - if (n == _tail) _tail = _tail->prev(); - if (n->prev()) - n->prev()->next(n->next()); - if (n->next()) - n->next()->prev(n->prev()); - --_size; - - if (_size == 0) - _head = _tail = NULL; // FIXME: Shouldn't be necessary - - return n; - } - return NULL; -} -#endif - - -/** Find an element in the list. - * - * This will only return the first element found. If there are duplicated, - * another call to find() will return the next, etc. - */ -template -typename List::iterator -List::find(const T& val) -{ - for (iterator i = begin(); i != end(); ++i) - if (*i == val) - return i; - - return end(); -} - - -/** Remove an element from the list using an iterator. - * - * This function is realtime safe - it is the caller's responsibility to - * delete the returned ListNode, or there will be a leak. - * Thread safe (safe to call while another thread reads the list). - * @a iter is invalid immediately following this call. - */ -template -ListNode* -List::erase(const iterator iter) -{ - ListNode* const n = iter._listnode; - - if (n) { - - ListNode* const prev = n->prev(); - ListNode* const next = n->next(); - - // Removing the head (or the only element) - if (n == _head.get()) - _head = next; - - // Removing the tail (or the only element) - if (n == _tail.get()) - _tail = _tail.get()->prev(); - - if (prev) - n->prev()->next(next); - - if (next) - n->next()->prev(prev); - - --_size; - } - - return n; -} - - -//// Iterator stuff //// - -template -List::iterator::iterator(List* list) -: _list(list), - _listnode(NULL) -{ -} - - -template -T& -List::iterator::operator*() -{ - assert(_listnode); - return _listnode->elem(); -} - - -template -inline typename List::iterator& -List::iterator::operator++() -{ - assert(_listnode); - _listnode = _listnode->next(); - - return *this; -} - - -template -inline bool -List::iterator::operator!=(const iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template -inline bool -List::iterator::operator!=(const const_iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template -inline bool -List::iterator::operator==(const iterator& iter) const -{ - return (_listnode == iter._listnode); -} - - -template -inline bool -List::iterator::operator==(const const_iterator& iter) const -{ - return (_listnode == iter._listnode); -} - - -template -inline typename List::iterator -List::begin() -{ - typename List::iterator iter(this); - - iter._listnode = _head.get(); - - return iter; -} - - -template -inline const typename List::iterator -List::end() const -{ - return _end_iter; -} - - - -/// const_iterator stuff /// - - -template -List::const_iterator::const_iterator(const List* const list) -: _list(list), - _listnode(NULL) -{ -} - - -template -const T& -List::const_iterator::operator*() -{ - assert(_listnode); - return _listnode->elem(); -} - - -template -inline typename List::const_iterator& -List::const_iterator::operator++() -{ - assert(_listnode); - _listnode = _listnode->next(); - - return *this; -} - - -template -inline bool -List::const_iterator::operator!=(const const_iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template -inline bool -List::const_iterator::operator!=(const iterator& iter) const -{ - return (_listnode != iter._listnode); -} - - -template -inline bool -List::const_iterator::operator==(const const_iterator& iter) const -{ - return (_listnode == iter._listnode); -} - - -template -inline bool -List::const_iterator::operator==(const iterator& iter) const -{ - return (_listnode == iter._listnode); -} - -template -inline typename List::const_iterator -List::begin() const -{ - typename List::const_iterator iter(this); - iter._listnode = _head.get(); - return iter; -} - -#if 0 -template -inline typename List::const_iterator -List::end() const -{ - /*typename List::const_iterator iter(this); - iter._listnode = NULL; - iter._next = NULL; - return iter;*/ - return _const_end_iter; -} -#endif - - -} // namespace Raul - -#endif // RAUL_LIST_H diff --git a/raul/List.hpp b/raul/List.hpp new file mode 100644 index 0000000..d3f4707 --- /dev/null +++ b/raul/List.hpp @@ -0,0 +1,544 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_LIST_HPP +#define RAUL_LIST_HPP + +#include +#include +#include +#include +#include + +namespace Raul { + + +/** A node in a List. + * + * This is exposed so the user can allocate ListNodes in different thread + * than the list reader, and insert (e.g. via an Event) it later in the + * reader thread. + */ +template +class ListNode : public Raul::Deletable +{ +public: + ListNode(T elem) : _elem(elem) {} + virtual ~ListNode() {} + + ListNode* next() const { return _next.get(); } + void next(ListNode* ln) { _next = ln; } + ListNode* prev() const { return _prev.get(); } + void prev(ListNode* ln) { _prev = ln; } + T& elem() { return _elem;} + const T& elem() const { return _elem; } + +private: + T _elem; + AtomicPtr _next; + AtomicPtr _prev; +}; + + + +/** A realtime safe, (partially) thread safe doubly-linked list. + * + * Elements can be added safely while another thread is reading the list. + * Like a typical ringbuffer, this is single-reader single-writer threadsafe + * only. See documentation for specific functions for specifics. + */ +template +class List : public Raul::Deletable +{ +public: + List() : _size(0), _end_iter(this), _const_end_iter(this) + { + _end_iter._listnode = NULL; + _const_end_iter._listnode = NULL; + } + ~List(); + + void push_back(ListNode* elem); // realtime safe + void push_back(T& elem); // NOT realtime safe + + void append(List& list); + + void clear(); + + /// Valid only in the write thread + unsigned size() const { return (unsigned)_size.get(); } + + /// Valid for any thread + bool empty() { return (_head.get() == NULL); } + + class iterator; + + /** Realtime safe const iterator for a List. */ + class const_iterator + { + public: + const_iterator(const List* const list); + const_iterator(const iterator& i) + : _list(i._list), _listnode(i._listnode) {} + + inline const T& operator*(); + inline const_iterator& operator++(); + inline bool operator!=(const const_iterator& iter) const; + inline bool operator!=(const iterator& iter) const; + inline bool operator==(const const_iterator& iter) const; + inline bool operator==(const iterator& iter) const; + + friend class List; + + private: + const List* const _list; + const ListNode* _listnode; + }; + + + /** Realtime safe iterator for a List. */ + class iterator + { + public: + iterator(List* const list); + + inline T& operator*(); + inline iterator& operator++(); + inline bool operator!=(const iterator& iter) const; + inline bool operator!=(const const_iterator& iter) const; + inline bool operator==(const iterator& iter) const; + inline bool operator==(const const_iterator& iter) const; + + friend class List; + friend class List::const_iterator; + + private: + const List* _list; + ListNode* _listnode; + }; + + + ListNode* erase(const iterator iter); + + iterator find(const T& val); + + iterator begin(); + const iterator end() const; + + const_iterator begin() const; + //const_iterator end() const; + +private: + AtomicPtr > _head; + AtomicPtr > _tail; ///< writer only + AtomicInt _size; + iterator _end_iter; + const_iterator _const_end_iter; +}; + + + + +template +List::~List() +{ + clear(); +} + + +/** Clear the list, deleting all ListNodes contained (but NOT their contents!) + * + * Not realtime safe. + */ +template +void +List::clear() +{ + ListNode* node = _head.get(); + ListNode* next = NULL; + + while (node) { + next = node->next(); + delete node; + node = next; + } + + _head = 0; + _tail = 0; + _size = 0; +} + + +/** Add an element to the list. + * + * Thread safe (may be called while another thread is reading the list). + * Realtime safe. + */ +template +void +List::push_back(ListNode* const ln) +{ + assert(ln); + + ln->next(NULL); + + if ( ! _head.get()) { // empty + ln->prev(NULL); + _tail = ln; + _head = ln; + } else { + ln->prev(_tail.get()); + _tail.get()->next(ln); + _tail = ln; + } + ++_size; +} + + +/** Add an element to the list. + * + * Thread safe (may be called while another thread is reading the list). + * NOT realtime safe (a ListNode is allocated). + */ +template +void +List::push_back(T& elem) +{ + ListNode* const ln = new ListNode(elem); + + assert(ln); + + ln->next(NULL); + + if ( ! _head.get()) { // empty + ln->prev(NULL); + _tail = ln; + _head = ln; + } else { + ln->prev(_tail.get()); + _tail.get()->next(ln); + _tail = ln; + } + ++_size; +} + + +/** Append a list to this list. + * + * This operation is fast ( O(1) ). + * The appended list is not safe to use concurrently with this call. + * + * The appended list will be empty after this call. + * + * Thread safe (may be called while another thread is reading the list). + * Realtime safe. + */ +template +void +List::append(List& list) +{ + ListNode* const my_head = _head.get(); + ListNode* const my_tail = _tail.get(); + ListNode* const other_head = list._head.get(); + ListNode* const other_tail = list._tail.get(); + + // Appending to an empty list + if (my_head == NULL && my_tail == NULL) { + _head = other_head; + _tail = other_tail; + _size = list._size; + } else if (other_head != NULL && other_tail != NULL) { + + other_head->prev(my_tail); + + // FIXME: atomicity an issue? _size < true size is probably fine... + // no gurantee an iteration runs exactly size times though. verify/document this. + // assuming comment above that says tail is writer only, this is fine + my_tail->next(other_head); + _tail = other_tail; + _size += list.size(); + } + + list._head = NULL; + list._tail = NULL; + list._size = 0; +} + + +/** Remove all elements equal to @val from the list. + * + * This function is realtime safe - it is the caller's responsibility to + * delete the returned ListNode, or there will be a leak. + */ +#if 0 +template +ListNode* +List::remove(const T val) +{ + // FIXME: atomicity? + ListNode* n = _head; + while (n) { + if (n->elem() == elem) + break; + n = n->next(); + } + if (n) { + if (n == _head) _head = _head->next(); + if (n == _tail) _tail = _tail->prev(); + if (n->prev()) + n->prev()->next(n->next()); + if (n->next()) + n->next()->prev(n->prev()); + --_size; + + if (_size == 0) + _head = _tail = NULL; // FIXME: Shouldn't be necessary + + return n; + } + return NULL; +} +#endif + + +/** Find an element in the list. + * + * This will only return the first element found. If there are duplicated, + * another call to find() will return the next, etc. + */ +template +typename List::iterator +List::find(const T& val) +{ + for (iterator i = begin(); i != end(); ++i) + if (*i == val) + return i; + + return end(); +} + + +/** Remove an element from the list using an iterator. + * + * This function is realtime safe - it is the caller's responsibility to + * delete the returned ListNode, or there will be a leak. + * Thread safe (safe to call while another thread reads the list). + * @a iter is invalid immediately following this call. + */ +template +ListNode* +List::erase(const iterator iter) +{ + ListNode* const n = iter._listnode; + + if (n) { + + ListNode* const prev = n->prev(); + ListNode* const next = n->next(); + + // Removing the head (or the only element) + if (n == _head.get()) + _head = next; + + // Removing the tail (or the only element) + if (n == _tail.get()) + _tail = _tail.get()->prev(); + + if (prev) + n->prev()->next(next); + + if (next) + n->next()->prev(prev); + + --_size; + } + + return n; +} + + +//// Iterator stuff //// + +template +List::iterator::iterator(List* list) +: _list(list), + _listnode(NULL) +{ +} + + +template +T& +List::iterator::operator*() +{ + assert(_listnode); + return _listnode->elem(); +} + + +template +inline typename List::iterator& +List::iterator::operator++() +{ + assert(_listnode); + _listnode = _listnode->next(); + + return *this; +} + + +template +inline bool +List::iterator::operator!=(const iterator& iter) const +{ + return (_listnode != iter._listnode); +} + + +template +inline bool +List::iterator::operator!=(const const_iterator& iter) const +{ + return (_listnode != iter._listnode); +} + + +template +inline bool +List::iterator::operator==(const iterator& iter) const +{ + return (_listnode == iter._listnode); +} + + +template +inline bool +List::iterator::operator==(const const_iterator& iter) const +{ + return (_listnode == iter._listnode); +} + + +template +inline typename List::iterator +List::begin() +{ + typename List::iterator iter(this); + + iter._listnode = _head.get(); + + return iter; +} + + +template +inline const typename List::iterator +List::end() const +{ + return _end_iter; +} + + + +/// const_iterator stuff /// + + +template +List::const_iterator::const_iterator(const List* const list) +: _list(list), + _listnode(NULL) +{ +} + + +template +const T& +List::const_iterator::operator*() +{ + assert(_listnode); + return _listnode->elem(); +} + + +template +inline typename List::const_iterator& +List::const_iterator::operator++() +{ + assert(_listnode); + _listnode = _listnode->next(); + + return *this; +} + + +template +inline bool +List::const_iterator::operator!=(const const_iterator& iter) const +{ + return (_listnode != iter._listnode); +} + + +template +inline bool +List::const_iterator::operator!=(const iterator& iter) const +{ + return (_listnode != iter._listnode); +} + + +template +inline bool +List::const_iterator::operator==(const const_iterator& iter) const +{ + return (_listnode == iter._listnode); +} + + +template +inline bool +List::const_iterator::operator==(const iterator& iter) const +{ + return (_listnode == iter._listnode); +} + +template +inline typename List::const_iterator +List::begin() const +{ + typename List::const_iterator iter(this); + iter._listnode = _head.get(); + return iter; +} + +#if 0 +template +inline typename List::const_iterator +List::end() const +{ + /*typename List::const_iterator iter(this); + iter._listnode = NULL; + iter._next = NULL; + return iter;*/ + return _const_end_iter; +} +#endif + + +} // namespace Raul + +#endif // RAUL_LIST_HPP diff --git a/raul/MIDISink.h b/raul/MIDISink.h deleted file mode 100644 index fe5f4e8..0000000 --- a/raul/MIDISink.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_MIDISINK_H -#define RAUL_MIDISINK_H - -#include -#include -#include - -namespace Raul { - - -/** Pure virtual base for anything you can write MIDI to. - */ -class MIDISink : public Deletable { -public: - virtual void write_event(BeatTime time, - size_t ev_size, - const unsigned char* ev) throw (std::logic_error) = 0; -}; - - -} // namespace Raul - -#endif // RAUL_MIDISINK_H - diff --git a/raul/MIDISink.hpp b/raul/MIDISink.hpp new file mode 100644 index 0000000..6955911 --- /dev/null +++ b/raul/MIDISink.hpp @@ -0,0 +1,41 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_MIDI_SINK_HPP +#define RAUL_MIDI_SINK_HPP + +#include +#include +#include + +namespace Raul { + + +/** Pure virtual base for anything you can write MIDI to. + */ +class MIDISink : public Deletable { +public: + virtual void write_event(BeatTime time, + size_t ev_size, + const unsigned char* ev) throw (std::logic_error) = 0; +}; + + +} // namespace Raul + +#endif // RAUL_MIDI_SINK_HPP + diff --git a/raul/Maid.h b/raul/Maid.h deleted file mode 100644 index f8f6c29..0000000 --- a/raul/Maid.h +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_MAID_H -#define RAUL_MAID_H - -#include -#include "raul/SharedPtr.h" -#include "raul/SRSWQueue.h" -#include "raul/Deletable.h" -#include "raul/List.h" - -namespace Raul { - - -/** Explicitly driven garbage collector. - * - * This is used by realtime threads to allow hard realtime deletion of objects - * (push() is realtime safe). - * - * You can also manage a SharedPtr, so cleanup() will delete it when all - * references are dropped (except the one held by the Maid itself). - * This allows using a SharedPtr freely in hard realtime threads without having - * to worry about deletion accidentally occuring in the realtime thread. - * - * cleanup() should be called periodically to free memory, often enough to - * prevent the queue from overflowing. This is probably best done by the main - * thread to avoid the overhead of having a thread just to delete things. - * - * \ingroup raul - */ -class Maid : boost::noncopyable -{ -public: - Maid(size_t size); - ~Maid(); - - /** Push a raw pointer to be deleted when cleanup() is called next. - * Realtime safe. - */ - inline void push(Raul::Deletable* obj) { - if (obj) - _objects.push(obj); - } - - void manage(SharedPtr ptr); - - void cleanup(); - -private: - typedef Raul::SRSWQueue Objects; - typedef Raul::List > Managed; - - Objects _objects; - Managed _managed; -}; - - -} // namespace Raul - -#endif // RAUL_MAID_H - diff --git a/raul/Maid.hpp b/raul/Maid.hpp new file mode 100644 index 0000000..0643062 --- /dev/null +++ b/raul/Maid.hpp @@ -0,0 +1,76 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_MAID_HPP +#define RAUL_MAID_HPP + +#include +#include +#include +#include +#include + +namespace Raul { + + +/** Explicitly driven garbage collector. + * + * This is used by realtime threads to allow hard realtime deletion of objects + * (push() is realtime safe). + * + * You can also manage a SharedPtr, so cleanup() will delete it when all + * references are dropped (except the one held by the Maid itself). + * This allows using a SharedPtr freely in hard realtime threads without having + * to worry about deletion accidentally occuring in the realtime thread. + * + * cleanup() should be called periodically to free memory, often enough to + * prevent the queue from overflowing. This is probably best done by the main + * thread to avoid the overhead of having a thread just to delete things. + * + * \ingroup raul + */ +class Maid : boost::noncopyable +{ +public: + Maid(size_t size); + ~Maid(); + + /** Push a raw pointer to be deleted when cleanup() is called next. + * Realtime safe. + */ + inline void push(Raul::Deletable* obj) { + if (obj) + _objects.push(obj); + } + + void manage(SharedPtr ptr); + + void cleanup(); + +private: + typedef Raul::SRSWQueue Objects; + typedef Raul::List > Managed; + + Objects _objects; + Managed _managed; +}; + + +} // namespace Raul + +#endif // RAUL_MAID_HPP + diff --git a/raul/Makefile.am b/raul/Makefile.am index 82c69de..77df449 100644 --- a/raul/Makefile.am +++ b/raul/Makefile.am @@ -1,48 +1,48 @@ raulincludedir = $(includedir)/raul raulinclude_HEADERS = \ - Array.h \ - Atom.h \ - AtomicInt.h \ - AtomicPtr.h \ - Deletable.h \ - DoubleBuffer.h \ - JackDriver.h \ - List.h \ - StampedChunkRingBuffer.h \ - MIDISink.h \ - Maid.h \ - Namespaces.h \ - Path.h \ - Process.h \ - Quantizer.h \ - RDFModel.h \ - RDFNode.h \ - RDFQuery.h \ - RDFWorld.h \ - RingBuffer.h \ - SMFReader.h \ - SMFWriter.h \ - SRMWQueue.h \ - SRSWQueue.h \ - Semaphore.h \ - SharedPtr.h \ - Slave.h \ - Stateful.h \ - Thread.h \ - TimeSlice.h \ - WeakPtr.h \ + Array.hpp \ + Atom.hpp \ + AtomicInt.hpp \ + AtomicPtr.hpp \ + Deletable.hpp \ + DoubleBuffer.hpp \ + JackDriver.hpp \ + List.hpp \ + MIDISink.hpp \ + Maid.hpp \ + Namespaces.hpp \ + Path.hpp \ + Process.hpp \ + Quantizer.hpp \ + RDFModel.hpp \ + RDFNode.hpp \ + RDFQuery.hpp \ + RDFWorld.hpp \ + RingBuffer.hpp \ + SMFReader.hpp \ + SMFWriter.hpp \ + SRMWQueue.hpp \ + SRSWQueue.hpp \ + Semaphore.hpp \ + SharedPtr.hpp \ + Slave.hpp \ + StampedChunkRingBuffer.hpp \ + Stateful.hpp \ + Thread.hpp \ + TimeSlice.hpp \ + WeakPtr.hpp \ midi_events.h \ - types.h + types.hpp if WITH_LIBLO -raulinclude_HEADERS += AtomLiblo.h +raulinclude_HEADERS += AtomLiblo.hpp endif if WITH_REDLAND -raulinclude_HEADERS += AtomRedland.h +raulinclude_HEADERS += AtomRedland.hpp endif if WITH_LASH -raulinclude_HEADERS += LashClient.h LashServerInterface.h LashProject.h +raulinclude_HEADERS += LashClient.hpp LashServerInterface.hpp LashProject.hpp endif diff --git a/raul/Namespaces.h b/raul/Namespaces.h deleted file mode 100644 index 673bbd5..0000000 --- a/raul/Namespaces.h +++ /dev/null @@ -1,37 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_NAMESPACES_H -#define RAUL_NAMESPACES_H - -#include -#include - -namespace Raul { - - -/** Collection of RDF namespaces with prefixes. - */ -class Namespaces : public std::map { -public: - std::string qualify(std::string uri) const; -}; - - -} // namespace Raul - -#endif // RAUL_NAMESPACES_H diff --git a/raul/Namespaces.hpp b/raul/Namespaces.hpp new file mode 100644 index 0000000..abaa838 --- /dev/null +++ b/raul/Namespaces.hpp @@ -0,0 +1,37 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_NAMESPACES_HPP +#define RAUL_NAMESPACES_HPP + +#include +#include + +namespace Raul { + + +/** Collection of RDF namespaces with prefixes. + */ +class Namespaces : public std::map { +public: + std::string qualify(std::string uri) const; +}; + + +} // namespace Raul + +#endif // RAUL_NAMESPACES_HPP diff --git a/raul/Path.h b/raul/Path.h deleted file mode 100644 index 5a8fbb8..0000000 --- a/raul/Path.h +++ /dev/null @@ -1,128 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_PATH_H -#define RAUL_PATH_H - -#include -#include -#include -using std::string; - -namespace Raul { - - -/** Simple wrapper around standard string with useful path-specific methods. - * - * This enforces that a Path is a valid OSC path (though it is used for - * GraphObject paths, which aren't directly OSC paths but a portion of one). - * - * A path is divided by slashes (/). The first character MUST be a slash, and - * the last character MUST NOT be a slash (except in the special case of the - * root path "/", which is the only valid single-character path). - * - * Valid characters are the 95 printable ASCII characters (32-126), excluding: - * space # * , ? [ ] { } - * - * \ingroup raul - */ -class Path : public std::basic_string { -public: - - /** Construct a Path from an std::string. - * - * It is a fatal error to construct a Path from an invalid string, - * use is_valid first to check. - */ - Path(const std::basic_string& path) - : std::basic_string(path) - { - assert(is_valid(path)); - } - - - /** Construct a Path from a C string. - * - * It is a fatal error to construct a Path from an invalid string, - * use is_valid first to check. - */ - Path(const char* cpath) - : std::basic_string(cpath) - { - assert(is_valid(cpath)); - } - - static bool is_valid(const std::basic_string& path); - - static bool is_valid_name(const std::basic_string& name) - { - return is_valid(string("/").append(name)); - } - - static string pathify(const std::basic_string& str); - static string nameify(const std::basic_string& str); - - static void replace_invalid_chars(string& str, bool replace_slash = false); - - bool is_child_of(const Path& parent) const; - bool is_parent_of(const Path& child) const; - - - /** Return the name of this object (everything after the last '/'). - * This is the "method name" for OSC paths. - */ - inline std::basic_string name() const - { - if ((*this) == "/") - return ""; - else - return substr(find_last_of("/")+1); - } - - - /** Return the parent's path. - * - * Calling this on the path "/" will return "/". - * This is the (deepest) "container path" for OSC paths. - */ - inline Path parent() const - { - std::basic_string parent = substr(0, find_last_of("/")); - return (parent == "") ? "/" : parent; - } - - - /** Parent path with a "/" appended. - * - * This exists to avoid needing to be careful about the special case of "/". - * To create a child of a path, use parent.base() + child_name. - * Returned value is always a valid path, with the single exception that - * the last character is "/". - */ - inline string base() const - { - if ((*this) == "/") - return *this; - else - return (*this) + "/"; - } -}; - - -} // namespace Raul - -#endif // RAUL_PATH_H diff --git a/raul/Path.hpp b/raul/Path.hpp new file mode 100644 index 0000000..5776309 --- /dev/null +++ b/raul/Path.hpp @@ -0,0 +1,128 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_PATH_HPP +#define RAUL_PATH_HPP + +#include +#include +#include +using std::string; + +namespace Raul { + + +/** Simple wrapper around standard string with useful path-specific methods. + * + * This enforces that a Path is a valid OSC path (though it is used for + * GraphObject paths, which aren't directly OSC paths but a portion of one). + * + * A path is divided by slashes (/). The first character MUST be a slash, and + * the last character MUST NOT be a slash (except in the special case of the + * root path "/", which is the only valid single-character path). + * + * Valid characters are the 95 printable ASCII characters (32-126), excluding: + * space # * , ? [ ] { } + * + * \ingroup raul + */ +class Path : public std::basic_string { +public: + + /** Construct a Path from an std::string. + * + * It is a fatal error to construct a Path from an invalid string, + * use is_valid first to check. + */ + Path(const std::basic_string& path) + : std::basic_string(path) + { + assert(is_valid(path)); + } + + + /** Construct a Path from a C string. + * + * It is a fatal error to construct a Path from an invalid string, + * use is_valid first to check. + */ + Path(const char* cpath) + : std::basic_string(cpath) + { + assert(is_valid(cpath)); + } + + static bool is_valid(const std::basic_string& path); + + static bool is_valid_name(const std::basic_string& name) + { + return is_valid(string("/").append(name)); + } + + static string pathify(const std::basic_string& str); + static string nameify(const std::basic_string& str); + + static void replace_invalid_chars(string& str, bool replace_slash = false); + + bool is_child_of(const Path& parent) const; + bool is_parent_of(const Path& child) const; + + + /** Return the name of this object (everything after the last '/'). + * This is the "method name" for OSC paths. + */ + inline std::basic_string name() const + { + if ((*this) == "/") + return ""; + else + return substr(find_last_of("/")+1); + } + + + /** Return the parent's path. + * + * Calling this on the path "/" will return "/". + * This is the (deepest) "container path" for OSC paths. + */ + inline Path parent() const + { + std::basic_string parent = substr(0, find_last_of("/")); + return (parent == "") ? "/" : parent; + } + + + /** Parent path with a "/" appended. + * + * This exists to avoid needing to be careful about the special case of "/". + * To create a child of a path, use parent.base() + child_name. + * Returned value is always a valid path, with the single exception that + * the last character is "/". + */ + inline string base() const + { + if ((*this) == "/") + return *this; + else + return (*this) + "/"; + } +}; + + +} // namespace Raul + +#endif // RAUL_PATH_HPP diff --git a/raul/Process.h b/raul/Process.h deleted file mode 100644 index 7e14566..0000000 --- a/raul/Process.h +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_PROCESS_H -#define RAUL_PROCESS_H - -#include -#include -#include -#include -#include -#include - -namespace Raul { - - -/** A child process. - * - * \ingroup raul - */ -class Process : boost::noncopyable -{ -public: - - /** Launch a sub process. - * - * @param command can be a typical shell command with parameters, the PATH is searched etc. - */ - static bool launch(std::string command) - { - const std::string executable = (command.find(" ") != std::string::npos) - ? command.substr(0, command.find(" ")) - : command; - - std::cerr << "Launching child process '" << executable << "' with command line '" - << command << "'" << std::endl; - - // Use the same double fork() trick as JACK to prevent zombie children - const int err = fork(); - - if (err == 0) { - // (child) - - // close all nonstandard file descriptors - struct rlimit max_fds; - getrlimit(RLIMIT_NOFILE, &max_fds); - - for (rlim_t fd = 3; fd < max_fds.rlim_cur; ++fd) - close(fd); - - switch (fork()) { - case 0: - // (grandchild) - setsid(); - execlp(executable.c_str(), command.c_str(), NULL); - _exit(-1); - - case -1: - // (second) fork failed, there is no grandchild - _exit (-1); - - /* exit the child process here */ - default: - _exit (0); - } - } - - return (err > 0); - } - -private: - Process() {} -}; - - -} // namespace Raul - -#endif // RAUL_PROCESS_H diff --git a/raul/Process.hpp b/raul/Process.hpp new file mode 100644 index 0000000..80063a1 --- /dev/null +++ b/raul/Process.hpp @@ -0,0 +1,92 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_PROCESS_HPP +#define RAUL_PROCESS_HPP + +#include +#include +#include +#include +#include +#include + +namespace Raul { + + +/** A child process. + * + * \ingroup raul + */ +class Process : boost::noncopyable +{ +public: + + /** Launch a sub process. + * + * @param command can be a typical shell command with parameters, the PATH is searched etc. + */ + static bool launch(std::string command) + { + const std::string executable = (command.find(" ") != std::string::npos) + ? command.substr(0, command.find(" ")) + : command; + + std::cerr << "Launching child process '" << executable << "' with command line '" + << command << "'" << std::endl; + + // Use the same double fork() trick as JACK to prevent zombie children + const int err = fork(); + + if (err == 0) { + // (child) + + // close all nonstandard file descriptors + struct rlimit max_fds; + getrlimit(RLIMIT_NOFILE, &max_fds); + + for (rlim_t fd = 3; fd < max_fds.rlim_cur; ++fd) + close(fd); + + switch (fork()) { + case 0: + // (grandchild) + setsid(); + execlp(executable.c_str(), command.c_str(), NULL); + _exit(-1); + + case -1: + // (second) fork failed, there is no grandchild + _exit (-1); + + /* exit the child process here */ + default: + _exit (0); + } + } + + return (err > 0); + } + +private: + Process() {} +}; + + +} // namespace Raul + +#endif // RAUL_PROCESS_HPP diff --git a/raul/Quantizer.h b/raul/Quantizer.h deleted file mode 100644 index 350e2e2..0000000 --- a/raul/Quantizer.h +++ /dev/null @@ -1,36 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_QUANTIZER_H -#define RAUL_QUANTIZER_H - -#include - -namespace Raul { - - -class Quantizer { -public: - inline static double quantize(double q, double value) { - return (q > 0) ? lrint(value / q) * q : value; - } -}; - - -} // namespace Raul - -#endif // RAUL_QUANTIZER_H diff --git a/raul/Quantizer.hpp b/raul/Quantizer.hpp new file mode 100644 index 0000000..13a5cb1 --- /dev/null +++ b/raul/Quantizer.hpp @@ -0,0 +1,36 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_QUANTIZER_HPP +#define RAUL_QUANTIZER_HPP + +#include + +namespace Raul { + + +class Quantizer { +public: + inline static double quantize(double q, double value) { + return (q > 0) ? lrint(value / q) * q : value; + } +}; + + +} // namespace Raul + +#endif // RAUL_QUANTIZER_HPP diff --git a/raul/RDFModel.h b/raul/RDFModel.h deleted file mode 100644 index 35910b5..0000000 --- a/raul/RDFModel.h +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RDFMODEL_H -#define RDFMODEL_H - -#include -#include -#include -#include -#include -#include "raul/Namespaces.h" -#include "raul/Atom.h" -#include "raul/RDFNode.h" - - -namespace Raul { -namespace RDF { - -class World; - - -class Model : public boost::noncopyable { -public: - Model(World& world); - Model(World& world, const Glib::ustring& uri, Glib::ustring base_uri=""); - ~Model(); - - void serialize_to_file_handle(FILE* fd); - void serialize_to_file(const Glib::ustring& uri); - std::string serialize_to_string(); - - void add_statement(const Node& subject, - const Node& predicate, - const Node& object); - - void add_statement(const Node& subject, - const std::string& predicate, - const Node& object); - - void add_statement(const Node& subject, - const Node& predicate, - const Atom& object); - - void add_statement(const Node& subject, - const std::string& predicate, - const Atom& object); - - World& world() const { return _world; } - -private: - friend class Query; - - void setup_prefixes(); - - World& _world; - librdf_storage* _storage; - librdf_model* _model; - librdf_serializer* _serializer; - - size_t _next_blank_id; -}; - - -} // namespace RDF -} // namespace Raul - -#endif // RDFMODEL_H diff --git a/raul/RDFModel.hpp b/raul/RDFModel.hpp new file mode 100644 index 0000000..d6f224e --- /dev/null +++ b/raul/RDFModel.hpp @@ -0,0 +1,82 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_RDF_MODEL_HPP +#define RAUL_RDF_MODEL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Raul { +namespace RDF { + +class World; + + +class Model : public boost::noncopyable { +public: + Model(World& world); + Model(World& world, const Glib::ustring& uri, Glib::ustring base_uri=""); + ~Model(); + + void serialize_to_file_handle(FILE* fd); + void serialize_to_file(const Glib::ustring& uri); + std::string serialize_to_string(); + + void add_statement(const Node& subject, + const Node& predicate, + const Node& object); + + void add_statement(const Node& subject, + const std::string& predicate, + const Node& object); + + void add_statement(const Node& subject, + const Node& predicate, + const Atom& object); + + void add_statement(const Node& subject, + const std::string& predicate, + const Atom& object); + + World& world() const { return _world; } + +private: + friend class Query; + + void setup_prefixes(); + + World& _world; + librdf_storage* _storage; + librdf_model* _model; + librdf_serializer* _serializer; + + size_t _next_blank_id; +}; + + +} // namespace RDF +} // namespace Raul + +#endif // RAUL_RDF_MODEL_HPP diff --git a/raul/RDFNode.h b/raul/RDFNode.h deleted file mode 100644 index 2213b5d..0000000 --- a/raul/RDFNode.h +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RDFNODE_H -#define RDFNODE_H - -#include -#include -#include -#include "raul/Atom.h" - -namespace Raul { -namespace RDF { - -class World; - - -class Node { -public: - enum Type { - UNKNOWN = LIBRDF_NODE_TYPE_UNKNOWN, - RESOURCE = LIBRDF_NODE_TYPE_RESOURCE, - LITERAL = LIBRDF_NODE_TYPE_LITERAL, - BLANK = LIBRDF_NODE_TYPE_BLANK - }; - - Node() : _node(NULL) {} - - Node(World& world, Type t, const std::string& s); - Node(World& world); - Node(librdf_node* node); - Node(const Node& other); - ~Node(); - - Type type() const { return ((_node) ? (Type)librdf_node_get_type(_node) : UNKNOWN); } - - librdf_node* get_node() const { return _node; } - - operator bool() const { return (_node != NULL); } - - const Node& operator=(const Node& other) { - if (_node) - librdf_free_node(_node); - _node = (other._node) ? librdf_new_node_from_node(other._node) : NULL; - return *this; - } - - std::string to_string() const; - std::string to_quoted_uri_string() const; - - bool is_int(); - int to_int(); - - bool is_float(); - float to_float(); - -private: - librdf_node* _node; -}; - - -} // namespace RDF -} // namespace Raul - -#endif // RDFNODE_H diff --git a/raul/RDFNode.hpp b/raul/RDFNode.hpp new file mode 100644 index 0000000..8a09699 --- /dev/null +++ b/raul/RDFNode.hpp @@ -0,0 +1,79 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_RDF_NODE_HPP +#define RAUL_RDF_NODE_HPP + +#include +#include +#include +#include + +namespace Raul { +namespace RDF { + +class World; + + +class Node { +public: + enum Type { + UNKNOWN = LIBRDF_NODE_TYPE_UNKNOWN, + RESOURCE = LIBRDF_NODE_TYPE_RESOURCE, + LITERAL = LIBRDF_NODE_TYPE_LITERAL, + BLANK = LIBRDF_NODE_TYPE_BLANK + }; + + Node() : _node(NULL) {} + + Node(World& world, Type t, const std::string& s); + Node(World& world); + Node(librdf_node* node); + Node(const Node& other); + ~Node(); + + Type type() const { return ((_node) ? (Type)librdf_node_get_type(_node) : UNKNOWN); } + + librdf_node* get_node() const { return _node; } + + operator bool() const { return (_node != NULL); } + + const Node& operator=(const Node& other) { + if (_node) + librdf_free_node(_node); + _node = (other._node) ? librdf_new_node_from_node(other._node) : NULL; + return *this; + } + + std::string to_string() const; + std::string to_quoted_uri_string() const; + + bool is_int(); + int to_int(); + + bool is_float(); + float to_float(); + +private: + librdf_node* _node; +}; + + +} // namespace RDF +} // namespace Raul + +#endif // RAUL_RDF_NODE_HPP diff --git a/raul/RDFQuery.h b/raul/RDFQuery.h deleted file mode 100644 index eef52bd..0000000 --- a/raul/RDFQuery.h +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_RDFQUERY_H -#define RAUL_RDFQUERY_H - -#include -#include -#include -#include "raul/RDFWorld.h" -#include "raul/Namespaces.h" - -namespace Raul { -namespace RDF { - -class World; -class Model; - - -/** Pretty wrapper for a SPARQL query. - * - * Automatically handles things like prepending prefixes, etc. - */ -class Query { -public: - typedef std::map Bindings; // FIXME: order? better to use int - typedef std::list Results; - - Query(const World& world, Glib::ustring query) - { - // Prepend prefix header - for (Namespaces::const_iterator i = world.prefixes().begin(); - i != world.prefixes().end(); ++i) { - _query += "PREFIX "; - _query += i->first + ": <" + i->second + ">\n"; - } - _query += "\n"; - _query += query; - } - - Results run(World& world, Model& model, const Glib::ustring base_uri="") const; - - Glib::ustring string() const { return _query; }; - -private: - Glib::ustring _query; -}; - - -} // namespace RDF -} // namespace Raul - -#endif // RAUL_RDFQUERY_H - diff --git a/raul/RDFQuery.hpp b/raul/RDFQuery.hpp new file mode 100644 index 0000000..76ae128 --- /dev/null +++ b/raul/RDFQuery.hpp @@ -0,0 +1,68 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_RDF_QUERY_HPP +#define RAUL_RDF_QUERY_HPP + +#include +#include +#include +#include +#include + +namespace Raul { +namespace RDF { + +class World; +class Model; + + +/** Pretty wrapper for a SPARQL query. + * + * Automatically handles things like prepending prefixes, etc. + */ +class Query { +public: + typedef std::map Bindings; // FIXME: order? better to use int + typedef std::list Results; + + Query(const World& world, Glib::ustring query) + { + // Prepend prefix header + for (Namespaces::const_iterator i = world.prefixes().begin(); + i != world.prefixes().end(); ++i) { + _query += "PREFIX "; + _query += i->first + ": <" + i->second + ">\n"; + } + _query += "\n"; + _query += query; + } + + Results run(World& world, Model& model, const Glib::ustring base_uri="") const; + + Glib::ustring string() const { return _query; }; + +private: + Glib::ustring _query; +}; + + +} // namespace RDF +} // namespace Raul + +#endif // RAUL_RDF_QUERY_HPP + diff --git a/raul/RDFWorld.h b/raul/RDFWorld.h deleted file mode 100644 index 8bbd3d1..0000000 --- a/raul/RDFWorld.h +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RDFWORLD_H -#define RDFWORLD_H - -#include -#include -#include -#include -#include "raul/Namespaces.h" -#include "raul/RDFNode.h" - -namespace Raul { -namespace RDF { - - -class World : public boost::noncopyable { -public: - World(); - ~World(); - - Node blank_id(); - - void add_prefix(const std::string& prefix, const std::string& uri); - std::string expand_uri(const std::string& uri) const; - std::string qualify(const std::string& uri) const; - - const Namespaces& prefixes() const { return _prefixes; } - - librdf_world* world() { return _world; } - -private: - void setup_prefixes(); - - librdf_world* _world; - Namespaces _prefixes; - - size_t _next_blank_id; -}; - - -} // namespace RDF -} // namespace Raul - -#endif // RDFWORLD_H diff --git a/raul/RDFWorld.hpp b/raul/RDFWorld.hpp new file mode 100644 index 0000000..7e3833f --- /dev/null +++ b/raul/RDFWorld.hpp @@ -0,0 +1,60 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_RDF_WORLD_HPP +#define RAUL_RDF_WORLD_HPP + +#include +#include +#include +#include +#include +#include + +namespace Raul { +namespace RDF { + + +class World : public boost::noncopyable { +public: + World(); + ~World(); + + Node blank_id(); + + void add_prefix(const std::string& prefix, const std::string& uri); + std::string expand_uri(const std::string& uri) const; + std::string qualify(const std::string& uri) const; + + const Namespaces& prefixes() const { return _prefixes; } + + librdf_world* world() { return _world; } + +private: + void setup_prefixes(); + + librdf_world* _world; + Namespaces _prefixes; + + size_t _next_blank_id; +}; + + +} // namespace RDF +} // namespace Raul + +#endif // RAUL_RDF_WORLD_HPP diff --git a/raul/RingBuffer.h b/raul/RingBuffer.h deleted file mode 100644 index beaf957..0000000 --- a/raul/RingBuffer.h +++ /dev/null @@ -1,163 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL__RING_BUFFER_H -#define RAUL__RING_BUFFER_H - -#include -#include - -namespace Raul { - - -/** A lock-free RingBuffer. - * Read/Write realtime safe. - * Single-reader Single-writer thread safe. - */ -template -class RingBuffer { -public: - - /** @param size Size in bytes. - */ - RingBuffer(size_t size) - : _size(size) - , _buf(new T[size]) - { - reset(); - assert(read_space() == 0); - assert(write_space() == size - 1); - } - - virtual ~RingBuffer() { - delete[] _buf; - } - - /** Reset(empty) the ringbuffer. - * NOT thread safe. - */ - void reset() { - g_atomic_int_set(&_write_ptr, 0); - g_atomic_int_set(&_read_ptr, 0); - } - - size_t write_space() const { - - const size_t w = g_atomic_int_get(&_write_ptr); - const size_t r = g_atomic_int_get(&_read_ptr); - - if (w > r) { - return ((r - w + _size) % _size) - 1; - } else if(w < r) { - return (r - w) - 1; - } else { - return _size - 1; - } - } - - size_t read_space() const { - - const size_t w = g_atomic_int_get(&_write_ptr); - const size_t r = g_atomic_int_get(&_read_ptr); - - if (w > r) { - return w - r; - } else { - return (w - r + _size) % _size; - } - } - - size_t capacity() const { return _size; } - - size_t read(size_t size, T* dst); - void write(size_t size, const T* src); - - bool full_read(size_t size, T* dst); - -protected: - mutable gint _write_ptr; - mutable gint _read_ptr; - - size_t _size; ///< Size (capacity) in bytes - T* _buf; ///< size, event, size, event... -}; - - -/** Read from the ringbuffer. - * - * Note that a full read may not be done if the data wraps around. - * Caller must check return value and call again if necessary, or use the - * full_read method which does this automatically. - */ -template -size_t -RingBuffer::read(size_t size, T* dst) -{ - const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); - - const size_t read_size = (priv_read_ptr + size < _size) - ? size - : _size - priv_read_ptr; - - memcpy(dst, &_buf[priv_read_ptr], read_size); - - g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) % _size); - - return read_size; -} - - -template -inline void -RingBuffer::write(size_t size, const T* src) -{ - const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr); - - if (priv_write_ptr + size <= _size) { - memcpy(&_buf[priv_write_ptr], src, size); - g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) % _size); - } else { - const size_t this_size = _size - priv_write_ptr; - assert(this_size < size); - assert(priv_write_ptr + this_size <= _size); - memcpy(&_buf[priv_write_ptr], src, this_size); - memcpy(&_buf[0], src+this_size, size - this_size); - g_atomic_int_set(&_write_ptr, size - this_size); - } -} - - -template -bool -RingBuffer::full_read(size_t size, T* dst) -{ - if (read_space() < size) - return false; - - const size_t read_size = read(size, dst); - - if (read_size < size) - read(size - read_size, dst + read_size); - - return true; -} - - -} // namespace Raul - -#endif // RAUL_RING_BUFFER_H - diff --git a/raul/RingBuffer.hpp b/raul/RingBuffer.hpp new file mode 100644 index 0000000..b746bce --- /dev/null +++ b/raul/RingBuffer.hpp @@ -0,0 +1,163 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_RING_BUFFER_HPP +#define RAUL_RING_BUFFER_HPP + +#include +#include + +namespace Raul { + + +/** A lock-free RingBuffer. + * Read/Write realtime safe. + * Single-reader Single-writer thread safe. + */ +template +class RingBuffer { +public: + + /** @param size Size in bytes. + */ + RingBuffer(size_t size) + : _size(size) + , _buf(new T[size]) + { + reset(); + assert(read_space() == 0); + assert(write_space() == size - 1); + } + + virtual ~RingBuffer() { + delete[] _buf; + } + + /** Reset(empty) the ringbuffer. + * NOT thread safe. + */ + void reset() { + g_atomic_int_set(&_write_ptr, 0); + g_atomic_int_set(&_read_ptr, 0); + } + + size_t write_space() const { + + const size_t w = g_atomic_int_get(&_write_ptr); + const size_t r = g_atomic_int_get(&_read_ptr); + + if (w > r) { + return ((r - w + _size) % _size) - 1; + } else if(w < r) { + return (r - w) - 1; + } else { + return _size - 1; + } + } + + size_t read_space() const { + + const size_t w = g_atomic_int_get(&_write_ptr); + const size_t r = g_atomic_int_get(&_read_ptr); + + if (w > r) { + return w - r; + } else { + return (w - r + _size) % _size; + } + } + + size_t capacity() const { return _size; } + + size_t read(size_t size, T* dst); + void write(size_t size, const T* src); + + bool full_read(size_t size, T* dst); + +protected: + mutable gint _write_ptr; + mutable gint _read_ptr; + + size_t _size; ///< Size (capacity) in bytes + T* _buf; ///< size, event, size, event... +}; + + +/** Read from the ringbuffer. + * + * Note that a full read may not be done if the data wraps around. + * Caller must check return value and call again if necessary, or use the + * full_read method which does this automatically. + */ +template +size_t +RingBuffer::read(size_t size, T* dst) +{ + const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); + + const size_t read_size = (priv_read_ptr + size < _size) + ? size + : _size - priv_read_ptr; + + memcpy(dst, &_buf[priv_read_ptr], read_size); + + g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) % _size); + + return read_size; +} + + +template +inline void +RingBuffer::write(size_t size, const T* src) +{ + const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr); + + if (priv_write_ptr + size <= _size) { + memcpy(&_buf[priv_write_ptr], src, size); + g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) % _size); + } else { + const size_t this_size = _size - priv_write_ptr; + assert(this_size < size); + assert(priv_write_ptr + this_size <= _size); + memcpy(&_buf[priv_write_ptr], src, this_size); + memcpy(&_buf[0], src+this_size, size - this_size); + g_atomic_int_set(&_write_ptr, size - this_size); + } +} + + +template +bool +RingBuffer::full_read(size_t size, T* dst) +{ + if (read_space() < size) + return false; + + const size_t read_size = read(size, dst); + + if (read_size < size) + read(size - read_size, dst + read_size); + + return true; +} + + +} // namespace Raul + +#endif // RAUL_RING_BUFFER_HPP + diff --git a/raul/SMFReader.h b/raul/SMFReader.h deleted file mode 100644 index 771f139..0000000 --- a/raul/SMFReader.h +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_SMFREADER_H -#define RAUL_SMFREADER_H - -#include - -namespace Raul { - - -/** Standard Midi File (Type 0) Reader - * - * Currently this only reads SMF files with tempo-based timing. - */ -class SMFReader { -public: - SMFReader(); - ~SMFReader(); - - bool open(const std::string& filename); - - bool seek_to_track(unsigned track); - - uint16_t type() const { return _type; } - uint16_t ppqn() const { return _ppqn; } - size_t num_tracks() { return _num_tracks; } - - int read_event(size_t buf_len, unsigned char* buf, uint32_t* ev_size, uint32_t* ev_delta_time); - - void close(); - -protected: - //static const uint32_t VAR_LEN_MAX = 0x0FFFFFFF; - - /** size of SMF header, including MTrk chunk header */ - static const uint32_t HEADER_SIZE = 22; - - uint32_t read_var_len() const; - - std::string _filename; - FILE* _fd; - uint16_t _type; - uint16_t _ppqn; - uint16_t _num_tracks; - //uint32_t _track; - uint32_t _track_size; -/* Raul::BeatTime _start_time; - Raul::BeatTime _last_ev_time; ///< Time last event was written relative to _start_time - */ -}; - - -} // namespace Raul - -#endif // RAUL_SMFREADER_H - diff --git a/raul/SMFReader.hpp b/raul/SMFReader.hpp new file mode 100644 index 0000000..bc7035d --- /dev/null +++ b/raul/SMFReader.hpp @@ -0,0 +1,71 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_SMF_READER_HPP +#define RAUL_SMF_READER_HPP + +#include + +namespace Raul { + + +/** Standard Midi File (Type 0) Reader + * + * Currently this only reads SMF files with tempo-based timing. + */ +class SMFReader { +public: + SMFReader(); + ~SMFReader(); + + bool open(const std::string& filename); + + bool seek_to_track(unsigned track); + + uint16_t type() const { return _type; } + uint16_t ppqn() const { return _ppqn; } + size_t num_tracks() { return _num_tracks; } + + int read_event(size_t buf_len, unsigned char* buf, uint32_t* ev_size, uint32_t* ev_delta_time); + + void close(); + +protected: + //static const uint32_t VAR_LEN_MAX = 0x0FFFFFFF; + + /** size of SMF header, including MTrk chunk header */ + static const uint32_t HEADER_SIZE = 22; + + uint32_t read_var_len() const; + + std::string _filename; + FILE* _fd; + uint16_t _type; + uint16_t _ppqn; + uint16_t _num_tracks; + //uint32_t _track; + uint32_t _track_size; +/* Raul::BeatTime _start_time; + Raul::BeatTime _last_ev_time; ///< Time last event was written relative to _start_time + */ +}; + + +} // namespace Raul + +#endif // RAUL_SMF_READER_HPP + diff --git a/raul/SMFWriter.h b/raul/SMFWriter.h deleted file mode 100644 index 875c151..0000000 --- a/raul/SMFWriter.h +++ /dev/null @@ -1,72 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_SMFWRITER_H -#define RAUL_SMFWRITER_H - -#include -#include - -namespace Raul { - - -/** Standard Midi File (Type 0) Writer - */ -class SMFWriter : public Raul::MIDISink { -public: - SMFWriter(unsigned short ppqn=1920); - ~SMFWriter(); - - bool start(const std::string& filename, - BeatTime start_time=0) throw (std::logic_error); - - uint16_t ppqn() const { return _ppqn; } - - void write_event(BeatTime time, - size_t ev_size, - const unsigned char* ev) throw (std::logic_error); - - void flush(); - - void finish() throw (std::logic_error); - -protected: - static const uint32_t VAR_LEN_MAX = 0x0FFFFFFF; - - void write_header(); - void write_footer(); - - void write_chunk_header(char id[4], uint32_t length); - void write_chunk(char id[4], uint32_t length, void* data); - size_t write_var_len(uint32_t val); - //uint32_t read_var_len() const; - //int read_event(MidiEvent& ev) const; - - std::string _filename; - FILE* _fd; - uint16_t _ppqn; - Raul::BeatTime _start_time; - Raul::BeatTime _last_ev_time; ///< Time last event was written relative to _start_time - uint32_t _track_size; - uint32_t _header_size; ///< size of SMF header, including MTrk chunk header -}; - - -} // namespace Raul - -#endif // RAUL_SMFWRITER_H - diff --git a/raul/SMFWriter.hpp b/raul/SMFWriter.hpp new file mode 100644 index 0000000..8994131 --- /dev/null +++ b/raul/SMFWriter.hpp @@ -0,0 +1,72 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_SMF_WRITER_HPP +#define RAUL_SMF_WRITER_HPP + +#include +#include + +namespace Raul { + + +/** Standard Midi File (Type 0) Writer + */ +class SMFWriter : public Raul::MIDISink { +public: + SMFWriter(unsigned short ppqn=1920); + ~SMFWriter(); + + bool start(const std::string& filename, + BeatTime start_time=0) throw (std::logic_error); + + uint16_t ppqn() const { return _ppqn; } + + void write_event(BeatTime time, + size_t ev_size, + const unsigned char* ev) throw (std::logic_error); + + void flush(); + + void finish() throw (std::logic_error); + +protected: + static const uint32_t VAR_LEN_MAX = 0x0FFFFFFF; + + void write_header(); + void write_footer(); + + void write_chunk_header(char id[4], uint32_t length); + void write_chunk(char id[4], uint32_t length, void* data); + size_t write_var_len(uint32_t val); + //uint32_t read_var_len() const; + //int read_event(MidiEvent& ev) const; + + std::string _filename; + FILE* _fd; + uint16_t _ppqn; + Raul::BeatTime _start_time; + Raul::BeatTime _last_ev_time; ///< Time last event was written relative to _start_time + uint32_t _track_size; + uint32_t _header_size; ///< size of SMF header, including MTrk chunk header +}; + + +} // namespace Raul + +#endif // RAUL_SMF_WRITER_HPP + diff --git a/raul/SRMWQueue.h b/raul/SRMWQueue.h deleted file mode 100644 index 5b841e5..0000000 --- a/raul/SRMWQueue.h +++ /dev/null @@ -1,224 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_SRMW_QUEUE_H -#define RAUL_SRMW_QUEUE_H - -#include -#include -#include -#include -#include "raul/AtomicInt.h" - -#include -using namespace std; - -namespace Raul { - - -/** Realtime-safe single-reader multi-writer queue (aka lock-free ringbuffer) - * - * Implemented as a dequeue in a fixed array. Both push and pop are realtime - * safe, but only push is threadsafe. In other words, multiple threads can push - * data into this queue for a single thread to consume. - * - * The interface is intentionally as similar to std::queue as possible, but - * note the additional thread restrictions imposed (e.g. empty() is only - * legal to call in the read thread). - * - * Obey the threading restrictions documented here, or horrible nasty (possibly - * undetected) errors will occur. - * - * If you only need a single writer, use SRSWQueue. This is slightly more - * computationally expensive, and allocates an additional size words of memory (ie - * if you're using this for ints or pointers etc, SRMWQueue will be twice the size - * of SRSWQueue for the same queue size. Additionally, the size of this queue must - * be a power of 2 (SRSWQueue does not have this limitation). - * - * \ingroup raul - */ -template -class SRMWQueue : boost::noncopyable -{ -public: - SRMWQueue(size_t size); - ~SRMWQueue(); - - - // Any thread: - - inline size_t capacity() const { return _size-1; } - - - // Write thread(s): - - inline bool full() const; - inline bool push(const T& obj); - - - // Read thread: - - inline bool empty() const; - inline T& front() const; - inline void pop(); - -private: - - // Note that _front doesn't need to be an AtomicInt since it's only accessed - // by the (single) reader thread - - unsigned _front; ///< Circular index of element at front of queue (READER ONLY) - AtomicInt _back; ///< Circular index 1 past element at back of queue (WRITERS ONLY) - AtomicInt _write_space; ///< Remaining free space for new elements (all threads) - const unsigned _size; ///< Size of @ref _objects (you can store _size-1 objects) - - T* const _objects; ///< Fixed array containing queued elements - AtomicInt* const _valid; ///< Parallel array to _objects, whether loc is written or not -}; - - -template -SRMWQueue::SRMWQueue(size_t size) - : _front(0) - , _back(0) - , _write_space(size) - , _size(size+1) - , _objects((T*)calloc(_size, sizeof(T))) - , _valid((AtomicInt*)calloc(_size, sizeof(AtomicInt))) -{ - assert(log2(size) - (int)log2(size) == 0); - assert(size > 1); - assert(_size-1 == (unsigned)_write_space.get()); - - for (unsigned i=0; i < _size; ++i) { - assert(_valid[i].get() == 0); - } -} - - -template -SRMWQueue::~SRMWQueue() -{ - free(_objects); -} - - -/** Return whether the queue is full. - * - * Write thread(s) only. - */ -template -inline bool -SRMWQueue::full() const -{ - return (_write_space.get() <= 0); -} - - -/** Push an item onto the back of the SRMWQueue - realtime-safe, not thread-safe. - * - * Write thread(s) only. - * - * @returns true if @a elem was successfully pushed onto the queue, - * false otherwise (queue is full). - */ -template -inline bool -SRMWQueue::push(const T& elem) -{ - const int old_write_space = _write_space.exchange_and_add(-1); - const bool already_full = ( old_write_space <= 0 ); - - /* Technically right here pop could be called in the reader thread and - * make space available, but no harm in failing anyway - this queue - * really isn't designed to be filled... */ - - if (already_full) { - - /* if multiple threads simultaneously get here, _write_space may be 0 - * or negative. The next call to pop() will set _write_space back to - * a sane value. Note that _write_space is not exposed, so this is okay - * (... assuming this code is correct) */ - - return false; - - } else { - - // Note: _size must be a power of 2 for this to not explode when _back overflows - const unsigned write_index = (unsigned)_back.exchange_and_add(1) % _size; - - assert(_valid[write_index] == 0); - _objects[write_index] = elem; - ++(_valid[write_index]); - - return true; - - } -} - - -/** Return whether the queue is empty. - * - * Read thread only. - */ -template -inline bool -SRMWQueue::empty() const -{ - return (_valid[_front].get() == 0); -} - - -/** Return the element at the front of the queue without removing it. - * - * It is a fatal error to call front() when the queue is empty. - * Read thread only. - */ -template -inline T& -SRMWQueue::front() const -{ - return _objects[_front]; -} - - -/** Pop an item off the front of the queue - realtime-safe, NOT thread-safe. - * - * It is a fatal error to call pop() if the queue is empty. - * Read thread only. - * - * @return true if queue is now empty, otherwise false. - */ -template -inline void -SRMWQueue::pop() -{ - assert(_valid[_front] == 1); - --(_valid[_front]); - - _front = (_front + 1) % (_size); - - if (_write_space.get() < 0) - _write_space = 1; - else - ++_write_space; -} - - -} // namespace Raul - -#endif // RAUL_SRMW_QUEUE_H diff --git a/raul/SRMWQueue.hpp b/raul/SRMWQueue.hpp new file mode 100644 index 0000000..ebdce5b --- /dev/null +++ b/raul/SRMWQueue.hpp @@ -0,0 +1,224 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_SRMW_QUEUE_HPP +#define RAUL_SRMW_QUEUE_HPP + +#include +#include +#include +#include +#include + +#include +using namespace std; + +namespace Raul { + + +/** Realtime-safe single-reader multi-writer queue (aka lock-free ringbuffer) + * + * Implemented as a dequeue in a fixed array. Both push and pop are realtime + * safe, but only push is threadsafe. In other words, multiple threads can push + * data into this queue for a single thread to consume. + * + * The interface is intentionally as similar to std::queue as possible, but + * note the additional thread restrictions imposed (e.g. empty() is only + * legal to call in the read thread). + * + * Obey the threading restrictions documented here, or horrible nasty (possibly + * undetected) errors will occur. + * + * If you only need a single writer, use SRSWQueue. This is slightly more + * computationally expensive, and allocates an additional size words of memory (ie + * if you're using this for ints or pointers etc, SRMWQueue will be twice the size + * of SRSWQueue for the same queue size. Additionally, the size of this queue must + * be a power of 2 (SRSWQueue does not have this limitation). + * + * \ingroup raul + */ +template +class SRMWQueue : boost::noncopyable +{ +public: + SRMWQueue(size_t size); + ~SRMWQueue(); + + + // Any thread: + + inline size_t capacity() const { return _size-1; } + + + // Write thread(s): + + inline bool full() const; + inline bool push(const T& obj); + + + // Read thread: + + inline bool empty() const; + inline T& front() const; + inline void pop(); + +private: + + // Note that _front doesn't need to be an AtomicInt since it's only accessed + // by the (single) reader thread + + unsigned _front; ///< Circular index of element at front of queue (READER ONLY) + AtomicInt _back; ///< Circular index 1 past element at back of queue (WRITERS ONLY) + AtomicInt _write_space; ///< Remaining free space for new elements (all threads) + const unsigned _size; ///< Size of @ref _objects (you can store _size-1 objects) + + T* const _objects; ///< Fixed array containing queued elements + AtomicInt* const _valid; ///< Parallel array to _objects, whether loc is written or not +}; + + +template +SRMWQueue::SRMWQueue(size_t size) + : _front(0) + , _back(0) + , _write_space(size) + , _size(size+1) + , _objects((T*)calloc(_size, sizeof(T))) + , _valid((AtomicInt*)calloc(_size, sizeof(AtomicInt))) +{ + assert(log2(size) - (int)log2(size) == 0); + assert(size > 1); + assert(_size-1 == (unsigned)_write_space.get()); + + for (unsigned i=0; i < _size; ++i) { + assert(_valid[i].get() == 0); + } +} + + +template +SRMWQueue::~SRMWQueue() +{ + free(_objects); +} + + +/** Return whether the queue is full. + * + * Write thread(s) only. + */ +template +inline bool +SRMWQueue::full() const +{ + return (_write_space.get() <= 0); +} + + +/** Push an item onto the back of the SRMWQueue - realtime-safe, not thread-safe. + * + * Write thread(s) only. + * + * @returns true if @a elem was successfully pushed onto the queue, + * false otherwise (queue is full). + */ +template +inline bool +SRMWQueue::push(const T& elem) +{ + const int old_write_space = _write_space.exchange_and_add(-1); + const bool already_full = ( old_write_space <= 0 ); + + /* Technically right here pop could be called in the reader thread and + * make space available, but no harm in failing anyway - this queue + * really isn't designed to be filled... */ + + if (already_full) { + + /* if multiple threads simultaneously get here, _write_space may be 0 + * or negative. The next call to pop() will set _write_space back to + * a sane value. Note that _write_space is not exposed, so this is okay + * (... assuming this code is correct) */ + + return false; + + } else { + + // Note: _size must be a power of 2 for this to not explode when _back overflows + const unsigned write_index = (unsigned)_back.exchange_and_add(1) % _size; + + assert(_valid[write_index] == 0); + _objects[write_index] = elem; + ++(_valid[write_index]); + + return true; + + } +} + + +/** Return whether the queue is empty. + * + * Read thread only. + */ +template +inline bool +SRMWQueue::empty() const +{ + return (_valid[_front].get() == 0); +} + + +/** Return the element at the front of the queue without removing it. + * + * It is a fatal error to call front() when the queue is empty. + * Read thread only. + */ +template +inline T& +SRMWQueue::front() const +{ + return _objects[_front]; +} + + +/** Pop an item off the front of the queue - realtime-safe, NOT thread-safe. + * + * It is a fatal error to call pop() if the queue is empty. + * Read thread only. + * + * @return true if queue is now empty, otherwise false. + */ +template +inline void +SRMWQueue::pop() +{ + assert(_valid[_front] == 1); + --(_valid[_front]); + + _front = (_front + 1) % (_size); + + if (_write_space.get() < 0) + _write_space = 1; + else + ++_write_space; +} + + +} // namespace Raul + +#endif // RAUL_SRMW_QUEUE_HPP diff --git a/raul/SRSWQueue.h b/raul/SRSWQueue.h deleted file mode 100644 index c5c2d1d..0000000 --- a/raul/SRSWQueue.h +++ /dev/null @@ -1,157 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_SRSW_QUEUE_H -#define RAUL_SRSW_QUEUE_H - -#include -#include -#include -#include "raul/AtomicInt.h" - -namespace Raul { - - -/** Realtime-safe single-reader single-writer queue (aka lock-free ringbuffer) - * - * Implemented as a dequeue in a fixed array. This is read/write thread-safe, - * pushing and popping may occur simultaneously by seperate threads, but - * the push and pop operations themselves are not thread-safe (ie. there can - * be at most 1 read and at most 1 writer thread). - * - * \ingroup raul - */ -template -class SRSWQueue : boost::noncopyable -{ -public: - SRSWQueue(size_t size); - ~SRSWQueue(); - - // Any thread: - - inline size_t capacity() const { return _size-1; } - - - // Write thread(s): - - inline bool full() const; - inline bool push(const T& obj); - - - // Read thread: - - inline bool empty() const; - inline T& front() const; - inline void pop(); - -private: - volatile size_t _front; ///< Index to front of queue (circular) - volatile size_t _back; ///< Index to back of queue (one past last element) (circular) - const size_t _size; ///< Size of @ref _objects (you can store _size-1 objects) - T* const _objects; ///< Fixed array containing queued elements -}; - - -template -SRSWQueue::SRSWQueue(size_t size) -: _front(0), - _back(0), - _size(size+1), - _objects((T*)calloc(_size, sizeof(T))) -{ - assert(size > 1); -} - - -template -SRSWQueue::~SRSWQueue() -{ - free(_objects); -} - - -/** Return whether or not the queue is empty. - */ -template -inline bool -SRSWQueue::empty() const -{ - return (_back == _front); -} - - -/** Return whether or not the queue is full. - */ -template -inline bool -SRSWQueue::full() const -{ - // FIXME: uses both _front and _back - thread safe? - return ( ((_front - _back + _size) % _size) == 1 ); -} - - -/** Return the element at the front of the queue without removing it - */ -template -inline T& -SRSWQueue::front() const -{ - return _objects[_front]; -} - - -/** Push an item onto the back of the SRSWQueue - realtime-safe, not thread-safe. - * - * @returns true if @a elem was successfully pushed onto the queue, - * false otherwise (queue is full). - */ -template -inline bool -SRSWQueue::push(const T& elem) -{ - if (full()) { - return false; - } else { - _objects[_back] = elem; - _back = (_back + 1) % (_size); - return true; - } -} - - -/** Pop an item off the front of the queue - realtime-safe, not thread-safe. - * - * It is a fatal error to call pop() when the queue is empty. - * - * @returns the element popped. - */ -template -inline void -SRSWQueue::pop() -{ - assert(!empty()); - assert(_size > 0); - - _front = (_front + 1) % (_size); -} - - -} // namespace Raul - -#endif // RAUL_SRSW_QUEUE_H diff --git a/raul/SRSWQueue.hpp b/raul/SRSWQueue.hpp new file mode 100644 index 0000000..0273f80 --- /dev/null +++ b/raul/SRSWQueue.hpp @@ -0,0 +1,157 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_SRSW_QUEUE_HPP +#define RAUL_SRSW_QUEUE_HPP + +#include +#include +#include +#include + +namespace Raul { + + +/** Realtime-safe single-reader single-writer queue (aka lock-free ringbuffer) + * + * Implemented as a dequeue in a fixed array. This is read/write thread-safe, + * pushing and popping may occur simultaneously by seperate threads, but + * the push and pop operations themselves are not thread-safe (ie. there can + * be at most 1 read and at most 1 writer thread). + * + * \ingroup raul + */ +template +class SRSWQueue : boost::noncopyable +{ +public: + SRSWQueue(size_t size); + ~SRSWQueue(); + + // Any thread: + + inline size_t capacity() const { return _size-1; } + + + // Write thread(s): + + inline bool full() const; + inline bool push(const T& obj); + + + // Read thread: + + inline bool empty() const; + inline T& front() const; + inline void pop(); + +private: + volatile size_t _front; ///< Index to front of queue (circular) + volatile size_t _back; ///< Index to back of queue (one past last element) (circular) + const size_t _size; ///< Size of @ref _objects (you can store _size-1 objects) + T* const _objects; ///< Fixed array containing queued elements +}; + + +template +SRSWQueue::SRSWQueue(size_t size) +: _front(0), + _back(0), + _size(size+1), + _objects((T*)calloc(_size, sizeof(T))) +{ + assert(size > 1); +} + + +template +SRSWQueue::~SRSWQueue() +{ + free(_objects); +} + + +/** Return whether or not the queue is empty. + */ +template +inline bool +SRSWQueue::empty() const +{ + return (_back == _front); +} + + +/** Return whether or not the queue is full. + */ +template +inline bool +SRSWQueue::full() const +{ + // FIXME: uses both _front and _back - thread safe? + return ( ((_front - _back + _size) % _size) == 1 ); +} + + +/** Return the element at the front of the queue without removing it + */ +template +inline T& +SRSWQueue::front() const +{ + return _objects[_front]; +} + + +/** Push an item onto the back of the SRSWQueue - realtime-safe, not thread-safe. + * + * @returns true if @a elem was successfully pushed onto the queue, + * false otherwise (queue is full). + */ +template +inline bool +SRSWQueue::push(const T& elem) +{ + if (full()) { + return false; + } else { + _objects[_back] = elem; + _back = (_back + 1) % (_size); + return true; + } +} + + +/** Pop an item off the front of the queue - realtime-safe, not thread-safe. + * + * It is a fatal error to call pop() when the queue is empty. + * + * @returns the element popped. + */ +template +inline void +SRSWQueue::pop() +{ + assert(!empty()); + assert(_size > 0); + + _front = (_front + 1) % (_size); +} + + +} // namespace Raul + +#endif // RAUL_SRSW_QUEUE_HPP diff --git a/raul/Semaphore.h b/raul/Semaphore.h deleted file mode 100644 index 28bd93e..0000000 --- a/raul/Semaphore.h +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_SEMAPHORE_H -#define RAUL_SEMAPHORE_H - -#include -#include - -namespace Raul { - - -/** Trivial wrapper around POSIX semaphores (zero memory overhead). - * - * This was created to provide an alternative debuggable implementation of - * semaphores based on a cond/mutex pair because semaphore's appeared not to - * work in GDB. Turns out sem_wait can fail when run in GDB, and Debian - * really needs to update it's man pages. - * - * This class remains as a trivial (yet pretty) wrapper/abstraction. - * - * \ingroup raul - */ -class Semaphore : boost::noncopyable { -public: - inline Semaphore(unsigned int initial) { sem_init(&_sem, 0, initial); } - - inline ~Semaphore() { sem_destroy(&_sem); } - - inline void reset(unsigned int initial) - { sem_destroy(&_sem); sem_init(&_sem, 0, initial); } - - /** Increment (and signal any waiters). - * - * Realtime safe. - */ - inline void post() { sem_post(&_sem); } - - /** Wait until count is > 0, then decrement. - * - * Note that sem_wait always returns 0 in practise. It returns nonzero - * when run in GDB, so the while is necessary to allow debugging. - * - * Obviously not realtime safe. - */ - inline void wait() { while (sem_wait(&_sem) != 0) ; } - - /** Non-blocking version of wait(). - * - * Realtime safe? - */ - inline int try_wait() { return sem_trywait(&_sem); } - -private: - sem_t _sem; -}; - - -} // namespace Raul - -#endif // RAUL_SEMAPHORE_H diff --git a/raul/Semaphore.hpp b/raul/Semaphore.hpp new file mode 100644 index 0000000..93dae0a --- /dev/null +++ b/raul/Semaphore.hpp @@ -0,0 +1,75 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_SEMAPHORE_HPP +#define RAUL_SEMAPHORE_HPP + +#include +#include + +namespace Raul { + + +/** Trivial wrapper around POSIX semaphores (zero memory overhead). + * + * This was created to provide an alternative debuggable implementation of + * semaphores based on a cond/mutex pair because semaphore's appeared not to + * work in GDB. Turns out sem_wait can fail when run in GDB, and Debian + * really needs to update it's man pages. + * + * This class remains as a trivial (yet pretty) wrapper/abstraction. + * + * \ingroup raul + */ +class Semaphore : boost::noncopyable { +public: + inline Semaphore(unsigned int initial) { sem_init(&_sem, 0, initial); } + + inline ~Semaphore() { sem_destroy(&_sem); } + + inline void reset(unsigned int initial) + { sem_destroy(&_sem); sem_init(&_sem, 0, initial); } + + /** Increment (and signal any waiters). + * + * Realtime safe. + */ + inline void post() { sem_post(&_sem); } + + /** Wait until count is > 0, then decrement. + * + * Note that sem_wait always returns 0 in practise. It returns nonzero + * when run in GDB, so the while is necessary to allow debugging. + * + * Obviously not realtime safe. + */ + inline void wait() { while (sem_wait(&_sem) != 0) ; } + + /** Non-blocking version of wait(). + * + * Realtime safe? + */ + inline int try_wait() { return sem_trywait(&_sem); } + +private: + sem_t _sem; +}; + + +} // namespace Raul + +#endif // RAUL_SEMAPHORE_HPP diff --git a/raul/SharedPtr.h b/raul/SharedPtr.h deleted file mode 100644 index 60840c0..0000000 --- a/raul/SharedPtr.h +++ /dev/null @@ -1,63 +0,0 @@ -/* A Reference Counting Smart Pointer. - * Copyright (C) 2007 Dave Robillard - * - * This is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This file is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_SHARED_PTR_H -#define RAUL_SHARED_PTR_H - -#include -#include - -#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS -#include -#include -#include - -static std::list shared_ptr_counters; - -// Use debug hooks to ensure 2 shared_ptrs never point to the same thing -namespace boost { - - inline void sp_scalar_constructor_hook(void* object, unsigned long cnt, void* ptr) { - assert(std::find(shared_ptr_counters.begin(), shared_ptr_counters.end(), - (void*)object) == shared_ptr_counters.end()); - shared_ptr_counters.push_back(object); - //std::cerr << "Creating SharedPtr to " - // << object << ", count = " << cnt << std::endl; - } - - inline void sp_scalar_destructor_hook(void* object, unsigned long cnt, void* ptr) { - shared_ptr_counters.remove(object); - //std::cerr << "Destroying SharedPtr to " - // << object << ", count = " << cnt << std::endl; - } - -} -#endif // BOOST_SP_ENABLE_DEBUG_HOOKS - - -#include - -#ifdef BOOST_AC_USE_PTHREADS -#error "Boost is using mutex locking for pointer reference counting." -#error "This is VERY slow. Please report your platform to dave@drobilla.net" -#endif - -#define SharedPtr boost::shared_ptr -#define PtrCast boost::dynamic_pointer_cast - -#endif // RAUL_SHARED_PTR_H - diff --git a/raul/SharedPtr.hpp b/raul/SharedPtr.hpp new file mode 100644 index 0000000..34a9d3d --- /dev/null +++ b/raul/SharedPtr.hpp @@ -0,0 +1,63 @@ +/* A Reference Counting Smart Pointer. + * Copyright (C) 2007 Dave Robillard + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This file is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_SHARED_PTR_HPP +#define RAUL_SHARED_PTR_HPP + +#include +#include + +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS +#include +#include +#include + +static std::list shared_ptr_counters; + +// Use debug hooks to ensure 2 shared_ptrs never point to the same thing +namespace boost { + + inline void sp_scalar_constructor_hook(void* object, unsigned long cnt, void* ptr) { + assert(std::find(shared_ptr_counters.begin(), shared_ptr_counters.end(), + (void*)object) == shared_ptr_counters.end()); + shared_ptr_counters.push_back(object); + //std::cerr << "Creating SharedPtr to " + // << object << ", count = " << cnt << std::endl; + } + + inline void sp_scalar_destructor_hook(void* object, unsigned long cnt, void* ptr) { + shared_ptr_counters.remove(object); + //std::cerr << "Destroying SharedPtr to " + // << object << ", count = " << cnt << std::endl; + } + +} +#endif // BOOST_SP_ENABLE_DEBUG_HOOKS + + +#include + +#ifdef BOOST_AC_USE_PTHREADS +#error "Boost is using mutex locking for pointer reference counting." +#error "This is VERY slow. Please report your platform to dave@drobilla.net" +#endif + +#define SharedPtr boost::shared_ptr +#define PtrCast boost::dynamic_pointer_cast + +#endif // RAUL_SHARED_PTR_HPP + diff --git a/raul/Slave.h b/raul/Slave.h deleted file mode 100644 index f02b55c..0000000 --- a/raul/Slave.h +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_SLAVE_H -#define RAUL_SLAVE_H - -#include -#include "raul/Semaphore.h" -#include "raul/Thread.h" - -namespace Raul { - - -/** Thread driven by (realtime safe) signals. - * - * Use this to perform some task in a separate thread you want to 'drive' - * from a realtime (or otherwise) thread. - * - * \ingroup raul - */ -class Slave : public Thread -{ -public: - Slave() : _whip(0) {} - - /** Tell the slave to do whatever work it does. Realtime safe. */ - inline void whip() { _whip.post(); } - -protected: - /** Worker method. - * - * This is called once from this thread every time whip() is called. - * Implementations likely want to put a single (non loop) chunk of code - * here, e.g. to process an event. - */ - virtual void _whipped() = 0; - - Semaphore _whip; - -private: - inline void _run() - { - while (true) { - _whip.wait(); - _whipped(); - } - } -}; - - -} // namespace Raul - -#endif // RAUL_SLAVE_H diff --git a/raul/Slave.hpp b/raul/Slave.hpp new file mode 100644 index 0000000..91c90f3 --- /dev/null +++ b/raul/Slave.hpp @@ -0,0 +1,67 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_SLAVE_HPP +#define RAUL_SLAVE_HPP + +#include +#include +#include + +namespace Raul { + + +/** Thread driven by (realtime safe) signals. + * + * Use this to perform some task in a separate thread you want to 'drive' + * from a realtime (or otherwise) thread. + * + * \ingroup raul + */ +class Slave : public Thread +{ +public: + Slave() : _whip(0) {} + + /** Tell the slave to do whatever work it does. Realtime safe. */ + inline void whip() { _whip.post(); } + +protected: + /** Worker method. + * + * This is called once from this thread every time whip() is called. + * Implementations likely want to put a single (non loop) chunk of code + * here, e.g. to process an event. + */ + virtual void _whipped() = 0; + + Semaphore _whip; + +private: + inline void _run() + { + while (true) { + _whip.wait(); + _whipped(); + } + } +}; + + +} // namespace Raul + +#endif // RAUL_SLAVE_HPP diff --git a/raul/StampedChunkRingBuffer.h b/raul/StampedChunkRingBuffer.h deleted file mode 100644 index 838ea0f..0000000 --- a/raul/StampedChunkRingBuffer.h +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_STAMPED_CHUNK_RING_BUFFER_H -#define RAUL_STAMPED_CHUNK_RING_BUFFER_H - -#include -#include -#include -#include -#include - -namespace Raul { - - -/** A RingBuffer of timestamped binary "chunks". - * - * This packs a timestamp, size, and size bytes of data flat into the buffer. - * Useful for MIDI events, OSC messages, etc. - */ -class StampedChunkRingBuffer : private Raul::RingBuffer { -public: - - /** @param size Size in bytes. - */ - StampedChunkRingBuffer(size_t size) - : RingBuffer(size) - {} - - size_t capacity() const { return _size; } - - size_t write(TickTime time, size_t size, const Byte* buf); - bool read(TickTime* time, size_t* size, Byte* buf); -}; - - -inline bool -StampedChunkRingBuffer::read(TickTime* time, size_t* size, Byte* buf) -{ - bool success = RingBuffer::full_read(sizeof(TickTime), (Byte*)time); - if (success) - success = RingBuffer::full_read(sizeof(size_t), (Byte*)size); - if (success) - success = RingBuffer::full_read(*size, buf); - - return success; -} - - -inline size_t -StampedChunkRingBuffer::write(TickTime time, size_t size, const Byte* buf) -{ - assert(size > 0); - - if (write_space() < (sizeof(TickTime) + sizeof(size_t) + size)) { - return 0; - } else { - RingBuffer::write(sizeof(TickTime), (Byte*)&time); - RingBuffer::write(sizeof(size_t), (Byte*)&size); - RingBuffer::write(size, buf); - return size; - } -} - - -} // namespace Raul - -#endif // RAUL_STAMPED_CHUNK_RING_BUFFER_H - diff --git a/raul/StampedChunkRingBuffer.hpp b/raul/StampedChunkRingBuffer.hpp new file mode 100644 index 0000000..b4f9371 --- /dev/null +++ b/raul/StampedChunkRingBuffer.hpp @@ -0,0 +1,83 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_STAMPED_CHUNK_RING_BUFFER_HPP +#define RAUL_STAMPED_CHUNK_RING_BUFFER_HPP + +#include +#include +#include +#include +#include + +namespace Raul { + + +/** A RingBuffer of timestamped binary "chunks". + * + * This packs a timestamp, size, and size bytes of data flat into the buffer. + * Useful for MIDI events, OSC messages, etc. + */ +class StampedChunkRingBuffer : private Raul::RingBuffer { +public: + + /** @param size Size in bytes. + */ + StampedChunkRingBuffer(size_t size) + : RingBuffer(size) + {} + + size_t capacity() const { return _size; } + + size_t write(TickTime time, size_t size, const Byte* buf); + bool read(TickTime* time, size_t* size, Byte* buf); +}; + + +inline bool +StampedChunkRingBuffer::read(TickTime* time, size_t* size, Byte* buf) +{ + bool success = RingBuffer::full_read(sizeof(TickTime), (Byte*)time); + if (success) + success = RingBuffer::full_read(sizeof(size_t), (Byte*)size); + if (success) + success = RingBuffer::full_read(*size, buf); + + return success; +} + + +inline size_t +StampedChunkRingBuffer::write(TickTime time, size_t size, const Byte* buf) +{ + assert(size > 0); + + if (write_space() < (sizeof(TickTime) + sizeof(size_t) + size)) { + return 0; + } else { + RingBuffer::write(sizeof(TickTime), (Byte*)&time); + RingBuffer::write(sizeof(size_t), (Byte*)&size); + RingBuffer::write(size, buf); + return size; + } +} + + +} // namespace Raul + +#endif // RAUL_STAMPED_CHUNK_RING_BUFFER_HPP + diff --git a/raul/Stateful.h b/raul/Stateful.h deleted file mode 100644 index a366ffd..0000000 --- a/raul/Stateful.h +++ /dev/null @@ -1,42 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef STATEFUL_H -#define STATEFUL_H - -#include "raul/RDFModel.h" - -namespace Raul { - - -class Stateful { -public: - virtual ~Stateful() {} - - virtual void write_state(RDF::Model& model) = 0; - - RDF::Node id() const { return _id; } - void set_id(const RDF::Node& id) { _id = id; } - -protected: - RDF::Node _id; -}; - - -} // namespace Raul - -#endif // STATEFUL_H diff --git a/raul/Stateful.hpp b/raul/Stateful.hpp new file mode 100644 index 0000000..a5ecdb8 --- /dev/null +++ b/raul/Stateful.hpp @@ -0,0 +1,42 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef STATEFUL_H +#define STATEFUL_H + +#include + +namespace Raul { + + +class Stateful { +public: + virtual ~Stateful() {} + + virtual void write_state(RDF::Model& model) = 0; + + RDF::Node id() const { return _id; } + void set_id(const RDF::Node& id) { _id = id; } + +protected: + RDF::Node _id; +}; + + +} // namespace Raul + +#endif // STATEFUL_H diff --git a/raul/Thread.h b/raul/Thread.h deleted file mode 100644 index 8c739f1..0000000 --- a/raul/Thread.h +++ /dev/null @@ -1,107 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_THREAD_H -#define RAUL_THREAD_H - -#include -#include -#include -#include - -namespace Raul { - - -/** Abstract base class for a thread. - * - * Extend this and override the _run method to easily create a thread - * to perform some task. - * - * The current Thread can be accessed using the get() method. - * - * \ingroup raul - */ -class Thread : boost::noncopyable -{ -public: - virtual ~Thread() { - stop(); - } - - static Thread* create(const std::string& name="") - { return new Thread(name); } - - /** Must be called from thread */ - static Thread* create_for_this_thread(const std::string& name="") - { return new Thread(pthread_self(), name); } - - static Thread& get(); - - virtual void start(); - virtual void stop(); - - void set_scheduling(int policy, unsigned int priority); - - const std::string& name() { return _name; } - void set_name(const std::string& name) { _name = name; } - - const unsigned context() { return _context; } - void set_context(unsigned context) { _context = context; } - -protected: - Thread(const std::string& name=""); - Thread(pthread_t thread, const std::string& name=""); - - /** Thread function to execute. - * - * This is called once on start, and terminated on stop. - * Implementations likely want to put some infinite loop here. - */ - virtual void _run() {} - -private: - - inline static void* _static_run(void* me) { - pthread_setspecific(_thread_key, me); - Thread* myself = (Thread*)me; - myself->_run(); - myself->_pthread_exists = false; - return NULL; // and I - } - - /** Allocate thread-specific data key */ - static void thread_key_alloc() - { - pthread_key_create(&_thread_key, NULL); - } - - /* Key for the thread-specific buffer */ - static pthread_key_t _thread_key; - - /* Once-only initialisation of the key */ - static pthread_once_t _thread_key_once; - - unsigned _context; - std::string _name; - bool _pthread_exists; - pthread_t _pthread; -}; - - -} // namespace Raul - -#endif // RAUL_THREAD_H diff --git a/raul/Thread.hpp b/raul/Thread.hpp new file mode 100644 index 0000000..e444c6e --- /dev/null +++ b/raul/Thread.hpp @@ -0,0 +1,107 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_THREAD_HPP +#define RAUL_THREAD_HPP + +#include +#include +#include +#include + +namespace Raul { + + +/** Abstract base class for a thread. + * + * Extend this and override the _run method to easily create a thread + * to perform some task. + * + * The current Thread can be accessed using the get() method. + * + * \ingroup raul + */ +class Thread : boost::noncopyable +{ +public: + virtual ~Thread() { + stop(); + } + + static Thread* create(const std::string& name="") + { return new Thread(name); } + + /** Must be called from thread */ + static Thread* create_for_this_thread(const std::string& name="") + { return new Thread(pthread_self(), name); } + + static Thread& get(); + + virtual void start(); + virtual void stop(); + + void set_scheduling(int policy, unsigned int priority); + + const std::string& name() { return _name; } + void set_name(const std::string& name) { _name = name; } + + const unsigned context() { return _context; } + void set_context(unsigned context) { _context = context; } + +protected: + Thread(const std::string& name=""); + Thread(pthread_t thread, const std::string& name=""); + + /** Thread function to execute. + * + * This is called once on start, and terminated on stop. + * Implementations likely want to put some infinite loop here. + */ + virtual void _run() {} + +private: + + inline static void* _static_run(void* me) { + pthread_setspecific(_thread_key, me); + Thread* myself = (Thread*)me; + myself->_run(); + myself->_pthread_exists = false; + return NULL; // and I + } + + /** Allocate thread-specific data key */ + static void thread_key_alloc() + { + pthread_key_create(&_thread_key, NULL); + } + + /* Key for the thread-specific buffer */ + static pthread_key_t _thread_key; + + /* Once-only initialisation of the key */ + static pthread_once_t _thread_key_once; + + unsigned _context; + std::string _name; + bool _pthread_exists; + pthread_t _pthread; +}; + + +} // namespace Raul + +#endif // RAUL_THREAD_HPP diff --git a/raul/TimeSlice.h b/raul/TimeSlice.h deleted file mode 100644 index 2d9c5ac..0000000 --- a/raul/TimeSlice.h +++ /dev/null @@ -1,159 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_TIMESLICE_H -#define RAUL_TIMESLICE_H - -#include -#include -#include -#include - -namespace Raul { - - -/** A duration of time, with conversion between tick time and beat time. - * - * This is a slice along a single timeline (ie t=0 in ticks and t=0 in beats - * are equal). Relation to an external time base (e.g. Jack frame time) is - * represented by frame_offset (the idea is that this holds all the information - * necessary for passing to run() methods so they know the current state of - * things WRT time). - * - * This class handles conversion between two units of time: musical - * (beat) time, and real (tick) time. Real time is discrete, the smallest - * unit of time is the 'tick' (usually audio frames or MIDI ticks). Beat time - * is stored as a double (to be independent of any rates or timer precision). - * - * This caches as many values as possible to make calls less expensive, pass it - * around by reference, not value. - * - * \ingroup raul - */ -class TimeSlice : public boost::noncopyable { -public: - TimeSlice(double tick_rate, double bpm) - : _tick_rate(tick_rate) - , _beat_rate(60.0/bpm) - , _start_ticks(0) - , _length_ticks(0) - , _start_beats(0) - , _length_beats(0) - , _offset_ticks(0) - {} - - - /** Set the start and length of the slice. - * - * Note that external offset is not affected by this, don't forget to reset - * the offset each cycle! - */ - void set_window(TickTime start, TickCount length) { - _start_ticks = start; - _length_ticks = length; - update_beat_time(); - } - - void set_start(TickTime time) { _start_ticks = time; update_beat_time(); } - - void set_length(TickCount length) { _length_ticks = length; update_beat_time(); } - - bool contains(TickTime time) { - return (time >= start_ticks() && time < start_ticks() + length_ticks()); - } - - double tick_rate() { return _tick_rate; } - double beat_rate() { return _beat_rate; } - double bpm() { return 60/_beat_rate; } - - void set_tick_rate(double tick_rate) { - _tick_rate = tick_rate; - update_beat_time(); - } - - void set_bpm(double bpm) { - _beat_rate = 60.0/bpm; - update_beat_time(); - } - - inline Seconds beats_to_seconds(BeatTime beats) const { - return (beats * _beat_rate); - } - - inline TickTime beats_to_ticks(BeatTime beats) const { - return static_cast(floor(beats_to_seconds(beats) / _tick_rate)); - } - - inline Seconds ticks_to_seconds(TickTime ticks) const { - return (ticks * _tick_rate); - } - - inline BeatTime ticks_to_beats(TickTime ticks) const { - return ticks_to_seconds(ticks) / _beat_rate; - } - - /** Start of current sub-cycle in ticks */ - inline TickTime start_ticks() const { return _start_ticks; } - - /** Length of current sub-cycle in ticks */ - inline TickCount length_ticks() const { return _length_ticks; } - - /** Start of current sub-cycle in beats */ - inline BeatTime start_beats() const { return _start_beats; } - - /** Length of current sub-cycle in beats */ - inline BeatCount length_beats() const { return _length_beats; } - - - // Real-time conversion -/* - TickCount ticks_to_offset(TickTime time) { - assert(time >= _start_ticks); - TickCount ret = time - _start_ticks + _offset_ticks; - assert(ret < _offset_ticks + _length_ticks); - return ret; - } -*/ - /** Set the offset between real-time and timeslice-time. */ - inline void set_offset(TickCount offset) { _offset_ticks = offset; } - /** Offset relative to external (e.g Jack) time */ - inline TickCount offset_ticks() const { return _offset_ticks; } - -private: - - inline void update_beat_time() { - _start_beats = ticks_to_beats(_start_ticks); - _length_beats = ticks_to_beats(_length_ticks); - } - - // Rate/Tempo - double _tick_rate; ///< Tick rate in Hz (e.g. sample rate) - double _beat_rate; ///< Beat rate in Hz - - // Current time - TickTime _start_ticks; ///< Current window start in ticks - TickCount _length_ticks; ///< Current window length in ticks - BeatTime _start_beats; ///< Current window start in beats - BeatCount _length_beats; ///< Current window length in beats - - TickCount _offset_ticks; ///< Offset to global time (ie Jack sub-cycle offset) -}; - - -} // namespace Raul - -#endif // RAUL_TIMESLICE_H diff --git a/raul/TimeSlice.hpp b/raul/TimeSlice.hpp new file mode 100644 index 0000000..0681fb5 --- /dev/null +++ b/raul/TimeSlice.hpp @@ -0,0 +1,159 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_TIME_SLICE_HPP +#define RAUL_TIME_SLICE_HPP + +#include +#include +#include +#include + +namespace Raul { + + +/** A duration of time, with conversion between tick time and beat time. + * + * This is a slice along a single timeline (ie t=0 in ticks and t=0 in beats + * are equal). Relation to an external time base (e.g. Jack frame time) is + * represented by frame_offset (the idea is that this holds all the information + * necessary for passing to run() methods so they know the current state of + * things WRT time). + * + * This class handles conversion between two units of time: musical + * (beat) time, and real (tick) time. Real time is discrete, the smallest + * unit of time is the 'tick' (usually audio frames or MIDI ticks). Beat time + * is stored as a double (to be independent of any rates or timer precision). + * + * This caches as many values as possible to make calls less expensive, pass it + * around by reference, not value. + * + * \ingroup raul + */ +class TimeSlice : public boost::noncopyable { +public: + TimeSlice(double tick_rate, double bpm) + : _tick_rate(tick_rate) + , _beat_rate(60.0/bpm) + , _start_ticks(0) + , _length_ticks(0) + , _start_beats(0) + , _length_beats(0) + , _offset_ticks(0) + {} + + + /** Set the start and length of the slice. + * + * Note that external offset is not affected by this, don't forget to reset + * the offset each cycle! + */ + void set_window(TickTime start, TickCount length) { + _start_ticks = start; + _length_ticks = length; + update_beat_time(); + } + + void set_start(TickTime time) { _start_ticks = time; update_beat_time(); } + + void set_length(TickCount length) { _length_ticks = length; update_beat_time(); } + + bool contains(TickTime time) { + return (time >= start_ticks() && time < start_ticks() + length_ticks()); + } + + double tick_rate() { return _tick_rate; } + double beat_rate() { return _beat_rate; } + double bpm() { return 60/_beat_rate; } + + void set_tick_rate(double tick_rate) { + _tick_rate = tick_rate; + update_beat_time(); + } + + void set_bpm(double bpm) { + _beat_rate = 60.0/bpm; + update_beat_time(); + } + + inline Seconds beats_to_seconds(BeatTime beats) const { + return (beats * _beat_rate); + } + + inline TickTime beats_to_ticks(BeatTime beats) const { + return static_cast(floor(beats_to_seconds(beats) / _tick_rate)); + } + + inline Seconds ticks_to_seconds(TickTime ticks) const { + return (ticks * _tick_rate); + } + + inline BeatTime ticks_to_beats(TickTime ticks) const { + return ticks_to_seconds(ticks) / _beat_rate; + } + + /** Start of current sub-cycle in ticks */ + inline TickTime start_ticks() const { return _start_ticks; } + + /** Length of current sub-cycle in ticks */ + inline TickCount length_ticks() const { return _length_ticks; } + + /** Start of current sub-cycle in beats */ + inline BeatTime start_beats() const { return _start_beats; } + + /** Length of current sub-cycle in beats */ + inline BeatCount length_beats() const { return _length_beats; } + + + // Real-time conversion +/* + TickCount ticks_to_offset(TickTime time) { + assert(time >= _start_ticks); + TickCount ret = time - _start_ticks + _offset_ticks; + assert(ret < _offset_ticks + _length_ticks); + return ret; + } +*/ + /** Set the offset between real-time and timeslice-time. */ + inline void set_offset(TickCount offset) { _offset_ticks = offset; } + /** Offset relative to external (e.g Jack) time */ + inline TickCount offset_ticks() const { return _offset_ticks; } + +private: + + inline void update_beat_time() { + _start_beats = ticks_to_beats(_start_ticks); + _length_beats = ticks_to_beats(_length_ticks); + } + + // Rate/Tempo + double _tick_rate; ///< Tick rate in Hz (e.g. sample rate) + double _beat_rate; ///< Beat rate in Hz + + // Current time + TickTime _start_ticks; ///< Current window start in ticks + TickCount _length_ticks; ///< Current window length in ticks + BeatTime _start_beats; ///< Current window start in beats + BeatCount _length_beats; ///< Current window length in beats + + TickCount _offset_ticks; ///< Offset to global time (ie Jack sub-cycle offset) +}; + + +} // namespace Raul + +#endif // RAUL_TIME_SLICE_HPP diff --git a/raul/WeakPtr.h b/raul/WeakPtr.h deleted file mode 100644 index ef4b70e..0000000 --- a/raul/WeakPtr.h +++ /dev/null @@ -1,26 +0,0 @@ -/* A "weak" pointer to a resource owned by a shared pointer. - * Copyright (C) 2007 Dave Robillard - * - * This is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This file is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_WEAK_PTR_H -#define RAUL_WEAK_PTR_H - -#include - -#define WeakPtr boost::weak_ptr - -#endif // RAUL_WEAK_PTR_H - diff --git a/raul/WeakPtr.hpp b/raul/WeakPtr.hpp new file mode 100644 index 0000000..650b437 --- /dev/null +++ b/raul/WeakPtr.hpp @@ -0,0 +1,26 @@ +/* A "weak" pointer to a resource owned by a shared pointer. + * Copyright (C) 2007 Dave Robillard + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This file is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_WEAK_PTR_HPP +#define RAUL_WEAK_PTR_HPP + +#include + +#define WeakPtr boost::weak_ptr + +#endif // RAUL_WEAK_PTR_HPP + diff --git a/raul/midi_events.h b/raul/midi_events.h index 863fe0f..1c786aa 100644 --- a/raul/midi_events.h +++ b/raul/midi_events.h @@ -18,8 +18,8 @@ * */ -#ifndef RAUL_MIDIEVENTS_H -#define RAUL_MIDIEVENTS_H +#ifndef RAUL_MIDI_EVENTS_H +#define RAUL_MIDI_EVENTS_H /** @@ -130,4 +130,4 @@ /** \} */ -#endif /* RAUL_MIDIEVENTS_H */ +#endif /* RAUL_MIDI_EVENTS_H */ diff --git a/raul/midi_names.h b/raul/midi_names.h index 45b61ef..1b98f9a 100644 --- a/raul/midi_names.h +++ b/raul/midi_names.h @@ -17,12 +17,16 @@ * */ -#ifndef RAUL_MIDINAMES_H -#define RAUL_MIDINAMES_H +#ifndef RAUL_MIDI_NAMES_H +#define RAUL_MIDI_NAMES_H #include "midi_events.h" +#ifdef __cplusplus namespace Raul { +extern "C" { +#endif + /** \group midi */ @@ -226,6 +230,10 @@ inline static const char* midi_name(uint8_t status) } +#ifdef __cplusplus +} // extern "C" } // namespace Raul +#endif + -#endif /* RAUL_MIDINAMES_H */ +#endif /* RAUL_MIDI_NAMES_H */ diff --git a/raul/types.h b/raul/types.h deleted file mode 100644 index 00d6479..0000000 --- a/raul/types.h +++ /dev/null @@ -1,35 +0,0 @@ -/* This file is part of Raul. - * Copyright (C) 2007 Dave Robillard - * - * Raul is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Raul is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RAUL_TYPES_H -#define RAUL_TYPES_H - -#include - -namespace Raul { - -typedef uint32_t TickTime; ///< absolute time in ticks -typedef uint32_t TickCount; ///< offset in ticks -typedef double BeatTime; -typedef double BeatCount; -typedef double Seconds; - -typedef unsigned char Byte; - -} - -#endif // RAUL_TYPES_H diff --git a/raul/types.hpp b/raul/types.hpp new file mode 100644 index 0000000..fe98e38 --- /dev/null +++ b/raul/types.hpp @@ -0,0 +1,35 @@ +/* This file is part of Raul. + * Copyright (C) 2007 Dave Robillard + * + * Raul is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Raul is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RAUL_TYPES_HPP +#define RAUL_TYPES_HPP + +#include + +namespace Raul { + +typedef uint32_t TickTime; ///< absolute time in ticks +typedef uint32_t TickCount; ///< offset in ticks +typedef double BeatTime; +typedef double BeatCount; +typedef double Seconds; + +typedef unsigned char Byte; + +} + +#endif // RAUL_TYPES_HPP diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp index 486f076..6c60085 100644 --- a/src/JackDriver.cpp +++ b/src/JackDriver.cpp @@ -22,7 +22,7 @@ #include #include #include -#include "raul/JackDriver.h" +#include "raul/JackDriver.hpp" using std::cerr; using std::endl; using std::string; diff --git a/src/LashClient.cpp b/src/LashClient.cpp index aa035a5..387ba45 100644 --- a/src/LashClient.cpp +++ b/src/LashClient.cpp @@ -15,7 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include using namespace std; diff --git a/src/LashProject.cpp b/src/LashProject.cpp index 77f6d7d..6cc7288 100644 --- a/src/LashProject.cpp +++ b/src/LashProject.cpp @@ -15,7 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include using namespace std; diff --git a/src/LashServerInterface.cpp b/src/LashServerInterface.cpp index 07a50c3..484a693 100644 --- a/src/LashServerInterface.cpp +++ b/src/LashServerInterface.cpp @@ -16,7 +16,7 @@ */ #include -#include +#include using namespace std; diff --git a/src/Maid.cpp b/src/Maid.cpp index ec1e837..dda8f27 100644 --- a/src/Maid.cpp +++ b/src/Maid.cpp @@ -15,8 +15,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "raul/Maid.h" -#include "raul/Deletable.h" +#include "raul/Maid.hpp" +#include "raul/Deletable.hpp" namespace Raul { diff --git a/src/Namespaces.cpp b/src/Namespaces.cpp index 5bdb3b9..8e0a055 100644 --- a/src/Namespaces.cpp +++ b/src/Namespaces.cpp @@ -15,7 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "raul/Namespaces.h" +#include "raul/Namespaces.hpp" namespace Raul { diff --git a/src/Path.cpp b/src/Path.cpp index 39a2b71..8853e34 100644 --- a/src/Path.cpp +++ b/src/Path.cpp @@ -15,7 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "raul/Path.h" +#include "raul/Path.hpp" namespace Raul { diff --git a/src/RDFModel.cpp b/src/RDFModel.cpp index df5936d..e68bd01 100644 --- a/src/RDFModel.cpp +++ b/src/RDFModel.cpp @@ -16,10 +16,10 @@ */ #include -#include "raul/RDFWorld.h" -#include "raul/RDFModel.h" -#include "raul/RDFNode.h" -#include "raul/AtomRedland.h" +#include "raul/RDFWorld.hpp" +#include "raul/RDFModel.hpp" +#include "raul/RDFNode.hpp" +#include "raul/AtomRedland.hpp" #define U(x) ((const unsigned char*)(x)) diff --git a/src/RDFNode.cpp b/src/RDFNode.cpp index 2278a7a..afba06c 100644 --- a/src/RDFNode.cpp +++ b/src/RDFNode.cpp @@ -16,8 +16,8 @@ */ #include -#include -#include +#include +#include using namespace std; diff --git a/src/RDFQuery.cpp b/src/RDFQuery.cpp index 2cc2209..0e99a22 100644 --- a/src/RDFQuery.cpp +++ b/src/RDFQuery.cpp @@ -18,8 +18,8 @@ #include #include #include -#include "raul/RDFQuery.h" -#include "raul/RDFModel.h" +#include "raul/RDFQuery.hpp" +#include "raul/RDFModel.hpp" using namespace std; diff --git a/src/RDFWorld.cpp b/src/RDFWorld.cpp index caf6fb8..e5bc42a 100644 --- a/src/RDFWorld.cpp +++ b/src/RDFWorld.cpp @@ -16,9 +16,9 @@ */ #include -#include "raul/RDFWorld.h" -#include "raul/RDFNode.h" -#include "raul/AtomRedland.h" +#include "raul/RDFWorld.hpp" +#include "raul/RDFNode.hpp" +#include "raul/AtomRedland.hpp" #define U(x) ((const unsigned char*)(x)) diff --git a/src/SMFReader.cpp b/src/SMFReader.cpp index a267e48..49e3888 100644 --- a/src/SMFReader.cpp +++ b/src/SMFReader.cpp @@ -19,8 +19,8 @@ #include #include #include -#include "raul/SMFReader.h" -#include "raul/midi_events.h" +#include +#include using namespace std; diff --git a/src/SMFWriter.cpp b/src/SMFWriter.cpp index 0af7688..0ba9379 100644 --- a/src/SMFWriter.cpp +++ b/src/SMFWriter.cpp @@ -18,7 +18,7 @@ #include #include #include -#include "raul/SMFWriter.h" +#include "raul/SMFWriter.hpp" using namespace std; diff --git a/src/Thread.cpp b/src/Thread.cpp index 1542363..cea32d8 100644 --- a/src/Thread.cpp +++ b/src/Thread.cpp @@ -15,7 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "raul/Thread.h" +#include "raul/Thread.hpp" namespace Raul { diff --git a/src/TimeSlice.cpp b/src/TimeSlice.cpp index d6b7fc6..e983a33 100644 --- a/src/TimeSlice.cpp +++ b/src/TimeSlice.cpp @@ -15,7 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include namespace Raul { -- cgit v1.2.1