summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-02-25 20:40:13 +0000
committerDavid Robillard <d@drobilla.net>2010-02-25 20:40:13 +0000
commit77a9beca75debd2d87d735fc4fe847694eee6f13 (patch)
treeae03699b999e84bc4c283abfd215c8037ecddaf6 /src
parente22984efe9b82ab006494aea93814a592cd44ece (diff)
downloadingen-77a9beca75debd2d87d735fc4fe847694eee6f13.tar.gz
ingen-77a9beca75debd2d87d735fc4fe847694eee6f13.tar.bz2
ingen-77a9beca75debd2d87d735fc4fe847694eee6f13.zip
Work on contexts and polymorphic ports.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2492 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/client/PluginUI.cpp2
-rw-r--r--src/client/PortModel.cpp9
-rw-r--r--src/client/PortModel.hpp20
-rw-r--r--src/common/interface/Port.hpp10
-rw-r--r--src/common/interface/PortType.hpp1
-rw-r--r--src/engine/ConnectionImpl.cpp28
-rw-r--r--src/engine/ConnectionImpl.hpp4
-rw-r--r--src/engine/InputPort.cpp8
-rw-r--r--src/engine/JackDriver.cpp13
-rw-r--r--src/engine/LADSPANode.cpp8
-rw-r--r--src/engine/LV2Node.cpp22
-rw-r--r--src/engine/ObjectSender.cpp7
-rw-r--r--src/engine/OutputPort.cpp2
-rw-r--r--src/engine/PortImpl.cpp28
-rw-r--r--src/engine/PortImpl.hpp30
-rw-r--r--src/engine/events/Connect.cpp72
-rw-r--r--src/engine/events/Connect.hpp2
-rw-r--r--src/engine/events/Disconnect.cpp10
-rw-r--r--src/engine/events/RequestMetadata.cpp15
-rw-r--r--src/engine/events/SetMetadata.cpp2
-rw-r--r--src/engine/events/SetPortValue.cpp2
-rw-r--r--src/gui/App.cpp13
-rw-r--r--src/gui/App.hpp10
-rw-r--r--src/gui/Configuration.cpp20
-rw-r--r--src/gui/ControlPanel.cpp29
-rw-r--r--src/gui/NodeControlWindow.cpp2
-rw-r--r--src/gui/NodeMenu.cpp4
-rw-r--r--src/gui/NodeModule.cpp6
-rw-r--r--src/gui/PatchCanvas.cpp7
-rw-r--r--src/gui/PatchWindow.cpp23
-rw-r--r--src/gui/Port.cpp29
-rw-r--r--src/gui/PortMenu.cpp4
-rw-r--r--src/serialisation/Serialiser.cpp14
-rw-r--r--src/shared/LV2Object.hpp4
-rw-r--r--src/shared/LV2URIMap.cpp1
-rw-r--r--src/shared/LV2URIMap.hpp1
36 files changed, 260 insertions, 202 deletions
diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp
index 89adb8da..f943e54f 100644
--- a/src/client/PluginUI.cpp
+++ b/src/client/PluginUI.cpp
@@ -87,7 +87,7 @@ lv2_ui_write(LV2UI_Controller controller,
} else if (format == map->object_transfer.id) {
LV2_Object* buf = (LV2_Object*)buffer;
Raul::Atom val;
- Shared::LV2Object::to_atom(ui->world(), buf, val);
+ Shared::LV2Object::to_atom(buf, val);
ui->world()->engine->set_property(port->path(), map->ingen_value, val);
} else {
diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp
index 80b97e61..e23a0e1a 100644
--- a/src/client/PortModel.cpp
+++ b/src/client/PortModel.cpp
@@ -35,6 +35,13 @@ PortModel::set_property(const Raul::URI& uri,
bool
+PortModel::supports(const Raul::URI& value_type) const
+{
+ return has_property(Shared::LV2URIMap::instance().obj_supports, value_type);
+}
+
+
+bool
PortModel::port_property(const std::string& uri) const
{
return has_property(Shared::LV2URIMap::instance().lv2_portProperty, Raul::URI(uri));
@@ -47,7 +54,7 @@ PortModel::set(SharedPtr<ObjectModel> model)
SharedPtr<PortModel> port = PtrCast<PortModel>(model);
if (port) {
_index = port->_index;
- _type = port->_type;
+ _types = port->_types;
_direction = port->_direction;
_current_val = port->_current_val;
_connections = port->_connections;
diff --git a/src/client/PortModel.hpp b/src/client/PortModel.hpp
index 6021ed19..02305e1a 100644
--- a/src/client/PortModel.hpp
+++ b/src/client/PortModel.hpp
@@ -41,8 +41,11 @@ class PortModel : public ObjectModel, public Ingen::Shared::Port
public:
enum Direction { INPUT, OUTPUT };
+ const PortTypes& types() const { return _types; }
+
+ bool supports(const Raul::URI& value_type) const;
+
inline uint32_t index() const { return _index; }
- inline Shared::PortType type() const { return _type; }
inline const Raul::Atom& value() const { return _current_val; }
inline bool connected() const { return (_connections > 0); }
inline bool is_input() const { return (_direction == INPUT); }
@@ -50,6 +53,7 @@ public:
bool port_property(const std::string& uri) const;
+ bool is_numeric() const { return is_a(Shared::PortType::CONTROL); }
bool is_logarithmic() const { return port_property("http://drobilla.net/ns/ingen#logarithmic"); }
bool is_integer() const { return port_property("http://lv2plug.in/ns/lv2core#integer"); }
bool is_toggle() const { return port_property("http://lv2plug.in/ns/lv2core#toggled"); }
@@ -83,12 +87,12 @@ private:
PortModel(const Raul::Path& path, uint32_t index, Shared::PortType type, Direction dir)
: ObjectModel(path)
, _index(index)
- , _type(type)
, _direction(dir)
, _current_val(0.0f)
, _connections(0)
{
- if (_type == Shared::PortType::UNKNOWN)
+ _types.insert(type);
+ if (type == Shared::PortType::UNKNOWN)
Raul::warn << "[PortModel] Unknown port type" << std::endl;
}
@@ -100,11 +104,11 @@ private:
void set(SharedPtr<ObjectModel> model);
- uint32_t _index;
- Shared::PortType _type;
- Direction _direction;
- Raul::Atom _current_val;
- size_t _connections;
+ uint32_t _index;
+ std::set<Shared::PortType> _types;
+ Direction _direction;
+ Raul::Atom _current_val;
+ size_t _connections;
};
diff --git a/src/common/interface/Port.hpp b/src/common/interface/Port.hpp
index c7029095..06272b6f 100644
--- a/src/common/interface/Port.hpp
+++ b/src/common/interface/Port.hpp
@@ -18,6 +18,7 @@
#ifndef INGEN_INTERFACE_PORT_HPP
#define INGEN_INTERFACE_PORT_HPP
+#include <set>
#include <stdint.h>
#include "GraphObject.hpp"
#include "PortType.hpp"
@@ -37,9 +38,16 @@ namespace Shared {
class Port : public virtual GraphObject
{
public:
+ typedef std::set<Shared::PortType> PortTypes;
+
+ virtual const PortTypes& types() const = 0;
+
+ inline bool is_a(PortType type) const { return types().find(type) != types().end(); }
+
+ virtual bool supports(const Raul::URI& value_type) const = 0;
+
virtual uint32_t index() const = 0;
virtual bool is_input() const = 0;
- virtual Shared::PortType type() const = 0;
virtual const Raul::Atom& value() const = 0;
};
diff --git a/src/common/interface/PortType.hpp b/src/common/interface/PortType.hpp
index e1d51e21..19558adc 100644
--- a/src/common/interface/PortType.hpp
+++ b/src/common/interface/PortType.hpp
@@ -68,6 +68,7 @@ public:
inline bool operator!=(const Symbol& symbol) const { return (_symbol != symbol); }
inline bool operator==(const PortType& type) const { return (_symbol == type._symbol); }
inline bool operator!=(const PortType& type) const { return (_symbol != type._symbol); }
+ inline bool operator<(const PortType& type) const { return (_symbol < type._symbol); }
inline bool is_audio() { return _symbol == AUDIO; }
inline bool is_control() { return _symbol == CONTROL; }
diff --git a/src/engine/ConnectionImpl.cpp b/src/engine/ConnectionImpl.cpp
index 02955757..d3ec6cc7 100644
--- a/src/engine/ConnectionImpl.cpp
+++ b/src/engine/ConnectionImpl.cpp
@@ -19,13 +19,16 @@
#include "raul/log.hpp"
#include "raul/Maid.hpp"
#include "raul/IntrusivePtr.hpp"
+#include "shared/LV2URIMap.hpp"
#include "AudioBuffer.hpp"
#include "BufferFactory.hpp"
#include "ConnectionImpl.hpp"
#include "Engine.hpp"
#include "EventBuffer.hpp"
#include "InputPort.hpp"
+#include "InputPort.hpp"
#include "MessageContext.hpp"
+#include "OutputPort.hpp"
#include "PortImpl.hpp"
#include "ProcessContext.hpp"
#include "mix.hpp"
@@ -53,7 +56,7 @@ ConnectionImpl::ConnectionImpl(BufferFactory& bufs, PortImpl* src_port, PortImpl
assert(src_port->path() != dst_port->path());
if (must_mix() || must_queue())
- _local_buffer = bufs.get(dst_port->type(), dst_port->buffer_size(), true);
+ _local_buffer = bufs.get(dst_port->buffer_type(), dst_port->buffer_size(), true);
if (must_queue())
_queue = new Raul::RingBuffer<LV2_Object>(src_port->buffer_size() * 2);
@@ -82,7 +85,7 @@ void
ConnectionImpl::allocate_buffer(BufferFactory& bufs)
{
if (!_local_buffer)
- _local_buffer = bufs.get(_dst_port->type(), _dst_port->buffer_size());
+ _local_buffer = bufs.get(_dst_port->buffer_type(), _dst_port->buffer_size());
}
@@ -97,7 +100,7 @@ ConnectionImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
const bool mix = _src_port->prepared_poly() > _dst_port->prepared_poly();
if ((mix || must_queue()) && !_local_buffer)
- _local_buffer = bufs.get(_dst_port->type(), _dst_port->buffer(0)->size());
+ _local_buffer = bufs.get(_dst_port->buffer_type(), _dst_port->buffer(0)->size());
}
@@ -181,5 +184,24 @@ ConnectionImpl::queue(Context& context)
}
+bool
+ConnectionImpl::can_connect(const OutputPort* src, const InputPort* dst)
+{
+ const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ return (
+ ( (src->is_a(PortType::CONTROL) || src->is_a(PortType::AUDIO))
+ && (dst->is_a(PortType::CONTROL) || dst->is_a(PortType::AUDIO)))
+ || ( src->is_a(PortType::EVENTS) && src->context() == Context::AUDIO
+ && dst->is_a(PortType::MESSAGE) && dst->context() == Context::MESSAGE)
+ || ( src->is_a(PortType::MESSAGE) && src->context() == Context::MESSAGE
+ && dst->is_a(PortType::EVENTS) && dst->context() == Context::AUDIO)
+ || (src->is_a(PortType::EVENTS) && dst->is_a(PortType::EVENTS))
+ || (src->is_a(PortType::CONTROL) && dst->supports(uris.object_class_float32))
+ || (src->is_a(PortType::AUDIO) && dst->supports(uris.object_class_vector))
+ || (src->supports(uris.object_class_float32) && dst->is_a(PortType::CONTROL))
+ || (src->supports(uris.object_class_vector) && dst->is_a(PortType::AUDIO)));
+}
+
+
} // namespace Ingen
diff --git a/src/engine/ConnectionImpl.hpp b/src/engine/ConnectionImpl.hpp
index 896b055b..232d8033 100644
--- a/src/engine/ConnectionImpl.hpp
+++ b/src/engine/ConnectionImpl.hpp
@@ -32,6 +32,8 @@ using namespace std;
namespace Ingen {
class PortImpl;
+class OutputPort;
+class InputPort;
class Buffer;
class BufferFactory;
@@ -92,6 +94,8 @@ public:
/** Returns true if this connection crosses contexts and must buffer */
inline bool must_queue() const { return _src_port->context() != _dst_port->context(); }
+ static bool can_connect(const OutputPort* src, const InputPort* dst);
+
protected:
void dump() const;
diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp
index f9ddbfe2..d5051865 100644
--- a/src/engine/InputPort.cpp
+++ b/src/engine/InputPort.cpp
@@ -93,7 +93,7 @@ InputPort::get_buffers(BufferFactory& bufs, Raul::Array<BufferFactory::Ref>* buf
size_t num_connections = (ThreadManager::current_thread_id() == THREAD_PROCESS)
? _connections.size() : _num_connections;
- if (_type == PortType::AUDIO && num_connections == 0) {
+ if (buffer_type() == PortType::AUDIO && num_connections == 0) {
// Audio input with no connections, use shared zero buffer
for (uint32_t v = 0; v < poly; ++v)
buffers->at(v) = bufs.silent_buffer();
@@ -113,7 +113,7 @@ InputPort::get_buffers(BufferFactory& bufs, Raul::Array<BufferFactory::Ref>* buf
// Use local buffers
for (uint32_t v = 0; v < poly; ++v) {
buffers->at(v) = NULL; // Release first (potential immediate recycling)
- buffers->at(v) = _bufs.get(_type, _buffer_size);
+ buffers->at(v) = _bufs.get(buffer_type(), _buffer_size);
buffers->at(v)->clear();
}
}
@@ -136,7 +136,7 @@ InputPort::add_connection(Connections::Node* const c)
_connections.push_back(c);
// Automatically broadcast connected control inputs
- if (_type == PortType::CONTROL)
+ if (is_a(PortType::CONTROL))
_broadcast = true;
}
@@ -170,7 +170,7 @@ InputPort::remove_connection(ProcessContext& context, const OutputPort* src_port
}
// Turn off broadcasting if we're no longer connected
- if (_type == PortType::CONTROL && _connections.size() == 0)
+ if (is_a(PortType::CONTROL) && _connections.size() == 0)
_broadcast = false;
return connection;
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index a604aeae..6c66cba3 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -77,7 +77,7 @@ JackPort::create()
_jack_port = jack_port_register(
_driver->jack_client(),
ingen_jack_port_name(_patch_port->path()).c_str(),
- (_patch_port->type() == PortType::AUDIO)
+ (_patch_port->buffer_type() == PortType::AUDIO)
? JACK_DEFAULT_AUDIO_TYPE : JACK_DEFAULT_MIDI_TYPE,
(_patch_port->is_input())
? JackPortIsInput : JackPortIsOutput,
@@ -115,13 +115,13 @@ JackPort::pre_process(ProcessContext& context)
const SampleCount nframes = context.nframes();
- if (_patch_port->type() == PortType::AUDIO) {
+ if (_patch_port->buffer_type() == PortType::AUDIO) {
jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(_jack_port, nframes);
AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
patch_buf->copy(jack_buf, 0, nframes - 1);
- } else if (_patch_port->type() == PortType::EVENTS) {
+ } else if (_patch_port->buffer_type() == PortType::EVENTS) {
void* jack_buf = jack_port_get_buffer(_jack_port, nframes);
EventBuffer* patch_buf = (EventBuffer*)_patch_port->buffer(0).get();
@@ -149,13 +149,13 @@ JackPort::post_process(ProcessContext& context)
const SampleCount nframes = context.nframes();
- if (_patch_port->type() == PortType::AUDIO) {
+ if (_patch_port->buffer_type() == PortType::AUDIO) {
jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(_jack_port, nframes);
AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
memcpy(jack_buf, patch_buf->data(), nframes * sizeof(Sample));
- } else if (_patch_port->type() == PortType::EVENTS) {
+ } else if (_patch_port->buffer_type() == PortType::EVENTS) {
void* jack_buf = jack_port_get_buffer(_jack_port, context.nframes());
EventBuffer* patch_buf = (EventBuffer*)_patch_port->buffer(0).get();
@@ -367,7 +367,8 @@ DriverPort*
JackDriver::create_port(DuplexPort* patch_port)
{
try {
- if (patch_port->type() == PortType::AUDIO || patch_port->type() == PortType::EVENTS)
+ if (patch_port->buffer_type() == PortType::AUDIO
+ || patch_port->buffer_type() == PortType::EVENTS)
return new JackPort(this, patch_port);
else
return NULL;
diff --git a/src/engine/LADSPANode.cpp b/src/engine/LADSPANode.cpp
index ec793915..ddcb774f 100644
--- a/src/engine/LADSPANode.cpp
+++ b/src/engine/LADSPANode.cpp
@@ -89,10 +89,10 @@ LADSPANode::prepare_poly(BufferFactory& bufs, uint32_t poly)
PortImpl* const port = _ports->at(j);
Buffer* const buffer = port->prepared_buffer(i).get();
if (buffer) {
- if (port->type() == PortType::CONTROL) {
+ if (port->is_a(PortType::CONTROL)) {
((AudioBuffer*)buffer)->set_value(port->value().get_float(), 0, 0);
- } else if (port->type() == PortType::AUDIO) {
- ((AudioBuffer*)buffer)->set_value(0.0f, 0, 0);
+ } else {
+ buffer->clear();
}
}
}
@@ -281,7 +281,7 @@ LADSPANode::set_port_buffer(uint32_t voice, uint32_t port_num,
NodeImpl::set_port_buffer(voice, port_num, buf, offset);
_descriptor->connect_port(instance(voice), port_num,
- buf ? (LADSPA_Data*)buf->port_data(_ports->at(port_num)->type(), offset) : NULL);
+ buf ? (LADSPA_Data*)buf->port_data(_ports->at(port_num)->buffer_type(), offset) : NULL);
}
diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp
index 60bb2bbb..b682ca4e 100644
--- a/src/engine/LV2Node.cpp
+++ b/src/engine/LV2Node.cpp
@@ -94,10 +94,10 @@ LV2Node::prepare_poly(BufferFactory& bufs, uint32_t poly)
PortImpl* const port = _ports->at(j);
Buffer* const buffer = port->prepared_buffer(i).get();
if (buffer) {
- if (port->type() == PortType::CONTROL) {
+ if (port->is_a(PortType::CONTROL)) {
((AudioBuffer*)buffer)->set_value(port->value().get_float(), 0, 0);
- } else if (port->type() == PortType::AUDIO) {
- ((AudioBuffer*)buffer)->set_value(0.0f, 0, 0);
+ } else {
+ buffer->clear();
}
}
}
@@ -201,6 +201,9 @@ LV2Node::instantiate(BufferFactory& bufs)
SLV2Value port_property_pred = slv2_value_new_uri(info->lv2_world(),
"http://lv2plug.in/ns/lv2core#portProperty");
+ SLV2Value supports_pred = slv2_value_new_uri(info->lv2_world(),
+ LV2_OBJECT_URI "#supports");
+
//SLV2Value as_large_as_pred = slv2_value_new_uri(info->lv2_world(),
// "http://lv2plug.in/ns/dev/resize-port#asLargeAs");
@@ -302,6 +305,17 @@ LV2Node::instantiate(BufferFactory& bufs)
}
}
+ // Set obj:supports properties
+ SLV2Values types = slv2_port_get_value(plug, id, supports_pred);
+ for (uint32_t i = 0; i < slv2_values_size(types); ++i) {
+ SLV2Value type = slv2_values_get_at(types, i);
+ std::cout << path() << " port " << id << " supports " <<
+ slv2_value_as_uri(type) << std::endl;
+ if (slv2_value_is_uri(type)) {
+ port->add_property(uris.obj_supports, Raul::URI(slv2_value_as_uri(type)));
+ }
+ }
+
SLV2Values contexts = slv2_port_get_value(plug, id, context_pred);
for (uint32_t i = 0; i < slv2_values_size(contexts); ++i) {
SLV2Value c = slv2_values_get_at(contexts, i);
@@ -397,7 +411,7 @@ LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num,
{
NodeImpl::set_port_buffer(voice, port_num, buf, offset);
slv2_instance_connect_port(instance(voice), port_num,
- buf ? buf->port_data(_ports->at(port_num)->type(), offset) : NULL);
+ buf ? buf->port_data(_ports->at(port_num)->buffer_type(), offset) : NULL);
}
diff --git a/src/engine/ObjectSender.cpp b/src/engine/ObjectSender.cpp
index adb35f13..0055dff1 100644
--- a/src/engine/ObjectSender.cpp
+++ b/src/engine/ObjectSender.cpp
@@ -141,11 +141,8 @@ ObjectSender::send_port(ClientInterface* client, const PortImpl* port, bool bund
client->put(port->path(), port->properties());
// Send control value
- if (port->type() == PortType::CONTROL) {
- //const Sample& value = PtrCast<const AudioBuffer>(port->buffer(0))->value_at(0);
- const Sample& value = ((const AudioBuffer*)port->buffer(0).get())->value_at(0);
- client->set_property(port->path(), map.ingen_value, value);
- }
+ if (port->is_a(PortType::CONTROL))
+ client->set_property(port->path(), map.ingen_value, port->value());
if (bundle)
client->bundle_end();
diff --git a/src/engine/OutputPort.cpp b/src/engine/OutputPort.cpp
index 269d6da6..c2381cff 100644
--- a/src/engine/OutputPort.cpp
+++ b/src/engine/OutputPort.cpp
@@ -55,7 +55,7 @@ void
OutputPort::get_buffers(BufferFactory& bufs, Raul::Array<BufferFactory::Ref>* buffers, uint32_t poly)
{
for (uint32_t v = 0; v < poly; ++v)
- buffers->at(v) = bufs.get(_type, _buffer_size);
+ buffers->at(v) = bufs.get(buffer_type(), _buffer_size);
}
diff --git a/src/engine/PortImpl.cpp b/src/engine/PortImpl.cpp
index 1f2c6530..a1a20ba8 100644
--- a/src/engine/PortImpl.cpp
+++ b/src/engine/PortImpl.cpp
@@ -53,7 +53,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
, _index(index)
, _poly(poly)
, _buffer_size(buffer_size)
- , _type(type)
+ , _buffer_type(type)
, _value(value)
, _broadcast(false)
, _set_by_user(false)
@@ -62,6 +62,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
, _buffers(new Array<BufferFactory::Ref>(static_cast<size_t>(poly)))
, _prepared_buffers(NULL)
{
+ _types.insert(type);
assert(node != NULL);
assert(_poly > 0);
@@ -84,6 +85,13 @@ PortImpl::~PortImpl()
}
+bool
+PortImpl::supports(const Raul::URI& value_type) const
+{
+ return has_property(Shared::LV2URIMap::instance().obj_supports, value_type);
+}
+
+
Raul::Array<BufferFactory::Ref>*
PortImpl::set_buffers(Raul::Array<BufferFactory::Ref>* buffers)
{
@@ -105,7 +113,7 @@ bool
PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- if (_type != PortType::CONTROL && _type != PortType::AUDIO)
+ if (buffer_type() != PortType::CONTROL && buffer_type() != PortType::AUDIO)
return false;
if (_poly == poly)
@@ -130,7 +138,7 @@ bool
PortImpl::apply_poly(Maid& maid, uint32_t poly)
{
ThreadManager::assert_thread(THREAD_PROCESS);
- if (_type != PortType::CONTROL && _type != PortType::AUDIO)
+ if (buffer_type() != PortType::CONTROL && buffer_type() != PortType::AUDIO)
return false;
if (!_prepared_buffers)
@@ -145,7 +153,7 @@ PortImpl::apply_poly(Maid& maid, uint32_t poly)
assert(_buffers == _prepared_buffers);
_prepared_buffers = NULL;
- if (_type == PortType::CONTROL)
+ if (is_a(PortType::CONTROL))
for (uint32_t v = 0; v < _poly; ++v)
if (_buffers->at(v))
boost::static_pointer_cast<AudioBuffer>(_buffers->at(v))->set_value(
@@ -199,7 +207,7 @@ void
PortImpl::broadcast_value(Context& context, bool force)
{
Raul::Atom val;
- switch (_type.symbol()) {
+ switch (buffer_type().symbol()) {
case PortType::UNKNOWN:
break;
case PortType::AUDIO:
@@ -214,7 +222,7 @@ PortImpl::broadcast_value(Context& context, bool force)
break;
case PortType::VALUE:
case PortType::MESSAGE:
- LV2Object::to_atom(context.engine().world(), ((ObjectBuffer*)buffer(0).get())->object(), val);
+ LV2Object::to_atom(((ObjectBuffer*)buffer(0).get())->object(), val);
break;
}
@@ -242,4 +250,12 @@ PortImpl::set_context(Context::ID c)
}
+PortType
+PortImpl::buffer_type() const
+{
+ // TODO: multiple types
+ return *_types.begin();
+}
+
+
} // namespace Ingen
diff --git a/src/engine/PortImpl.hpp b/src/engine/PortImpl.hpp
index 6771b78a..637336af 100644
--- a/src/engine/PortImpl.hpp
+++ b/src/engine/PortImpl.hpp
@@ -20,6 +20,7 @@
#include <cstdlib>
#include <string>
+#include <set>
#include "raul/Array.hpp"
#include "raul/Atom.hpp"
#include "interface/Port.hpp"
@@ -103,8 +104,13 @@ public:
virtual bool is_input() const = 0;
virtual bool is_output() const = 0;
- uint32_t index() const { return _index; }
- Shared::PortType type() const { return _type; }
+ uint32_t index() const { return _index; }
+
+ const PortTypes& types() const { return _types; }
+
+ PortType buffer_type() const;
+
+ bool supports(const Raul::URI& value_type) const;
size_t buffer_size() const { return _buffer_size; }
@@ -116,6 +122,7 @@ public:
}
void set_buffer_size(Context& context, BufferFactory& bufs, size_t size);
+ void set_buffer_type(PortType type);
void broadcast(bool b) { _broadcast = b; }
bool broadcast() { return _broadcast; }
@@ -137,15 +144,16 @@ protected:
const Raul::Atom& value,
size_t buffer_size);
- BufferFactory& _bufs;
- uint32_t _index;
- uint32_t _poly;
- uint32_t _buffer_size;
- Shared::PortType _type;
- Raul::Atom _value;
- bool _broadcast;
- bool _set_by_user;
- Raul::Atom _last_broadcasted_value;
+ BufferFactory& _bufs;
+ uint32_t _index;
+ uint32_t _poly;
+ uint32_t _buffer_size;
+ PortType _buffer_type;
+ std::set<Shared::PortType> _types;
+ Raul::Atom _value;
+ bool _broadcast;
+ bool _set_by_user;
+ Raul::Atom _last_broadcasted_value;
Context::ID _context;
Raul::Array<BufferFactory::Ref>* _buffers;
diff --git a/src/engine/events/Connect.cpp b/src/engine/events/Connect.cpp
index b4389438..5b7726d9 100644
--- a/src/engine/events/Connect.cpp
+++ b/src/engine/events/Connect.cpp
@@ -47,8 +47,6 @@ Connect::Connect(Engine& engine, SharedPtr<Request> request, SampleCount timesta
, _src_port_path(src_port_path)
, _dst_port_path(dst_port_path)
, _patch(NULL)
- , _src_port(NULL)
- , _dst_port(NULL)
, _src_output_port(NULL)
, _dst_input_port(NULL)
, _compiled_patch(NULL)
@@ -61,58 +59,46 @@ Connect::Connect(Engine& engine, SharedPtr<Request> request, SampleCount timesta
void
Connect::pre_process()
{
- if (_src_port_path.parent().parent() != _dst_port_path.parent().parent()
- && _src_port_path.parent() != _dst_port_path.parent().parent()
- && _src_port_path.parent().parent() != _dst_port_path.parent()) {
- _error = PARENT_PATCH_DIFFERENT;
+ PortImpl* src_port = _engine.engine_store()->find_port(_src_port_path);
+ PortImpl* dst_port = _engine.engine_store()->find_port(_dst_port_path);
+ if (!src_port || !dst_port) {
+ _error = PORT_NOT_FOUND;
QueuedEvent::pre_process();
return;
}
- _src_port = _engine.engine_store()->find_port(_src_port_path);
- _dst_port = _engine.engine_store()->find_port(_dst_port_path);
-
- if (_src_port == NULL || _dst_port == NULL) {
- _error = PORT_NOT_FOUND;
+ _dst_input_port = dynamic_cast<InputPort*>(dst_port);
+ _src_output_port = dynamic_cast<OutputPort*>(src_port);
+ if (!_dst_input_port || !_src_output_port) {
+ _error = DIRECTION_MISMATCH;
QueuedEvent::pre_process();
return;
}
- const PortType src_type = _src_port->type();
- const PortType dst_type = _dst_port->type();
-
- if ( !(
- // Equal types
- (src_type == dst_type)
-
- || // or Control=>Audio or Audio=>Control
- ((src_type == PortType::CONTROL || src_type == PortType::AUDIO)
- && (dst_type == PortType::CONTROL || dst_type == PortType::AUDIO))
-
- || // or Events=>Message or Message=>Events
- ((src_type == PortType::EVENTS || src_type == PortType::MESSAGE)
- && (dst_type == PortType::EVENTS || dst_type == PortType::MESSAGE))
- )) {
- _error = TYPE_MISMATCH;
+ NodeImpl* const src_node = src_port->parent_node();
+ NodeImpl* const dst_node = dst_port->parent_node();
+ if (!src_node || !dst_node) {
+ _error = PARENTS_NOT_FOUND;
QueuedEvent::pre_process();
return;
}
- _dst_input_port = dynamic_cast<InputPort*>(_dst_port);
- _src_output_port = dynamic_cast<OutputPort*>(_src_port);
-
- if (!_dst_input_port || !_src_output_port) {
- _error = DIRECTION_MISMATCH;
+ if (src_node->parent() != dst_node->parent()
+ && src_node != dst_node->parent()
+ && src_node->parent() != dst_node) {
+ _error = PARENT_PATCH_DIFFERENT;
QueuedEvent::pre_process();
return;
}
- NodeImpl* const src_node = _src_port->parent_node();
- NodeImpl* const dst_node = _dst_port->parent_node();
+ if (!ConnectionImpl::can_connect(_src_output_port, _dst_input_port)) {
+ _error = TYPE_MISMATCH;
+ QueuedEvent::pre_process();
+ return;
+ }
// Connection to a patch port from inside the patch
if (src_node->parent_patch() != dst_node->parent_patch()) {
-
assert(src_node->parent() == dst_node || dst_node->parent() == src_node);
if (src_node->parent() == dst_node)
_patch = dynamic_cast<PatchImpl*>(dst_node);
@@ -128,28 +114,14 @@ Connect::pre_process()
_patch = src_node->parent_patch();
}
- assert(_patch);
-
if (_patch->has_connection(_src_output_port, _dst_input_port)) {
_error = ALREADY_CONNECTED;
QueuedEvent::pre_process();
return;
}
- if (src_node == NULL || dst_node == NULL) {
- _error = PARENTS_NOT_FOUND;
- QueuedEvent::pre_process();
- return;
- }
-
- if (_patch != src_node && src_node->parent() != _patch && dst_node->parent() != _patch) {
- _error = PARENTS_NOT_FOUND;
- QueuedEvent::pre_process();
- return;
- }
-
_connection = SharedPtr<ConnectionImpl>(
- new ConnectionImpl(*_engine.buffer_factory(), _src_port, _dst_port));
+ new ConnectionImpl(*_engine.buffer_factory(), _src_output_port, _dst_input_port));
_port_listnode = new InputPort::Connections::Node(_connection);
diff --git a/src/engine/events/Connect.hpp b/src/engine/events/Connect.hpp
index 322a5dbf..cfb924c2 100644
--- a/src/engine/events/Connect.hpp
+++ b/src/engine/events/Connect.hpp
@@ -70,8 +70,6 @@ private:
Raul::Path _dst_port_path;
PatchImpl* _patch;
- PortImpl* _src_port;
- PortImpl* _dst_port;
OutputPort* _src_output_port;
InputPort* _dst_input_port;
diff --git a/src/engine/events/Disconnect.cpp b/src/engine/events/Disconnect.cpp
index 250dc234..f25c0f4a 100644
--- a/src/engine/events/Disconnect.cpp
+++ b/src/engine/events/Disconnect.cpp
@@ -190,10 +190,12 @@ Disconnect::execute(ProcessContext& context)
_dst_input_port->connect_buffers();
if (_clear_dst_port) {
for (uint32_t v = 0; v < _dst_input_port->poly(); ++v) {
- if (_dst_input_port->type() == PortType::CONTROL) {
- PtrCast<AudioBuffer>(_dst_input_port->buffer(v))->set_value(
- _dst_input_port->value().get_float(),
- context.start(), context.start());
+ if (_dst_input_port->is_a(PortType::CONTROL)) {
+ IntrusivePtr<AudioBuffer> abuf(PtrCast<AudioBuffer>(
+ _dst_input_port->buffer(v)));
+ if (abuf)
+ abuf->set_value(_dst_input_port->value().get_float(),
+ context.start(), context.start());
} else {
_dst_input_port->buffer(v)->clear();
}
diff --git a/src/engine/events/RequestMetadata.cpp b/src/engine/events/RequestMetadata.cpp
index 707398bd..4d879298 100644
--- a/src/engine/events/RequestMetadata.cpp
+++ b/src/engine/events/RequestMetadata.cpp
@@ -15,6 +15,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "raul/IntrusivePtr.hpp"
#include "interface/ClientInterface.hpp"
#include "events/RequestMetadata.hpp"
#include "shared/LV2Object.hpp"
@@ -94,11 +95,15 @@ RequestMetadata::execute(ProcessContext& context)
if (_special_type == PORT_VALUE) {
PortImpl* port = dynamic_cast<PortImpl*>(_resource);
if (port) {
- if (port->type() == PortType::CONTROL || port->type() == PortType::AUDIO)
- _value = ((AudioBuffer*)port->buffer(0).get())->value_at(0); // TODO: offset
- else if (port->type() == PortType::VALUE || port->type() == PortType::MESSAGE)
- LV2Object::to_atom(context.engine().world(),
- ((ObjectBuffer*)port->buffer(0).get())->object(), _value);
+ IntrusivePtr<AudioBuffer> abuf = PtrCast<AudioBuffer>(port->buffer(0));
+ if (abuf) {
+ _value = abuf->value_at(0);
+ } else {
+ IntrusivePtr<ObjectBuffer> obuf = PtrCast<ObjectBuffer>(port->buffer(0));
+ if (obuf) {
+ LV2Object::to_atom(obuf->object(), _value);
+ }
+ }
} else {
_resource = 0;
}
diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp
index c1cc97f0..a44261d4 100644
--- a/src/engine/events/SetMetadata.cpp
+++ b/src/engine/events/SetMetadata.cpp
@@ -193,7 +193,7 @@ SetMetadata::pre_process()
ev->pre_process();
_set_events.push_back(ev);
} else if (key == uris.ingen_controlBinding) {
- if (port->type() == Shared::PortType::CONTROL) {
+ if (port->is_a(Shared::PortType::CONTROL)) {
if (value == uris.wildcard) {
_engine.control_bindings()->learn(port);
} else if (value.type() == Atom::DICT) {
diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp
index 2ad94082..b93783c2 100644
--- a/src/engine/events/SetPortValue.cpp
+++ b/src/engine/events/SetPortValue.cpp
@@ -176,7 +176,7 @@ SetPortValue::apply(Context& context)
ObjectBuffer* const obuf = dynamic_cast<ObjectBuffer*>(buf);
if (obuf) {
obuf->object()->size = obuf->size() - sizeof(LV2_Object);
- if (LV2Object::from_atom(_engine.world(), _value, obuf->object())) {
+ if (LV2Object::from_atom(_value, obuf->object())) {
debug << "Converted atom " << _value << " :: " << obuf->object()->type
<< " * " << obuf->object()->size << " @ " << obuf->object() << endl;
return;
diff --git a/src/gui/App.cpp b/src/gui/App.cpp
index 3bf45761..968d5940 100644
--- a/src/gui/App.cpp
+++ b/src/gui/App.cpp
@@ -30,10 +30,11 @@
#include "module/World.hpp"
#include "engine/Engine.hpp"
#include "interface/EngineInterface.hpp"
+#include "shared/runtime_paths.hpp"
+#include "shared/LV2URIMap.hpp"
#include "client/ObjectModel.hpp"
#include "client/PatchModel.hpp"
#include "client/ClientStore.hpp"
-#include "shared/runtime_paths.hpp"
#include "NodeModule.hpp"
#include "ControlPanel.hpp"
#include "SubpatchModule.hpp"
@@ -389,6 +390,16 @@ App::icon_destroyed(void* data)
}
+bool
+App::can_control(const Shared::Port* port) const
+{
+ return port->is_a(PortType::CONTROL)
+ || (port->is_a(PortType::VALUE)
+ && (port->supports(uris().object_class_float32)
+ || port->supports(uris().object_class_string)));
+}
+
+
} // namespace GUI
} // namespace Ingen
diff --git a/src/gui/App.hpp b/src/gui/App.hpp
index 78839772..3ac881f6 100644
--- a/src/gui/App.hpp
+++ b/src/gui/App.hpp
@@ -35,11 +35,13 @@ namespace Ingen {
class EngineInterface;
class ClientInterface;
class World;
+ class Port;
}
namespace Client {
+ class ClientStore;
class PatchModel;
class PluginModel;
- class ClientStore;
+ class PortModel;
class SigClientInterface;
}
namespace Serialisation {
@@ -48,6 +50,7 @@ namespace Ingen {
}
namespace Ingen {
+
namespace GUI {
class MessagesWindow;
@@ -88,6 +91,7 @@ public:
void port_activity(Port* port);
void activity_port_destroyed(Port* port);
+ bool can_control(const Shared::Port* port) const;
bool signal() const { return _enable_signal; }
bool disable_signals() { bool old = _enable_signal; _enable_signal = false; return old; }
@@ -113,8 +117,8 @@ public:
static void init(Ingen::Shared::World* world);
static void run();
- inline Ingen::Shared::World* world() { return _world; }
- inline Ingen::Shared::LV2URIMap& uris() { return *_world->uris; }
+ inline Ingen::Shared::World* world() const { return _world; }
+ inline Ingen::Shared::LV2URIMap& uris() const { return *_world->uris; }
protected:
diff --git a/src/gui/Configuration.cpp b/src/gui/Configuration.cpp
index 03f84a5a..6154de72 100644
--- a/src/gui/Configuration.cpp
+++ b/src/gui/Configuration.cpp
@@ -89,24 +89,16 @@ Configuration::get_port_color(const PortModel* p)
{
assert(p != NULL);
- if (p->type().is_control()) {
- return _control_port_color;
- } else if (p->type().is_audio()) {
+ if (p->is_a(Shared::PortType::AUDIO)) {
return _audio_port_color;
- } else if (p->type().is_events()) {
- return _event_port_color;
- /*} else if (p->type().is_osc()) {
- return _osc_port_color;
- */} else if (p->type().is_value()) {
- return _value_port_color;
- } else if (p->type().is_message()) {
+ } else if (App::instance().can_control(p)) {
+ return _control_port_color;
+ } else if (p->is_a(Shared::PortType::EVENTS) || p->is_a(Shared::PortType::MESSAGE)) {
return _event_port_color;
}
- error << "[Configuration] Unknown port type " << p->type().uri()
- << ", port will appear black." << endl;
-
- return 0x000000FF;
+ warn << "[Configuration] No known port type for " << p->path() << endl;
+ return 0x666666FF;
}
diff --git a/src/gui/ControlPanel.cpp b/src/gui/ControlPanel.cpp
index eda1adc0..c0f6d19f 100644
--- a/src/gui/ControlPanel.cpp
+++ b/src/gui/ControlPanel.cpp
@@ -16,6 +16,7 @@
*/
#include "interface/EngineInterface.hpp"
+#include "interface/PortType.hpp"
#include "shared/LV2URIMap.hpp"
#include "client/NodeModel.hpp"
#include "client/PortModel.hpp"
@@ -89,21 +90,19 @@ ControlPanel::add_port(SharedPtr<PortModel> pm)
// Add port
if (pm->is_input()) {
- if (pm->type().is_control()) {
- if (pm->is_toggle()) {
- ToggleControl* tc;
- Glib::RefPtr<Gnome::Glade::Xml> xml
- = GladeFactory::new_glade_reference("toggle_control");
- xml->get_widget_derived("toggle_control", tc);
- control = tc;
- } else {
- SliderControl* sc;
- Glib::RefPtr<Gnome::Glade::Xml> xml
- = GladeFactory::new_glade_reference("control_strip");
- xml->get_widget_derived("control_strip", sc);
- control = sc;
- }
- } else if (pm->type().is_value() || pm->type().is_message()) {
+ if (pm->is_toggle()) {
+ ToggleControl* tc;
+ Glib::RefPtr<Gnome::Glade::Xml> xml
+ = GladeFactory::new_glade_reference("toggle_control");
+ xml->get_widget_derived("toggle_control", tc);
+ control = tc;
+ } else if (pm->supports(App::instance().uris().object_class_float32)) {
+ SliderControl* sc;
+ Glib::RefPtr<Gnome::Glade::Xml> xml
+ = GladeFactory::new_glade_reference("control_strip");
+ xml->get_widget_derived("control_strip", sc);
+ control = sc;
+ } else if (pm->supports(App::instance().uris().object_class_string)) {
StringControl* sc;
Glib::RefPtr<Gnome::Glade::Xml> xml
= GladeFactory::new_glade_reference("string_control");
diff --git a/src/gui/NodeControlWindow.cpp b/src/gui/NodeControlWindow.cpp
index 4fce6636..bef6f15a 100644
--- a/src/gui/NodeControlWindow.cpp
+++ b/src/gui/NodeControlWindow.cpp
@@ -111,7 +111,7 @@ NodeControlWindow::on_show()
{
for (NodeModel::Ports::const_iterator i = _node->ports().begin();
i != _node->ports().end(); ++i)
- if ((*i)->type().is_control() && (*i)->is_input())
+ if ((*i)->is_input() && App::instance().can_control(i->get()))
App::instance().engine()->request_property((*i)->path(),
App::instance().uris().ingen_value);
diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp
index be5d645b..faa61b56 100644
--- a/src/gui/NodeMenu.cpp
+++ b/src/gui/NodeMenu.cpp
@@ -149,7 +149,7 @@ NodeMenu::on_menu_randomize()
const NodeModel* const nm = (NodeModel*)_object.get();
for (NodeModel::Ports::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i) {
- if ((*i)->is_input() && (*i)->type().is_control()) {
+ if ((*i)->is_input() && App::instance().can_control(i->get())) {
float min = 0.0f, max = 1.0f;
nm->port_value_range(*i, min, max);
const float val = ((rand() / (float)RAND_MAX) * (max - min) + min);
@@ -209,7 +209,7 @@ NodeMenu::has_control_inputs()
{
const NodeModel* const nm = (NodeModel*)_object.get();
for (NodeModel::Ports::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i)
- if ((*i)->is_input() && (*i)->type().is_control())
+ if ((*i)->is_input() && (*i)->is_numeric())
return true;
return false;
diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp
index 03182942..30762f99 100644
--- a/src/gui/NodeModule.cpp
+++ b/src/gui/NodeModule.cpp
@@ -222,7 +222,7 @@ NodeModule::embed_gui(bool embed)
for (NodeModel::Ports::const_iterator p = _node->ports().begin();
p != _node->ports().end(); ++p)
- if ((*p)->type().is_control() && (*p)->is_output())
+ if ((*p)->is_output() && App::instance().can_control(p->get()))
App::instance().engine()->set_property((*p)->path(), uris.ingen_broadcast, true);
}
@@ -232,7 +232,7 @@ NodeModule::embed_gui(bool embed)
_plugin_ui.reset();
for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p)
- if ((*p)->type().is_control() && (*p)->is_output())
+ if ((*p)->is_output() && App::instance().can_control(p->get()))
App::instance().engine()->set_property((*p)->path(), uris.ingen_broadcast, false);
}
@@ -351,7 +351,7 @@ NodeModule::set_control_values()
{
uint32_t index=0;
for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) {
- if ((*p)->type().is_control())
+ if (App::instance().can_control(p->get()))
value_changed(index, (*p)->value());
++index;
}
diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp
index 83e921b3..69cb0414 100644
--- a/src/gui/PatchCanvas.cpp
+++ b/src/gui/PatchCanvas.cpp
@@ -499,12 +499,7 @@ PatchCanvas::connect(boost::shared_ptr<FlowCanvas::Connectable> src_port,
if (!src || !dst)
return;
- // Midi binding/learn shortcut
- if (src->model()->type().is_events() && dst->model()->type().is_control()) {
- LOG(error) << "TODO: MIDI binding shortcut" << endl;
- } else {
- App::instance().engine()->connect(src->model()->path(), dst->model()->path());
- }
+ App::instance().engine()->connect(src->model()->path(), dst->model()->path());
}
diff --git a/src/gui/PatchWindow.cpp b/src/gui/PatchWindow.cpp
index d4fb24cc..27e2737e 100644
--- a/src/gui/PatchWindow.cpp
+++ b/src/gui/PatchWindow.cpp
@@ -237,7 +237,7 @@ PatchWindow::set_patch(SharedPtr<PatchModel> patch, SharedPtr<PatchView> view)
for (NodeModel::Ports::const_iterator p = patch->ports().begin();
p != patch->ports().end(); ++p) {
- if ((*p)->type().is_control() && (*p)->is_input()) {
+ if (App::instance().can_control(p->get())) {
_menu_view_control_window->property_sensitive() = true;
break;
}
@@ -266,7 +266,7 @@ PatchWindow::set_patch(SharedPtr<PatchModel> patch, SharedPtr<PatchView> view)
void
PatchWindow::patch_port_added(SharedPtr<PortModel> port)
{
- if (port->type().is_control() && port->is_input()) {
+ if (port->is_input() && App::instance().can_control(port.get())) {
_menu_view_control_window->property_sensitive() = true;
}
}
@@ -275,19 +275,18 @@ PatchWindow::patch_port_added(SharedPtr<PortModel> port)
void
PatchWindow::patch_port_removed(SharedPtr<PortModel> port)
{
- if (port->type().is_control() && port->is_input()) {
-
- bool found_control = false;
+ if (!(port->is_input() && App::instance().can_control(port.get())))
+ return;
- for (NodeModel::Ports::const_iterator i = _patch->ports().begin(); i != _patch->ports().end(); ++i) {
- if ((*i)->type().is_control() && (*i)->is_input()) {
- found_control = true;
- break;
- }
+ for (NodeModel::Ports::const_iterator i = _patch->ports().begin();
+ i != _patch->ports().end(); ++i) {
+ if ((*i)->is_input() && App::instance().can_control(i->get())) {
+ _menu_view_control_window->property_sensitive() = true;
+ return;
}
-
- _menu_view_control_window->property_sensitive() = found_control;
}
+
+ _menu_view_control_window->property_sensitive() = false;
}
diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp
index e353190d..4e1a5460 100644
--- a/src/gui/Port.cpp
+++ b/src/gui/Port.cpp
@@ -89,7 +89,7 @@ Port::Port(
pm->signal_moved.connect(sigc::mem_fun(this, &Port::moved));
- if (pm->type().is_control()) {
+ if (App::instance().can_control(pm.get())) {
set_toggled(pm->is_toggle());
show_control();
pm->signal_property.connect(sigc::mem_fun(this, &Port::property_changed));
@@ -114,7 +114,7 @@ void
Port::update_metadata()
{
SharedPtr<PortModel> pm = _port_model.lock();
- if (pm && pm->type().is_control()) {
+ if (App::instance().can_control(pm.get()) && pm->is_numeric()) {
boost::shared_ptr<NodeModel> parent = PtrCast<NodeModel>(pm->parent());
if (parent) {
float min = 0.0f;
@@ -191,22 +191,15 @@ Port::set_control(float value, bool signal)
if (signal) {
App& app = App::instance();
Ingen::Shared::World* const world = app.world();
- if (model()->type() == PortType::CONTROL) {
- app.engine()->set_property(model()->path(),
- world->uris->ingen_value, Atom(value));
- PatchWindow* pw = app.window_factory()->patch_window(
- PtrCast<PatchModel>(model()->parent()));
- if (!pw)
- pw = app.window_factory()->patch_window(
- PtrCast<PatchModel>(model()->parent()->parent()));
- if (pw)
- pw->show_port_status(model().get(), value);
-
- } else if (model()->type() == PortType::EVENTS) {
- app.engine()->set_property(model()->path(),
- world->uris->ingen_value,
- Atom("http://example.org/ev#BangEvent", 0, NULL));
- }
+ app.engine()->set_property(model()->path(),
+ world->uris->ingen_value, Atom(value));
+ PatchWindow* pw = app.window_factory()->patch_window(
+ PtrCast<PatchModel>(model()->parent()));
+ if (!pw)
+ pw = app.window_factory()->patch_window(
+ PtrCast<PatchModel>(model()->parent()->parent()));
+ if (pw)
+ pw->show_port_status(model().get(), value);
}
FlowCanvas::Port::set_control(value);
diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp
index b9c538e1..6e15cc9a 100644
--- a/src/gui/PortMenu.cpp
+++ b/src/gui/PortMenu.cpp
@@ -61,10 +61,10 @@ PortMenu::init(SharedPtr<PortModel> port, bool patch_port)
_destroy_menuitem->hide();
}
- if (port->type() == PortType::EVENTS)
+ if (port->is_a(PortType::EVENTS))
_polyphonic_menuitem->hide();
- if (port->type() == PortType::CONTROL) {
+ if (App::instance().can_control(port.get()) && port->is_numeric()) {
_learn_menuitem->show();
_unlearn_menuitem->show();
diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp
index 1469afaf..8d88a21c 100644
--- a/src/serialisation/Serialiser.cpp
+++ b/src/serialisation/Serialiser.cpp
@@ -417,8 +417,10 @@ Serialiser::serialise_port(const Port* port, const Redland::Node& port_id)
_model->add_statement(port_id, "rdf:type",
Redland::Resource(_model->world(), "lv2:OutputPort"));
- _model->add_statement(port_id, "rdf:type",
- Redland::Resource(_model->world(), port->type().uri().str()));
+ for (Port::PortTypes::const_iterator i = port->types().begin();
+ i != port->types().end(); ++i)
+ _model->add_statement(port_id, "rdf:type",
+ Redland::Resource(_model->world(), i->uri().str()));
if (dynamic_cast<Patch*>(port->graph_parent()))
_model->add_statement(port_id, "rdf:instanceOf",
@@ -439,8 +441,10 @@ Serialiser::serialise_port_meta(const Port* port, const Redland::Node& port_id)
_model->add_statement(port_id, "rdf:type",
Redland::Resource(_model->world(), "lv2:OutputPort"));
- _model->add_statement(port_id, "rdf:type",
- Redland::Resource(_model->world(), port->type().uri().str()));
+ for (Port::PortTypes::const_iterator i = port->types().begin();
+ i != port->types().end(); ++i)
+ _model->add_statement(port_id, "rdf:type",
+ Redland::Resource(_model->world(), i->uri().str()));
_model->add_statement(port_id, "lv2:index",
AtomRDF::atom_to_node(*_model, Atom((int)port->index())));
@@ -450,7 +454,7 @@ Serialiser::serialise_port_meta(const Port* port, const Redland::Node& port_id)
if (port->value().is_valid()) {
_model->add_statement(port_id, "lv2:default",
AtomRDF::atom_to_node(*_model, Atom(port->value())));
- } else if (port->type() == PortType::CONTROL) {
+ } else if (port->is_a(PortType::CONTROL)) {
LOG(warn) << "Port " << port->path() << " has no lv2:default" << endl;
}
}
diff --git a/src/shared/LV2Object.hpp b/src/shared/LV2Object.hpp
index b0136d06..794422a0 100644
--- a/src/shared/LV2Object.hpp
+++ b/src/shared/LV2Object.hpp
@@ -28,8 +28,8 @@ class World;
namespace LV2Object {
- bool to_atom(World* world, const LV2_Object* object, Raul::Atom& atom);
- bool from_atom(World* word, const Raul::Atom& atom, LV2_Object* object);
+ bool to_atom(const LV2_Object* object, Raul::Atom& atom);
+ bool from_atom(const Raul::Atom& atom, LV2_Object* object);
} // namespace LV2Object
diff --git a/src/shared/LV2URIMap.cpp b/src/shared/LV2URIMap.cpp
index f83f7aa5..d8114014 100644
--- a/src/shared/LV2URIMap.cpp
+++ b/src/shared/LV2URIMap.cpp
@@ -93,6 +93,7 @@ LV2URIMap::LV2URIMap()
, midi_noteNumber(NS_MIDI "noteNumber")
, obj_MessagePort("http://lv2plug.in/ns/dev/objects#MessagePort")
, obj_ValuePort("http://lv2plug.in/ns/dev/objects#ValuePort")
+ , obj_supports("http://lv2plug.in/ns/dev/objects#supports")
, object_class_bool(LV2_OBJECT_URI "#Bool")
, object_class_float32(LV2_OBJECT_URI "#Float32")
, object_class_int32(LV2_OBJECT_URI "#Int32")
diff --git a/src/shared/LV2URIMap.hpp b/src/shared/LV2URIMap.hpp
index 6b298e79..2c5bdef2 100644
--- a/src/shared/LV2URIMap.hpp
+++ b/src/shared/LV2URIMap.hpp
@@ -101,6 +101,7 @@ public:
const Quark midi_noteNumber;
const Quark obj_MessagePort;
const Quark obj_ValuePort;
+ const Quark obj_supports;
const Quark object_class_bool;
const Quark object_class_float32;
const Quark object_class_int32;