diff options
author | David Robillard <d@drobilla.net> | 2010-02-13 22:07:26 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-02-13 22:07:26 +0000 |
commit | ad07c414d557629251b2f4ea4078c22f241cc865 (patch) | |
tree | dafecc5dd8758e0273105bb2a2a8d481509d19fb /src/engine/events | |
parent | b8cf49d04a2600f83767ddda46929d4d47adc3fd (diff) | |
download | ingen-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.cpp | 99 | ||||
-rw-r--r-- | src/engine/events/Learn.hpp | 61 | ||||
-rw-r--r-- | src/engine/events/SetMetadata.cpp | 131 | ||||
-rw-r--r-- | src/engine/events/SetMetadata.hpp | 11 |
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; }; |