summaryrefslogtreecommitdiffstats
path: root/src/engine/events
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-10-19 04:07:02 +0000
committerDavid Robillard <d@drobilla.net>2009-10-19 04:07:02 +0000
commita0108c19c4704316a02c85676af349acdda29d72 (patch)
treec971fe3fa385bd3abfb3d450f7f2b4e1a718ed60 /src/engine/events
parent78ebb57ba3268da3560aa596dfe14c515f617890 (diff)
downloadingen-a0108c19c4704316a02c85676af349acdda29d72.tar.gz
ingen-a0108c19c4704316a02c85676af349acdda29d72.tar.bz2
ingen-a0108c19c4704316a02c85676af349acdda29d72.zip
Fix set/PUT with multiple properties of the same predicate.
Actually set port value when PUT of ingen:value occurs (fix ticket #410). git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2198 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/events')
-rw-r--r--src/engine/events/SetMetadata.cpp42
-rw-r--r--src/engine/events/SetMetadata.hpp9
-rw-r--r--src/engine/events/SetPortValue.cpp34
-rw-r--r--src/engine/events/SetPortValue.hpp6
4 files changed, 77 insertions, 14 deletions
diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp
index e991bcf5..3d62781d 100644
--- a/src/engine/events/SetMetadata.cpp
+++ b/src/engine/events/SetMetadata.cpp
@@ -31,6 +31,7 @@
#include "QueuedEventSource.hpp"
#include "Responder.hpp"
#include "SetMetadata.hpp"
+#include "SetPortValue.hpp"
using namespace std;
using namespace Raul;
@@ -47,6 +48,7 @@ SetMetadata::SetMetadata(
SharedPtr<Responder> responder,
SampleCount timestamp,
QueuedEventSource* source,
+ bool replace,
bool meta,
const URI& subject,
const Properties& properties)
@@ -58,12 +60,20 @@ SetMetadata::SetMetadata(
, _object(NULL)
, _patch(NULL)
, _compiled_patch(NULL)
+ , _replace(replace)
, _is_meta(meta)
, _success(false)
{
}
+SetMetadata::~SetMetadata()
+{
+ for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i)
+ delete *i;
+}
+
+
void
SetMetadata::pre_process()
{
@@ -112,16 +122,23 @@ SetMetadata::pre_process()
_types.reserve(_properties.size());
+ GraphObjectImpl* obj = dynamic_cast<GraphObjectImpl*>(_object);
+
+ // 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);
+
for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) {
const Raul::URI& key = p->first;
const Raul::Atom& value = p->second;
- GraphObjectImpl* obj = dynamic_cast<GraphObjectImpl*>(_object);
SpecialType op = NONE;
if (obj) {
- if (_is_meta)
- obj->meta().set_property(key, value);
- else
- obj->set_property(key, value);
+ Resource& resource = _is_meta ? obj->meta() : *obj;
+ resource.add_property(key, value);
_patch = dynamic_cast<PatchImpl*>(_object);
@@ -150,6 +167,15 @@ SetMetadata::pre_process()
_error = BAD_TYPE;
}
}
+ } else if (key.str() == "ingen:value") {
+ PortImpl* port = dynamic_cast<PortImpl*>(_object);
+ if (port) {
+ SetPortValue* ev = new SetPortValue(_engine, _responder, _time, port, value);
+ ev->pre_process();
+ _set_events.push_back(ev);
+ } else {
+ cerr << "WARNING: Set value for non-port " << _object->uri() << endl;
+ }
}
}
@@ -179,6 +205,9 @@ SetMetadata::execute(ProcessContext& context)
return;
}
+ for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i)
+ (*i)->execute(context);
+
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;
@@ -219,6 +248,9 @@ SetMetadata::execute(ProcessContext& context)
void
SetMetadata::post_process()
{
+ for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i)
+ (*i)->post_process();
+
switch (_error) {
case NO_ERROR:
_responder->respond_ok();
diff --git a/src/engine/events/SetMetadata.hpp b/src/engine/events/SetMetadata.hpp
index 3fd3c904..cf33b5aa 100644
--- a/src/engine/events/SetMetadata.hpp
+++ b/src/engine/events/SetMetadata.hpp
@@ -57,6 +57,8 @@ namespace Events {
* properties from the message.
*/
+class SetPortValue;
+
/** Set properties of a graph object.
* \ingroup engine
*/
@@ -68,10 +70,13 @@ public:
SharedPtr<Responder> responder,
SampleCount timestamp,
QueuedEventSource* source,
+ bool replace,
bool meta,
const Raul::URI& subject,
const Shared::Resource::Properties& properties);
+ ~SetMetadata();
+
void pre_process();
void execute(ProcessContext& context);
void post_process();
@@ -86,13 +91,17 @@ private:
POLYPHONIC
};
+ typedef std::vector<SetPortValue*> SetEvents;
+
QueuedEvent* _create_event;
+ SetEvents _set_events;
std::vector<SpecialType> _types;
Raul::URI _subject;
Shared::Resource::Properties _properties;
Shared::ResourceImpl* _object;
PatchImpl* _patch;
CompiledPatch* _compiled_patch;
+ bool _replace;
bool _is_meta;
bool _success;
};
diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp
index ba906705..eacf172b 100644
--- a/src/engine/events/SetPortValue.cpp
+++ b/src/engine/events/SetPortValue.cpp
@@ -20,17 +20,17 @@
#include "shared/LV2URIMap.hpp"
#include "shared/LV2Features.hpp"
#include "module/World.hpp"
-#include "Responder.hpp"
-#include "SetPortValue.hpp"
-#include "Engine.hpp"
-#include "PortImpl.hpp"
+#include "AudioBuffer.hpp"
#include "ClientBroadcaster.hpp"
-#include "NodeImpl.hpp"
+#include "Engine.hpp"
#include "EngineStore.hpp"
-#include "AudioBuffer.hpp"
#include "EventBuffer.hpp"
-#include "ProcessContext.hpp"
#include "MessageContext.hpp"
+#include "NodeImpl.hpp"
+#include "PortImpl.hpp"
+#include "ProcessContext.hpp"
+#include "Responder.hpp"
+#include "SetPortValue.hpp"
using namespace std;
using namespace Raul;
@@ -53,7 +53,7 @@ SetPortValue::SetPortValue(Engine& engine,
, _omni(true)
, _voice_num(0)
, _port_path(port_path)
- , _value(value)
+ , _value(value)
, _port(NULL)
, _error(NO_ERROR)
{
@@ -73,12 +73,28 @@ SetPortValue::SetPortValue(Engine& engine,
, _omni(false)
, _voice_num(voice_num)
, _port_path(port_path)
- , _value(value)
+ , _value(value)
, _port(NULL)
, _error(NO_ERROR)
{
}
+/** Internal */
+SetPortValue::SetPortValue(Engine& engine,
+ SharedPtr<Responder> responder,
+ SampleCount timestamp,
+ PortImpl* port,
+ const Raul::Atom& value)
+ : QueuedEvent(engine, responder, timestamp)
+ , _queued(false)
+ , _omni(true)
+ , _voice_num(0)
+ , _port_path(port->path())
+ , _value(value)
+ , _port(port)
+ , _error(NO_ERROR)
+{
+}
SetPortValue::~SetPortValue()
{
diff --git a/src/engine/events/SetPortValue.hpp b/src/engine/events/SetPortValue.hpp
index 6d7c142b..87f4f6f6 100644
--- a/src/engine/events/SetPortValue.hpp
+++ b/src/engine/events/SetPortValue.hpp
@@ -56,6 +56,12 @@ public:
const Raul::Path& port_path,
const Raul::Atom& value);
+ SetPortValue(Engine& engine,
+ SharedPtr<Responder> responder,
+ SampleCount timestamp,
+ PortImpl* port,
+ const Raul::Atom& value);
+
~SetPortValue();
void pre_process();