From e3fd49d281eb4926bb3b2929b5ac198800e6a8f1 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 23 May 2012 04:00:57 +0000 Subject: SetMetadata => Delta. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4448 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/EventWriter.cpp | 12 +- src/server/events.hpp | 2 +- src/server/events/Delta.cpp | 367 ++++++++++++++++++++++++++++++++++++++ src/server/events/Delta.hpp | 118 ++++++++++++ src/server/events/SetMetadata.cpp | 367 -------------------------------------- src/server/events/SetMetadata.hpp | 118 ------------ src/server/wscript | 2 +- 7 files changed, 493 insertions(+), 493 deletions(-) create mode 100644 src/server/events/Delta.cpp create mode 100644 src/server/events/Delta.hpp delete mode 100644 src/server/events/SetMetadata.cpp delete mode 100644 src/server/events/SetMetadata.hpp diff --git a/src/server/EventWriter.cpp b/src/server/EventWriter.cpp index 33462c1c..a6482a38 100644 --- a/src/server/EventWriter.cpp +++ b/src/server/EventWriter.cpp @@ -61,8 +61,8 @@ EventWriter::put(const Raul::URI& uri, const Resource::Graph ctx) { _engine.enqueue_event( - new Events::SetMetadata(_engine, _respondee.get(), _request_id, now(), - true, ctx, uri, properties)); + new Events::Delta(_engine, _respondee.get(), _request_id, now(), + true, ctx, uri, properties)); } void @@ -71,8 +71,8 @@ EventWriter::delta(const Raul::URI& uri, const Resource::Properties& add) { _engine.enqueue_event( - new Events::SetMetadata(_engine, _respondee.get(), _request_id, now(), - false, Resource::DEFAULT, uri, add, remove)); + new Events::Delta(_engine, _respondee.get(), _request_id, now(), + false, Resource::DEFAULT, uri, add, remove)); } void @@ -129,8 +129,8 @@ EventWriter::set_property(const Raul::URI& uri, Resource::Properties add; add.insert(make_pair(predicate, value)); _engine.enqueue_event( - new Events::SetMetadata(_engine, _respondee.get(), _request_id, now(), - false, Resource::DEFAULT, uri, add, remove)); + new Events::Delta(_engine, _respondee.get(), _request_id, now(), + false, Resource::DEFAULT, uri, add, remove)); } void diff --git a/src/server/events.hpp b/src/server/events.hpp index 9c1ed8aa..cf764fa9 100644 --- a/src/server/events.hpp +++ b/src/server/events.hpp @@ -22,11 +22,11 @@ #include "events/CreatePatch.hpp" #include "events/CreatePort.hpp" #include "events/Delete.hpp" +#include "events/Delta.hpp" #include "events/Disconnect.hpp" #include "events/DisconnectAll.hpp" #include "events/Get.hpp" #include "events/Move.hpp" -#include "events/SetMetadata.hpp" #include "events/SetPortValue.hpp" #endif // INGEN_ENGINE_EVENTS_HPP diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp new file mode 100644 index 00000000..34e9d63d --- /dev/null +++ b/src/server/events/Delta.cpp @@ -0,0 +1,367 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#include +#include + +#include + +#include + +#include "raul/log.hpp" +#include "raul/Maid.hpp" + +#include "ingen/shared/URIMap.hpp" +#include "ingen/shared/URIs.hpp" + +#include "Broadcaster.hpp" +#include "ControlBindings.hpp" +#include "CreateNode.hpp" +#include "CreatePatch.hpp" +#include "CreatePort.hpp" +#include "Delta.hpp" +#include "Driver.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" +#include "GraphObjectImpl.hpp" +#include "PatchImpl.hpp" +#include "PluginImpl.hpp" +#include "PortImpl.hpp" +#include "PortType.hpp" +#include "SetPortValue.hpp" + +#define LOG(s) s << "[Delta] " + +namespace Ingen { +namespace Server { +namespace Events { + +typedef Resource::Properties Properties; + +Delta::Delta(Engine& engine, + Interface* client, + int32_t id, + SampleCount timestamp, + bool create, + Resource::Graph context, + const Raul::URI& subject, + const Properties& properties, + const Properties& remove) + : Event(engine, client, id, timestamp) + , _create_event(NULL) + , _subject(subject) + , _properties(properties) + , _remove(remove) + , _object(NULL) + , _patch(NULL) + , _compiled_patch(NULL) + , _create(create) + , _context(context) +{ + if (context != Resource::DEFAULT) { + Resource::set_context(_properties, context); + } + + /* + LOG(Raul::info) << "Delta " << subject << " : " << context << " {" << std::endl; + typedef Resource::Properties::const_iterator iterator; + for (iterator i = properties.begin(); i != properties.end(); ++i) { + LOG(Raul::info) << " + " << i->first + << " = " << engine.world()->forge().str(i->second) + << " :: " << engine.world()->uri_map().unmap_uri(i->second.type()) << std::endl; + } + typedef Resource::Properties::const_iterator iterator; + for (iterator i = remove.begin(); i != remove.end(); ++i) { + LOG(Raul::info) << " - " << i->first + << " = " << engine.world()->forge().str(i->second) + << " :: " << engine.world()->uri_map().unmap_uri(i->second.type()) << std::endl; + } + LOG(Raul::info) << "}" << std::endl; + */ +} + +Delta::~Delta() +{ + for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) + delete *i; + + delete _create_event; +} + +bool +Delta::pre_process() +{ + typedef Properties::const_iterator iterator; + + const bool is_graph_object = Raul::Path::is_path(_subject); + + // Take a writer lock while we modify the store + Glib::RWLock::WriterLock lock(_engine.engine_store()->lock()); + + _object = is_graph_object + ? _engine.engine_store()->find_object(Raul::Path(_subject.str())) + : static_cast(_engine.node_factory()->plugin(_subject)); + + if (!_object && (!is_graph_object || !_create)) { + return Event::pre_process_done(NOT_FOUND); + } + + const Ingen::Shared::URIs& uris = _engine.world()->uris(); + + if (is_graph_object && !_object) { + Raul::Path path(_subject.str()); + bool is_patch = false, is_node = false, is_port = false, is_output = false; + Shared::ResourceImpl::type(uris, _properties, is_patch, is_node, is_port, is_output); + + if (is_patch) { + _create_event = new CreatePatch( + _engine, _request_client, _request_id, _time, path, _properties); + } else if (is_node) { + _create_event = new CreateNode( + _engine, _request_client, _request_id, _time, path, _properties); + } else if (is_port) { + _create_event = new CreatePort( + _engine, _request_client, _request_id, _time, + path, is_output, _properties); + } + if (_create_event) { + _create_event->pre_process(); + // Grab the object for applying properties, if the create-event succeeded + _object = _engine.engine_store()->find_object(Raul::Path(_subject.str())); + } else { + return Event::pre_process_done(BAD_OBJECT_TYPE); + } + } + + _types.reserve(_properties.size()); + + GraphObjectImpl* obj = dynamic_cast(_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 + // existing properties should be replaced + if (_replace) + for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) + obj->properties().erase(p->first); +#endif + + for (Properties::const_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(_object); + if (port) + _old_bindings = _engine.control_bindings()->remove(port); + } + _object->remove_property(key, value); + } + + for (Properties::const_iterator p = _properties.begin(); p != _properties.end(); ++p) { + const Raul::URI& key = p->first; + const Resource::Property& value = p->second; + SpecialType op = NONE; + if (obj) { + Resource& resource = *obj; + resource.add_property(key, value, value.context()); + + PortImpl* port = dynamic_cast(_object); + if (port) { + if (key == uris.ingen_broadcast) { + if (value.type() == uris.forge.Bool) { + op = ENABLE_BROADCAST; + } else { + _status = BAD_VALUE_TYPE; + } + } else if (key == uris.ingen_value) { + SetPortValue* ev = new SetPortValue( + _engine, _request_client, _request_id, _time, port, value); + ev->pre_process(); + _set_events.push_back(ev); + } else if (key == uris.ingen_controlBinding) { + if (port->is_a(PortType::CONTROL) || port->is_a(PortType::CV)) { + if (value == uris.wildcard) { + _engine.control_bindings()->learn(port); + } else if (value.type() == uris.forge.Dict) { + op = CONTROL_BINDING; + } else { + _status = BAD_VALUE_TYPE; + } + } else { + _status = BAD_OBJECT_TYPE; + } + } + } else if ((_patch = dynamic_cast(_object))) { + if (key == uris.ingen_enabled) { + if (value.type() == uris.forge.Bool) { + op = ENABLE; + // FIXME: defer this until all other metadata has been processed + if (value.get_bool() && !_patch->enabled()) + _compiled_patch = _patch->compile(); + } else { + _status = BAD_VALUE_TYPE; + } + } else if (key == uris.ingen_polyphony) { + if (value.type() == uris.forge.Int) { + op = POLYPHONY; + _patch->prepare_internal_poly(*_engine.buffer_factory(), value.get_int32()); + } else { + _status = BAD_VALUE_TYPE; + } + } + } else if (key == uris.ingen_polyphonic) { + PatchImpl* parent = dynamic_cast(obj->parent()); + if (parent) { + if (value.type() == uris.forge.Bool) { + op = POLYPHONIC; + obj->set_property(key, value, value.context()); + NodeImpl* node = dynamic_cast(obj); + if (node) + node->set_polyphonic(value.get_bool()); + if (value.get_bool()) { + obj->prepare_poly(*_engine.buffer_factory(), parent->internal_poly()); + } else { + obj->prepare_poly(*_engine.buffer_factory(), 1); + } + } else { + _status = BAD_VALUE_TYPE; + } + } else { + _status = BAD_OBJECT_TYPE; + } + } + } + + if (_status != NOT_PREPARED) { + break; + } + + _types.push_back(op); + } + + return Event::pre_process_done(_status == NOT_PREPARED ? SUCCESS : _status); +} + +void +Delta::execute(ProcessContext& context) +{ + if (_status) { + return; + } + + const Ingen::Shared::URIs& uris = _engine.world()->uris(); + + if (_create_event) { + _create_event->set_time(_time); + _create_event->execute(context); + } + + for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) { + (*i)->set_time(_time); + (*i)->execute(context); + } + + GraphObjectImpl* const object = dynamic_cast(_object); + NodeImpl* const node = dynamic_cast(_object); + PortImpl* const port = dynamic_cast(_object); + + std::vector::const_iterator t = _types.begin(); + for (Properties::const_iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) { + const Raul::URI& key = p->first; + const Raul::Atom& value = p->second; + switch (*t) { + case ENABLE_BROADCAST: + if (port) { + port->broadcast(value.get_bool()); + } + break; + case ENABLE: + if (value.get_bool()) { + if (_compiled_patch) { + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); + } + _patch->enable(); + } else { + _patch->disable(context); + } + break; + case POLYPHONIC: { + PatchImpl* parent = reinterpret_cast(object->parent()); + if (value.get_bool()) { + object->apply_poly( + context, *_engine.maid(), parent->internal_poly_process()); + } else { + object->apply_poly(context, *_engine.maid(), 1); + } + } break; + case POLYPHONY: + if (!_patch->apply_internal_poly(context, + *_engine.buffer_factory(), + *_engine.maid(), + value.get_int32())) { + _status = INTERNAL_ERROR; + } + break; + case CONTROL_BINDING: + if (port) { + _engine.control_bindings()->port_binding_changed(context, port, value); + } else if (node) { + if (node->plugin_impl()->type() == Plugin::Internal) { + node->learn(); + } + } + break; + case NONE: + if (port) { + if (key == uris.lv2_minimum) { + port->set_minimum(value); + } else if (key == uris.lv2_maximum) { + port->set_maximum(value); + } + } + break; + } + } +} + +void +Delta::post_process() +{ + for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) + (*i)->post_process(); + + if (!_status) { + if (_create_event) { + _create_event->post_process(); + } else { + respond(SUCCESS); + if (_create) { + _engine.broadcaster()->put(_subject, _properties, _context); + } else { + _engine.broadcaster()->delta(_subject, _remove, _properties); + } + } + } else { + respond(_status); + } +} + +} // namespace Events +} // namespace Server +} // namespace Ingen + diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp new file mode 100644 index 00000000..935dcfac --- /dev/null +++ b/src/server/events/Delta.hpp @@ -0,0 +1,118 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_EVENTS_SETMETADATA_HPP +#define INGEN_EVENTS_SETMETADATA_HPP + +#include + +#include "raul/URI.hpp" + +#include "ControlBindings.hpp" +#include "Event.hpp" +#include "ingen/shared/ResourceImpl.hpp" + +namespace Ingen { +namespace Server { + +class GraphObjectImpl; +class PatchImpl; +class CompiledPatch; + +namespace Events { + +/** \page methods + *

POST

+ * As per HTTP (RFC2616 S9.5). + * + * Append properties to a graph object. + * + * An object can have several properties with a single predicate. + * POST appends properties without modifying or removing existing properties. + */ + +/** \page methods + *

PUT

+ * As per HTTP (RFC2616 S9.6). + * + * Set properties of a graph object, or create an object. + * + * An object can have several properties with a single predicate. + * \li If the object does not yet exist, the message must contain sufficient + * information to create the object (e.g. known rdf:type properties, etc.) + * \li If the object does exist, a PUT removes all existing object properties + * with predicates that match any property in the message, then adds all + * properties from the message. + */ + +class SetPortValue; + +/** Set properties of a graph object. + * \ingroup engine + */ +class Delta : public Event +{ +public: + Delta(Engine& engine, + Interface* client, + int32_t id, + SampleCount timestamp, + bool create, + Resource::Graph context, + const Raul::URI& subject, + const Resource::Properties& properties, + const Resource::Properties& remove = Resource::Properties()); + + ~Delta(); + + bool pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum SpecialType { + NONE, + ENABLE, + ENABLE_BROADCAST, + POLYPHONY, + POLYPHONIC, + CONTROL_BINDING + }; + + typedef std::vector SetEvents; + + Event* _create_event; + SetEvents _set_events; + std::vector _types; + std::vector _remove_types; + Raul::URI _subject; + Resource::Properties _properties; + Resource::Properties _remove; + Ingen::Shared::ResourceImpl* _object; + PatchImpl* _patch; + CompiledPatch* _compiled_patch; + bool _create; + Resource::Graph _context; + ControlBindings::Key _binding; + + SharedPtr _old_bindings; +}; + +} // namespace Events +} // namespace Server +} // namespace Ingen + +#endif // INGEN_EVENTS_SETMETADATA_HPP diff --git a/src/server/events/SetMetadata.cpp b/src/server/events/SetMetadata.cpp deleted file mode 100644 index cc2ae563..00000000 --- a/src/server/events/SetMetadata.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#include -#include - -#include - -#include - -#include "raul/log.hpp" -#include "raul/Maid.hpp" - -#include "ingen/shared/URIMap.hpp" -#include "ingen/shared/URIs.hpp" - -#include "Broadcaster.hpp" -#include "ControlBindings.hpp" -#include "CreateNode.hpp" -#include "CreatePatch.hpp" -#include "CreatePort.hpp" -#include "Driver.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "GraphObjectImpl.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "PortType.hpp" -#include "SetMetadata.hpp" -#include "SetPortValue.hpp" - -#define LOG(s) s << "[SetMetadata] " - -namespace Ingen { -namespace Server { -namespace Events { - -typedef Resource::Properties Properties; - -SetMetadata::SetMetadata(Engine& engine, - Interface* client, - int32_t id, - SampleCount timestamp, - bool create, - Resource::Graph context, - const Raul::URI& subject, - const Properties& properties, - const Properties& remove) - : Event(engine, client, id, timestamp) - , _create_event(NULL) - , _subject(subject) - , _properties(properties) - , _remove(remove) - , _object(NULL) - , _patch(NULL) - , _compiled_patch(NULL) - , _create(create) - , _context(context) -{ - if (context != Resource::DEFAULT) { - Resource::set_context(_properties, context); - } - - /* - LOG(Raul::info) << "Patch " << subject << " : " << context << " {" << std::endl; - typedef Resource::Properties::const_iterator iterator; - for (iterator i = properties.begin(); i != properties.end(); ++i) { - LOG(Raul::info) << " + " << i->first - << " = " << engine.world()->forge().str(i->second) - << " :: " << engine.world()->uri_map().unmap_uri(i->second.type()) << std::endl; - } - typedef Resource::Properties::const_iterator iterator; - for (iterator i = remove.begin(); i != remove.end(); ++i) { - LOG(Raul::info) << " - " << i->first - << " = " << engine.world()->forge().str(i->second) - << " :: " << engine.world()->uri_map().unmap_uri(i->second.type()) << std::endl; - } - LOG(Raul::info) << "}" << std::endl; - */ -} - -SetMetadata::~SetMetadata() -{ - for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) - delete *i; - - delete _create_event; -} - -bool -SetMetadata::pre_process() -{ - typedef Properties::const_iterator iterator; - - const bool is_graph_object = Raul::Path::is_path(_subject); - - // Take a writer lock while we modify the store - Glib::RWLock::WriterLock lock(_engine.engine_store()->lock()); - - _object = is_graph_object - ? _engine.engine_store()->find_object(Raul::Path(_subject.str())) - : static_cast(_engine.node_factory()->plugin(_subject)); - - if (!_object && (!is_graph_object || !_create)) { - return Event::pre_process_done(NOT_FOUND); - } - - const Ingen::Shared::URIs& uris = _engine.world()->uris(); - - if (is_graph_object && !_object) { - Raul::Path path(_subject.str()); - bool is_patch = false, is_node = false, is_port = false, is_output = false; - Shared::ResourceImpl::type(uris, _properties, is_patch, is_node, is_port, is_output); - - if (is_patch) { - _create_event = new CreatePatch( - _engine, _request_client, _request_id, _time, path, _properties); - } else if (is_node) { - _create_event = new CreateNode( - _engine, _request_client, _request_id, _time, path, _properties); - } else if (is_port) { - _create_event = new CreatePort( - _engine, _request_client, _request_id, _time, - path, is_output, _properties); - } - if (_create_event) { - _create_event->pre_process(); - // Grab the object for applying properties, if the create-event succeeded - _object = _engine.engine_store()->find_object(Raul::Path(_subject.str())); - } else { - return Event::pre_process_done(BAD_OBJECT_TYPE); - } - } - - _types.reserve(_properties.size()); - - GraphObjectImpl* obj = dynamic_cast(_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 - // existing properties should be replaced - if (_replace) - for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) - obj->properties().erase(p->first); -#endif - - for (Properties::const_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(_object); - if (port) - _old_bindings = _engine.control_bindings()->remove(port); - } - _object->remove_property(key, value); - } - - for (Properties::const_iterator p = _properties.begin(); p != _properties.end(); ++p) { - const Raul::URI& key = p->first; - const Resource::Property& value = p->second; - SpecialType op = NONE; - if (obj) { - Resource& resource = *obj; - resource.add_property(key, value, value.context()); - - PortImpl* port = dynamic_cast(_object); - if (port) { - if (key == uris.ingen_broadcast) { - if (value.type() == uris.forge.Bool) { - op = ENABLE_BROADCAST; - } else { - _status = BAD_VALUE_TYPE; - } - } else if (key == uris.ingen_value) { - SetPortValue* ev = new SetPortValue( - _engine, _request_client, _request_id, _time, port, value); - ev->pre_process(); - _set_events.push_back(ev); - } else if (key == uris.ingen_controlBinding) { - if (port->is_a(PortType::CONTROL) || port->is_a(PortType::CV)) { - if (value == uris.wildcard) { - _engine.control_bindings()->learn(port); - } else if (value.type() == uris.forge.Dict) { - op = CONTROL_BINDING; - } else { - _status = BAD_VALUE_TYPE; - } - } else { - _status = BAD_OBJECT_TYPE; - } - } - } else if ((_patch = dynamic_cast(_object))) { - if (key == uris.ingen_enabled) { - if (value.type() == uris.forge.Bool) { - op = ENABLE; - // FIXME: defer this until all other metadata has been processed - if (value.get_bool() && !_patch->enabled()) - _compiled_patch = _patch->compile(); - } else { - _status = BAD_VALUE_TYPE; - } - } else if (key == uris.ingen_polyphony) { - if (value.type() == uris.forge.Int) { - op = POLYPHONY; - _patch->prepare_internal_poly(*_engine.buffer_factory(), value.get_int32()); - } else { - _status = BAD_VALUE_TYPE; - } - } - } else if (key == uris.ingen_polyphonic) { - PatchImpl* parent = dynamic_cast(obj->parent()); - if (parent) { - if (value.type() == uris.forge.Bool) { - op = POLYPHONIC; - obj->set_property(key, value, value.context()); - NodeImpl* node = dynamic_cast(obj); - if (node) - node->set_polyphonic(value.get_bool()); - if (value.get_bool()) { - obj->prepare_poly(*_engine.buffer_factory(), parent->internal_poly()); - } else { - obj->prepare_poly(*_engine.buffer_factory(), 1); - } - } else { - _status = BAD_VALUE_TYPE; - } - } else { - _status = BAD_OBJECT_TYPE; - } - } - } - - if (_status != NOT_PREPARED) { - break; - } - - _types.push_back(op); - } - - return Event::pre_process_done(_status == NOT_PREPARED ? SUCCESS : _status); -} - -void -SetMetadata::execute(ProcessContext& context) -{ - if (_status) { - return; - } - - const Ingen::Shared::URIs& uris = _engine.world()->uris(); - - if (_create_event) { - _create_event->set_time(_time); - _create_event->execute(context); - } - - for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) { - (*i)->set_time(_time); - (*i)->execute(context); - } - - GraphObjectImpl* const object = dynamic_cast(_object); - NodeImpl* const node = dynamic_cast(_object); - PortImpl* const port = dynamic_cast(_object); - - std::vector::const_iterator t = _types.begin(); - for (Properties::const_iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) { - const Raul::URI& key = p->first; - const Raul::Atom& value = p->second; - switch (*t) { - case ENABLE_BROADCAST: - if (port) { - port->broadcast(value.get_bool()); - } - break; - case ENABLE: - if (value.get_bool()) { - if (_compiled_patch) { - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } - _patch->enable(); - } else { - _patch->disable(context); - } - break; - case POLYPHONIC: { - PatchImpl* parent = reinterpret_cast(object->parent()); - if (value.get_bool()) { - object->apply_poly( - context, *_engine.maid(), parent->internal_poly_process()); - } else { - object->apply_poly(context, *_engine.maid(), 1); - } - } break; - case POLYPHONY: - if (!_patch->apply_internal_poly(context, - *_engine.buffer_factory(), - *_engine.maid(), - value.get_int32())) { - _status = INTERNAL_ERROR; - } - break; - case CONTROL_BINDING: - if (port) { - _engine.control_bindings()->port_binding_changed(context, port, value); - } else if (node) { - if (node->plugin_impl()->type() == Plugin::Internal) { - node->learn(); - } - } - break; - case NONE: - if (port) { - if (key == uris.lv2_minimum) { - port->set_minimum(value); - } else if (key == uris.lv2_maximum) { - port->set_maximum(value); - } - } - break; - } - } -} - -void -SetMetadata::post_process() -{ - for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) - (*i)->post_process(); - - if (!_status) { - if (_create_event) { - _create_event->post_process(); - } else { - respond(SUCCESS); - if (_create) { - _engine.broadcaster()->put(_subject, _properties, _context); - } else { - _engine.broadcaster()->delta(_subject, _remove, _properties); - } - } - } else { - respond(_status); - } -} - -} // namespace Events -} // namespace Server -} // namespace Ingen - diff --git a/src/server/events/SetMetadata.hpp b/src/server/events/SetMetadata.hpp deleted file mode 100644 index 223339da..00000000 --- a/src/server/events/SetMetadata.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see . -*/ - -#ifndef INGEN_EVENTS_SETMETADATA_HPP -#define INGEN_EVENTS_SETMETADATA_HPP - -#include - -#include "raul/URI.hpp" - -#include "ControlBindings.hpp" -#include "Event.hpp" -#include "ingen/shared/ResourceImpl.hpp" - -namespace Ingen { -namespace Server { - -class GraphObjectImpl; -class PatchImpl; -class CompiledPatch; - -namespace Events { - -/** \page methods - *

POST

- * As per HTTP (RFC2616 S9.5). - * - * Append properties to a graph object. - * - * An object can have several properties with a single predicate. - * POST appends properties without modifying or removing existing properties. - */ - -/** \page methods - *

PUT

- * As per HTTP (RFC2616 S9.6). - * - * Set properties of a graph object, or create an object. - * - * An object can have several properties with a single predicate. - * \li If the object does not yet exist, the message must contain sufficient - * information to create the object (e.g. known rdf:type properties, etc.) - * \li If the object does exist, a PUT removes all existing object properties - * with predicates that match any property in the message, then adds all - * properties from the message. - */ - -class SetPortValue; - -/** Set properties of a graph object. - * \ingroup engine - */ -class SetMetadata : public Event -{ -public: - SetMetadata(Engine& engine, - Interface* client, - int32_t id, - SampleCount timestamp, - bool create, - Resource::Graph context, - const Raul::URI& subject, - const Resource::Properties& properties, - const Resource::Properties& remove = Resource::Properties()); - - ~SetMetadata(); - - bool pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum SpecialType { - NONE, - ENABLE, - ENABLE_BROADCAST, - POLYPHONY, - POLYPHONIC, - CONTROL_BINDING - }; - - typedef std::vector SetEvents; - - Event* _create_event; - SetEvents _set_events; - std::vector _types; - std::vector _remove_types; - Raul::URI _subject; - Resource::Properties _properties; - Resource::Properties _remove; - Ingen::Shared::ResourceImpl* _object; - PatchImpl* _patch; - CompiledPatch* _compiled_patch; - bool _create; - Resource::Graph _context; - ControlBindings::Key _binding; - - SharedPtr _old_bindings; -}; - -} // namespace Events -} // namespace Server -} // namespace Ingen - -#endif // INGEN_EVENTS_SETMETADATA_HPP diff --git a/src/server/wscript b/src/server/wscript index c1ea75e9..1d80b926 100644 --- a/src/server/wscript +++ b/src/server/wscript @@ -35,11 +35,11 @@ def build(bld): events/CreatePatch.cpp events/CreatePort.cpp events/Delete.cpp + events/Delta.cpp events/Disconnect.cpp events/DisconnectAll.cpp events/Get.cpp events/Move.cpp - events/SetMetadata.cpp events/SetPortValue.cpp ingen_engine.cpp internals/Controller.cpp -- cgit v1.2.1