summaryrefslogtreecommitdiffstats
path: root/src/engine/events
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-02-13 22:07:26 +0000
committerDavid Robillard <d@drobilla.net>2010-02-13 22:07:26 +0000
commitad07c414d557629251b2f4ea4078c22f241cc865 (patch)
treedafecc5dd8758e0273105bb2a2a8d481509d19fb /src/engine/events
parentb8cf49d04a2600f83767ddda46929d4d47adc3fd (diff)
downloadingen-ad07c414d557629251b2f4ea4078c22f241cc865.tar.gz
ingen-ad07c414d557629251b2f4ea4078c22f241cc865.tar.bz2
ingen-ad07c414d557629251b2f4ea4078c22f241cc865.zip
Learn and remove bindings exclusively through property interface.
Note this commit breaks some aspects of OSC and HTTP control for now. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2442 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/events')
-rw-r--r--src/engine/events/Learn.cpp99
-rw-r--r--src/engine/events/Learn.hpp61
-rw-r--r--src/engine/events/SetMetadata.cpp131
-rw-r--r--src/engine/events/SetMetadata.hpp11
4 files changed, 96 insertions, 206 deletions
diff --git a/src/engine/events/Learn.cpp b/src/engine/events/Learn.cpp
deleted file mode 100644
index bf453bc3..00000000
--- a/src/engine/events/Learn.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/* This file is part of Ingen.
- * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net>
- *
- * Ingen 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.
- *
- * Ingen 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
- */
-
-#include "events/Learn.hpp"
-#include "ClientBroadcaster.hpp"
-#include "ControlBindings.hpp"
-#include "Engine.hpp"
-#include "EngineStore.hpp"
-#include "NodeImpl.hpp"
-#include "PluginImpl.hpp"
-#include "PortImpl.hpp"
-#include "Request.hpp"
-#include "internals/Controller.hpp"
-
-using namespace std;
-
-namespace Ingen {
-namespace Events {
-
-
-Learn::Learn(Engine& engine, SharedPtr<Request> request, SampleCount timestamp, const Raul::Path& path)
- : QueuedEvent(engine, request, timestamp)
- , _error(NO_ERROR)
- , _path(path)
- , _object(NULL)
- , _done(false)
-{
-}
-
-
-void
-Learn::pre_process()
-{
- _object = _engine.engine_store()->find_object(_path);
-
- PortImpl* port = dynamic_cast<PortImpl*>(_object);
- if (port) {
- _done = true;
- if (port->type() == Shared::PortType::CONTROL)
- _engine.control_bindings()->learn(port);
- }
-
- QueuedEvent::pre_process();
-}
-
-
-void
-Learn::execute(ProcessContext& context)
-{
- QueuedEvent::execute(context);
-
- if (_done || !_object)
- return;
-
- NodeImpl* node = dynamic_cast<NodeImpl*>(_object);
- if (node) {
- if (node->plugin_impl()->type() == Shared::Plugin::Internal) {
- ((NodeBase*)_object)->learn();
- } else {
- _error = INVALID_NODE_TYPE;
- }
- }
-}
-
-
-void
-Learn::post_process()
-{
- if (_error == NO_ERROR) {
- _request->respond_ok();
- } else if (_object == NULL) {
- string msg = "Did not find node '";
- msg.append(_path.str()).append("' for learn.");
- _request->respond_error(msg);
- } else {
- const string msg = string("Object '") + _path.str() + "' is not capable of learning.";
- _request->respond_error(msg);
- }
-}
-
-
-} // namespace Ingen
-} // namespace Events
-
-
diff --git a/src/engine/events/Learn.hpp b/src/engine/events/Learn.hpp
deleted file mode 100644
index fea8a53e..00000000
--- a/src/engine/events/Learn.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This file is part of Ingen.
- * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net>
- *
- * Ingen 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.
- *
- * Ingen 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 INGEN_EVENTS_LEARN_HPP
-#define INGEN_EVENTS_LEARN_HPP
-
-#include "QueuedEvent.hpp"
-#include "internals/Controller.hpp"
-#include "types.hpp"
-
-namespace Ingen {
-
-class NodeImpl;
-
-namespace Events {
-
-
-/** A MIDI learn event (used by control node to learn controller number).
- *
- * \ingroup engine
- */
-class Learn : public QueuedEvent
-{
-public:
- Learn(Engine& engine, SharedPtr<Request> request, SampleCount timestamp, const Raul::Path& path);
-
- void pre_process();
- void execute(ProcessContext& context);
- void post_process();
-
-private:
- enum ErrorType {
- NO_ERROR,
- INVALID_NODE_TYPE
- };
-
- ErrorType _error;
- const Raul::Path _path;
- GraphObjectImpl* _object;
- bool _done;
-};
-
-
-} // namespace Ingen
-} // namespace Events
-
-#endif // INGEN_EVENTS_LEARN_HPP
diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp
index 77b67543..48de6b85 100644
--- a/src/engine/events/SetMetadata.cpp
+++ b/src/engine/events/SetMetadata.cpp
@@ -35,6 +35,8 @@
#include "SetMetadata.hpp"
#include "SetPortValue.hpp"
+#define LOG(s) s << "[SetMetadata] "
+
using namespace std;
using namespace Raul;
@@ -49,22 +51,34 @@ SetMetadata::SetMetadata(
Engine& engine,
SharedPtr<Request> request,
SampleCount timestamp,
- bool replace,
+ bool create,
bool meta,
const URI& subject,
- const Properties& properties)
+ const Properties& properties,
+ const Properties& remove)
: QueuedEvent(engine, request, timestamp, false)
, _error(NO_ERROR)
, _create_event(NULL)
, _subject(subject)
, _properties(properties)
+ , _remove(remove)
, _object(NULL)
, _patch(NULL)
, _compiled_patch(NULL)
- , _replace(replace)
+ , _create(create)
, _is_meta(meta)
- , _success(false)
{
+ LOG(debug) << "Set " << subject << " {" << endl;
+ typedef Resource::Properties::const_iterator iterator;
+ for (iterator i = properties.begin(); i != properties.end(); ++i)
+ LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl;
+ LOG(debug) << "}" << endl;
+
+ LOG(debug) << "Unset " << subject << " {" << endl;
+ typedef Resource::Properties::const_iterator iterator;
+ for (iterator i = remove.begin(); i != remove.end(); ++i)
+ LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl;
+ LOG(debug) << "}" << endl;
}
@@ -88,7 +102,7 @@ SetMetadata::pre_process()
? _engine.engine_store()->find_object(Path(_subject.str()))
: _object = _engine.node_factory()->plugin(_subject);
- if (!_object && !is_graph_object) {
+ if (!_object && (!is_graph_object || !_create)) {
_error = NOT_FOUND;
QueuedEvent::pre_process();
return;
@@ -133,6 +147,7 @@ SetMetadata::pre_process()
GraphObjectImpl* obj = dynamic_cast<GraphObjectImpl*>(_object);
+#if 0
// If we're replacing (i.e. this is a PUT, not a POST), first remove all properties
// with keys we will later set. This must be done first so a PUT with several properties
// of the same predicate (e.g. rdf:type) retains the multiple values. Only previously
@@ -140,6 +155,7 @@ SetMetadata::pre_process()
if (_replace)
for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p)
obj->properties().erase(p->first);
+#endif
for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) {
const Raul::URI& key = p->first;
@@ -149,14 +165,38 @@ SetMetadata::pre_process()
Resource& resource = _is_meta ? obj->meta() : *obj;
resource.add_property(key, value);
- _patch = dynamic_cast<PatchImpl*>(_object);
-
- if (key == uris.ingen_broadcast) {
- if (value.type() == Atom::BOOL)
- op = ENABLE_BROADCAST;
- else
- _error = BAD_VALUE_TYPE;
- } else if (_patch) {
+ PortImpl* port = dynamic_cast<PortImpl*>(_object);
+ if (port) {
+ if (key == uris.ingen_broadcast) {
+ if (value.type() == Atom::BOOL) {
+ op = ENABLE_BROADCAST;
+ } else {
+ _error = BAD_VALUE_TYPE;
+ }
+ } else if (key == uris.ingen_value) {
+ PortImpl* port = dynamic_cast<PortImpl*>(_object);
+ if (port) {
+ SetPortValue* ev = new SetPortValue(_engine, _request, _time, port, value);
+ ev->pre_process();
+ _set_events.push_back(ev);
+ } else {
+ _error = BAD_OBJECT_TYPE;
+ }
+ } else if (key == uris.ingen_controlBinding) {
+ PortImpl* port = dynamic_cast<PortImpl*>(_object);
+ if (port && port->type() == Shared::PortType::CONTROL) {
+ if (value == uris.wildcard) {
+ _engine.control_bindings()->learn(port);
+ } else if (value.type() == Atom::DICT) {
+ op = CONTROL_BINDING;
+ } else {
+ _error = BAD_VALUE_TYPE;
+ }
+ } else {
+ _error = BAD_OBJECT_TYPE;
+ }
+ }
+ } else if ((_patch = dynamic_cast<PatchImpl*>(_object))) {
if (key == uris.ingen_enabled) {
if (value.type() == Atom::BOOL) {
op = ENABLE;
@@ -179,26 +219,6 @@ SetMetadata::pre_process()
_error = BAD_VALUE_TYPE;
}
}
- } else if (key == uris.ingen_value) {
- PortImpl* port = dynamic_cast<PortImpl*>(_object);
- if (port) {
- SetPortValue* ev = new SetPortValue(_engine, _request, _time, port, value);
- ev->pre_process();
- _set_events.push_back(ev);
- } else {
- warn << "Set value for non-port " << _object->uri() << endl;
- }
- } else if (key == uris.ingen_controlBinding) {
- PortImpl* port = dynamic_cast<PortImpl*>(_object);
- if (port) {
- if (value.type() == Atom::DICT) {
- op = CONTROL_BINDING;
- } else {
- _error = BAD_VALUE_TYPE;
- }
- } else {
- warn << "Set binding for non-port " << _object->uri() << endl;
- }
}
}
@@ -210,6 +230,17 @@ SetMetadata::pre_process()
_types.push_back(op);
}
+ for (Properties::iterator p = _remove.begin(); p != _remove.end(); ++p) {
+ const Raul::URI& key = p->first;
+ const Raul::Atom& value = p->second;
+ if (key == uris.ingen_controlBinding && value == uris.wildcard) {
+ PortImpl* port = dynamic_cast<PortImpl*>(_object);
+ if (port)
+ _old_bindings = _engine.control_bindings()->remove(port);
+ }
+ _object->remove_property(key, value);
+ }
+
QueuedEvent::pre_process();
}
@@ -233,14 +264,16 @@ SetMetadata::execute(ProcessContext& context)
for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i)
(*i)->execute(context);
+ GraphObjectImpl* const object = dynamic_cast<GraphObjectImpl*>(_object);
+ NodeBase* const node = dynamic_cast<NodeBase*>(_object);
+ PortImpl* const port = dynamic_cast<PortImpl*>(_object);
+
std::vector<SpecialType>::const_iterator t = _types.begin();
- for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) {
- const Raul::Atom& value = p->second;
- PortImpl* port = 0;
- GraphObjectImpl* object = 0;
+ for (Properties::const_iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) {
+ const Raul::Atom& value = p->second;
switch (*t) {
case ENABLE_BROADCAST:
- if ((port = dynamic_cast<PortImpl*>(_object)))
+ if (port)
port->broadcast(value.get_bool());
break;
case ENABLE:
@@ -253,7 +286,7 @@ SetMetadata::execute(ProcessContext& context)
}
break;
case POLYPHONIC:
- if ((object = dynamic_cast<GraphObjectImpl*>(_object)))
+ if (object)
if (!object->set_polyphonic(*_engine.maid(), value.get_bool()))
_error = INTERNAL;
break;
@@ -262,13 +295,22 @@ SetMetadata::execute(ProcessContext& context)
_error = INTERNAL;
break;
case CONTROL_BINDING:
- if ((port = dynamic_cast<PortImpl*>(_object)))
+ if (port) {
_engine.control_bindings()->port_binding_changed(context, port);
- default:
- _success = true;
+ } else if (node) {
+ if (node->plugin_impl()->type() == Shared::Plugin::Internal) {
+ node->learn();
+ }
+ }
+ break;
+ case NONE:
+ break;
}
}
+ for (Properties::const_iterator p = _remove.begin(); p != _remove.end(); ++p, ++t)
+ _object->remove_property(p->first, p->second);
+
QueuedEvent::execute(context);
}
@@ -282,7 +324,10 @@ SetMetadata::post_process()
switch (_error) {
case NO_ERROR:
_request->respond_ok();
- _engine.broadcaster()->put(_subject, _properties);
+ if (_create)
+ _engine.broadcaster()->put(_subject, _properties);
+ else
+ _engine.broadcaster()->delta(_subject, _remove, _properties);
if (_create_event)
_create_event->post_process();
break;
diff --git a/src/engine/events/SetMetadata.hpp b/src/engine/events/SetMetadata.hpp
index 0abdd52a..b4b1d0ef 100644
--- a/src/engine/events/SetMetadata.hpp
+++ b/src/engine/events/SetMetadata.hpp
@@ -69,10 +69,11 @@ public:
Engine& engine,
SharedPtr<Request> request,
SampleCount timestamp,
- bool replace,
+ bool create,
bool meta,
const Raul::URI& subject,
- const Shared::Resource::Properties& properties);
+ const Shared::Resource::Properties& properties,
+ const Shared::Resource::Properties& remove=Shared::Resource::Properties());
~SetMetadata();
@@ -102,15 +103,19 @@ private:
QueuedEvent* _create_event;
SetEvents _set_events;
std::vector<SpecialType> _types;
+ std::vector<SpecialType> _remove_types;
Raul::URI _subject;
Shared::Resource::Properties _properties;
+ Shared::Resource::Properties _remove;
Shared::ResourceImpl* _object;
PatchImpl* _patch;
CompiledPatch* _compiled_patch;
std::string _error_predicate;
- bool _replace;
+ bool _create;
bool _is_meta;
bool _success;
+
+ SharedPtr<ControlBindings::Bindings> _old_bindings;
};