summaryrefslogtreecommitdiffstats
path: root/src/libs/engine/events
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-09-18 06:24:53 +0000
committerDavid Robillard <d@drobilla.net>2006-09-18 06:24:53 +0000
commit6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979 (patch)
tree82b27a4802198215546558c006f7ac4228ab0599 /src/libs/engine/events
parentd520692eb49ff9e5aded38061a204713571b095b (diff)
downloadingen-6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979.tar.gz
ingen-6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979.tar.bz2
ingen-6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979.zip
Work on loading old (deprecated) patches.
More error tolerance in Store, related bugfixes. Patch port adding (threading) bug fixed (made event blocking). Better PatchView cacheing. Moved generic things from engine to util (shared) Bug fixes, features, etc. git-svn-id: http://svn.drobilla.net/lad/ingen@142 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/engine/events')
-rw-r--r--src/libs/engine/events/AddNodeEvent.cpp31
-rw-r--r--src/libs/engine/events/AddNodeEvent.h18
-rw-r--r--src/libs/engine/events/AddPortEvent.cpp31
-rw-r--r--src/libs/engine/events/AddPortEvent.h2
-rw-r--r--src/libs/engine/events/CreatePatchEvent.cpp8
-rw-r--r--src/libs/engine/events/Makefile.am4
-rw-r--r--src/libs/engine/events/RequestAllObjectsEvent.cpp2
-rw-r--r--src/libs/engine/events/RequestObjectEvent.cpp97
-rw-r--r--src/libs/engine/events/RequestObjectEvent.h55
-rw-r--r--src/libs/engine/events/RequestPluginEvent.cpp78
-rw-r--r--src/libs/engine/events/RequestPluginEvent.h55
11 files changed, 353 insertions, 28 deletions
diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp
index 6e42ef82..1a317e39 100644
--- a/src/libs/engine/events/AddNodeEvent.cpp
+++ b/src/libs/engine/events/AddNodeEvent.cpp
@@ -33,23 +33,31 @@
namespace Ingen {
-/*AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly)
+AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path,
+ const string& plugin_uri, bool poly)
: QueuedEvent(engine, responder, timestamp),
m_path(path),
- m_plugin(plugin),
+ m_plugin_uri(plugin_uri),
m_poly(poly),
m_patch(NULL),
m_node(NULL),
m_process_order(NULL),
m_node_already_exists(false)
{
-}*/
+}
+
+/** DEPRECATED: Construct from type, library name, and plugin label.
+ *
+ * Do not use.
+ */
AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path,
- const string& plugin_uri, bool poly)
+ const string& plugin_type, const string& plugin_lib, const string& plugin_label, bool poly)
: QueuedEvent(engine, responder, timestamp),
m_path(path),
- m_plugin_uri(plugin_uri),
+ m_plugin_type(plugin_type),
+ m_plugin_lib(plugin_lib),
+ m_plugin_label(plugin_label),
m_poly(poly),
m_patch(NULL),
m_node(NULL),
@@ -59,11 +67,6 @@ AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, Samp
}
-AddNodeEvent::~AddNodeEvent()
-{
-}
-
-
void
AddNodeEvent::pre_process()
{
@@ -74,7 +77,10 @@ AddNodeEvent::pre_process()
}
m_patch = _engine.object_store()->find_patch(m_path.parent());
- const Plugin* plugin = _engine.node_factory()->plugin(m_plugin_uri);
+
+ const Plugin* plugin = (m_plugin_uri != "")
+ ? _engine.node_factory()->plugin(m_plugin_uri)
+ : _engine.node_factory()->plugin(m_plugin_type, m_plugin_lib, m_plugin_label);
if (m_patch && plugin) {
if (m_poly)
@@ -130,8 +136,7 @@ AddNodeEvent::post_process()
_responder->respond_error(msg);
} else {
_responder->respond_ok();
- //_engine.broadcaster()->send_node_creation_messages(m_node);
- _engine.broadcaster()->send_node(m_node);
+ _engine.broadcaster()->send_node(m_node, true); // yes, send ports
}
}
diff --git a/src/libs/engine/events/AddNodeEvent.h b/src/libs/engine/events/AddNodeEvent.h
index b4345f90..22e164ea 100644
--- a/src/libs/engine/events/AddNodeEvent.h
+++ b/src/libs/engine/events/AddNodeEvent.h
@@ -39,15 +39,22 @@ class Plugin;
class AddNodeEvent : public QueuedEvent
{
public:
- //AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly);
AddNodeEvent(Engine& engine,
CountedPtr<Responder> responder,
SampleCount timestamp,
const string& node_path,
const string& plugin_uri,
bool poly);
-
- ~AddNodeEvent();
+
+ // DEPRECATED
+ AddNodeEvent(Engine& engine,
+ CountedPtr<Responder> responder,
+ SampleCount timestamp,
+ const string& node_path,
+ const string& plugin_type,
+ const string& lib_name,
+ const string& plugin_label,
+ bool poly);
void pre_process();
void execute(SampleCount nframes, FrameTime start, FrameTime end);
@@ -56,7 +63,10 @@ public:
private:
string m_patch_name;
Path m_path;
- string m_plugin_uri;
+ string m_plugin_uri; ///< If nonempty then type, library, label, are ignored
+ string m_plugin_type;
+ string m_plugin_lib;
+ string m_plugin_label;
bool m_poly;
Patch* m_patch;
Node* m_node;
diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp
index 06ddae94..ae692b1b 100644
--- a/src/libs/engine/events/AddPortEvent.cpp
+++ b/src/libs/engine/events/AddPortEvent.cpp
@@ -23,6 +23,7 @@
#include "Patch.h"
#include "Maid.h"
#include "util/Path.h"
+#include "QueuedEventSource.h"
#include "ObjectStore.h"
#include "ClientBroadcaster.h"
#include "util/Path.h"
@@ -32,12 +33,13 @@
#include "List.h"
#include "Driver.h"
#include "DuplexPort.h"
+#include "Array.h"
namespace Ingen {
-AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output)
-: QueuedEvent(engine, responder, timestamp),
+AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source)
+: QueuedEvent(engine, responder, timestamp, true, source),
_path(path),
_type(type),
_is_output(is_output),
@@ -46,6 +48,14 @@ AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, Samp
_patch_port(NULL),
_driver_port(NULL)
{
+ /* This is blocking because of the two different sets of Patch ports, the array used in the
+ * audio thread (inherited from NodeBase), and the arrays used in the pre processor thread.
+ * If two add port events arrive in the same cycle and the second pre processes before the
+ * first executes, bad things happen (ports are lost).
+ *
+ * FIXME: fix this using RCU
+ */
+
string type_str;
if (type == "CONTROL" || type == "AUDIO")
_data_type = DataType::FLOAT;
@@ -73,17 +83,22 @@ AddPortEvent::pre_process()
if (_type == "AUDIO" || _type == "MIDI")
buffer_size = _engine.audio_driver()->buffer_size();
+ const size_t old_num_ports = _patch->num_ports();
+
_patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output);
+
if (_patch_port) {
+
if (_is_output)
_patch->add_output(new ListNode<Port*>(_patch_port));
else
_patch->add_input(new ListNode<Port*>(_patch_port));
if (_patch->external_ports())
- _ports_array = new Array<Port*>(_patch->num_ports() + 1, *_patch->external_ports());
+ _ports_array = new Array<Port*>(old_num_ports + 1, *_patch->external_ports());
else
- _ports_array = new Array<Port*>(_patch->num_ports() + 1, NULL);
+ _ports_array = new Array<Port*>(old_num_ports + 1, NULL);
+
_ports_array->at(_patch->num_ports()) = _patch_port;
_engine.object_store()->add(_patch_port);
@@ -96,6 +111,9 @@ AddPortEvent::pre_process()
_driver_port = _engine.midi_driver()->create_port(
dynamic_cast<DuplexPort<MidiMessage>*>(_patch_port));
}
+
+ assert(_patch->num_ports() == old_num_ports);
+ assert(_ports_array->size() == _patch->num_ports() + 1);
}
}
QueuedEvent::pre_process();
@@ -108,8 +126,10 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
QueuedEvent::execute(nframes, start, end);
if (_patch_port) {
+
_engine.maid()->push(_patch->external_ports());
//_patch->add_port(_port);
+
_patch->external_ports(_ports_array);
}
@@ -121,6 +141,9 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
void
AddPortEvent::post_process()
{
+ if (_source)
+ _source->unblock();
+
if (!_patch_port) {
const string msg = string("Could not create port - ").append(_path);
_responder->respond_error(msg);
diff --git a/src/libs/engine/events/AddPortEvent.h b/src/libs/engine/events/AddPortEvent.h
index 070d07df..0ef33515 100644
--- a/src/libs/engine/events/AddPortEvent.h
+++ b/src/libs/engine/events/AddPortEvent.h
@@ -41,7 +41,7 @@ class DriverPort;
class AddPortEvent : public QueuedEvent
{
public:
- AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output);
+ AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source);
void pre_process();
void execute(SampleCount nframes, FrameTime start, FrameTime end);
diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp
index 7532291b..97be5557 100644
--- a/src/libs/engine/events/CreatePatchEvent.cpp
+++ b/src/libs/engine/events/CreatePatchEvent.cpp
@@ -120,11 +120,9 @@ CreatePatchEvent::post_process()
_responder->respond_ok();
- // Don't want to send nodes that have been added since prepare()
- //_engine.broadcaster()->send_node_creation_messages(m_patch);
-
- // Patches are always empty on creation, so this is fine
- _engine.broadcaster()->send_patch(m_patch);
+ // Don't send ports/nodes that have been added since prepare()
+ // (otherwise they would be sent twice)
+ _engine.broadcaster()->send_patch(m_patch, false);
} else if (m_error == OBJECT_EXISTS) {
string msg = "Unable to create patch: ";
diff --git a/src/libs/engine/events/Makefile.am b/src/libs/engine/events/Makefile.am
index 5b29e12b..a1760738 100644
--- a/src/libs/engine/events/Makefile.am
+++ b/src/libs/engine/events/Makefile.am
@@ -36,6 +36,10 @@ EXTRA_DIST = \
events/SetMetadataEvent.cpp \
events/RequestMetadataEvent.h \
events/RequestMetadataEvent.cpp \
+ events/RequestPluginEvent.h \
+ events/RequestPluginEvent.cpp \
+ events/RequestObjectEvent.h \
+ events/RequestObjectEvent.cpp \
events/RequestPortValueEvent.h \
events/RequestPortValueEvent.cpp \
events/RequestAllObjectsEvent.h \
diff --git a/src/libs/engine/events/RequestAllObjectsEvent.cpp b/src/libs/engine/events/RequestAllObjectsEvent.cpp
index f51a514e..893aa5df 100644
--- a/src/libs/engine/events/RequestAllObjectsEvent.cpp
+++ b/src/libs/engine/events/RequestAllObjectsEvent.cpp
@@ -48,7 +48,7 @@ RequestAllObjectsEvent::post_process()
// Everything is a child of the root patch, so this sends it all
Patch* root = _engine.object_store()->find_patch("/");
if (root)
- ObjectSender::send_patch(m_client.get(), root);
+ ObjectSender::send_patch(m_client.get(), root, true);
} else {
_responder->respond_error("Unable to find client to send all objects");
diff --git a/src/libs/engine/events/RequestObjectEvent.cpp b/src/libs/engine/events/RequestObjectEvent.cpp
new file mode 100644
index 00000000..3b0dc6fd
--- /dev/null
+++ b/src/libs/engine/events/RequestObjectEvent.cpp
@@ -0,0 +1,97 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * 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 "RequestObjectEvent.h"
+#include <string>
+#include "Responder.h"
+#include "Engine.h"
+#include "interface/ClientInterface.h"
+#include "TypedPort.h"
+#include "ObjectStore.h"
+#include "ClientBroadcaster.h"
+#include "Patch.h"
+#include "Node.h"
+#include "ObjectSender.h"
+
+using std::string;
+
+namespace Ingen {
+
+
+RequestObjectEvent::RequestObjectEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path)
+: QueuedEvent(engine, responder, timestamp),
+ m_path(path),
+ m_object(NULL)
+{
+}
+
+
+void
+RequestObjectEvent::pre_process()
+{
+ m_client = _engine.broadcaster()->client(_responder->client_key());
+ m_object = _engine.object_store()->find(m_path);
+
+ QueuedEvent::pre_process();
+}
+
+
+void
+RequestObjectEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
+{
+ QueuedEvent::execute(nframes, start, end);
+ assert(_time >= start && _time <= end);
+}
+
+
+void
+RequestObjectEvent::post_process()
+{
+ if (!m_object) {
+ _responder->respond_error("Unable to find object requested.");
+
+ } else if (m_client) {
+ Patch* const patch = dynamic_cast<Patch*>(m_object);
+ if (patch) {
+ _responder->respond_ok();
+ ObjectSender::send_patch(m_client.get(), patch, true);
+ return;
+ }
+
+ Node* const node = dynamic_cast<Node*>(m_object);
+ if (node) {
+ _responder->respond_ok();
+ ObjectSender::send_node(m_client.get(), node, true);
+ return;
+ }
+
+ Port* const port = dynamic_cast<Port*>(m_object);
+ if (port) {
+ _responder->respond_ok();
+ ObjectSender::send_port(m_client.get(), port);
+ return;
+ }
+
+ _responder->respond_error("Object of unknown type requested.");
+
+ } else {
+ _responder->respond_error("Unable to find client to send object.");
+ }
+}
+
+
+} // namespace Ingen
+
diff --git a/src/libs/engine/events/RequestObjectEvent.h b/src/libs/engine/events/RequestObjectEvent.h
new file mode 100644
index 00000000..276b60fa
--- /dev/null
+++ b/src/libs/engine/events/RequestObjectEvent.h
@@ -0,0 +1,55 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * 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 REQUESTOBJECTEVENT_H
+#define REQUESTOBJECTEVENT_H
+
+#include <string>
+#include "QueuedEvent.h"
+#include "types.h"
+
+using std::string;
+
+namespace Ingen {
+
+class GraphObject;
+namespace Shared { class ClientInterface; }
+using Shared::ClientInterface;
+
+
+/** A request from a client to send the value of a port.
+ *
+ * \ingroup engine
+ */
+class RequestObjectEvent : public QueuedEvent
+{
+public:
+ RequestObjectEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path);
+
+ void pre_process();
+ void execute(SampleCount nframes, FrameTime start, FrameTime end);
+ void post_process();
+
+private:
+ string m_path;
+ GraphObject* m_object;
+ CountedPtr<ClientInterface> m_client;
+};
+
+
+} // namespace Ingen
+
+#endif // REQUESTOBJECTEVENT_H
diff --git a/src/libs/engine/events/RequestPluginEvent.cpp b/src/libs/engine/events/RequestPluginEvent.cpp
new file mode 100644
index 00000000..95141226
--- /dev/null
+++ b/src/libs/engine/events/RequestPluginEvent.cpp
@@ -0,0 +1,78 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * 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 "RequestPluginEvent.h"
+#include <string>
+#include "Responder.h"
+#include "Engine.h"
+#include "interface/ClientInterface.h"
+#include "TypedPort.h"
+#include "ObjectStore.h"
+#include "ClientBroadcaster.h"
+#include "NodeFactory.h"
+#include "Plugin.h"
+
+using std::string;
+
+namespace Ingen {
+
+
+RequestPluginEvent::RequestPluginEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& uri)
+: QueuedEvent(engine, responder, timestamp),
+ m_uri(uri),
+ m_plugin(NULL)
+{
+}
+
+
+void
+RequestPluginEvent::pre_process()
+{
+ m_client = _engine.broadcaster()->client(_responder->client_key());
+ m_plugin = _engine.node_factory()->plugin(m_uri);
+
+ QueuedEvent::pre_process();
+}
+
+
+void
+RequestPluginEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
+{
+ QueuedEvent::execute(nframes, start, end);
+ assert(_time >= start && _time <= end);
+}
+
+
+void
+RequestPluginEvent::post_process()
+{
+ if (!m_plugin) {
+ _responder->respond_error("Unable to find plugin requested.");
+
+ } else if (m_client) {
+
+ _responder->respond_ok();
+ assert(m_plugin->uri() == m_uri);
+ m_client->new_plugin(m_uri, m_plugin->name());
+
+ } else {
+ _responder->respond_error("Unable to find client to send plugin.");
+ }
+}
+
+
+} // namespace Ingen
+
diff --git a/src/libs/engine/events/RequestPluginEvent.h b/src/libs/engine/events/RequestPluginEvent.h
new file mode 100644
index 00000000..1c12c78e
--- /dev/null
+++ b/src/libs/engine/events/RequestPluginEvent.h
@@ -0,0 +1,55 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * 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 REQUESTPLUGINEVENT_H
+#define REQUESTPLUGINEVENT_H
+
+#include <string>
+#include "QueuedEvent.h"
+#include "types.h"
+
+using std::string;
+
+namespace Ingen {
+
+class Plugin;
+namespace Shared { class ClientInterface; }
+using Shared::ClientInterface;
+
+
+/** A request from a client to send the value of a port.
+ *
+ * \ingroup engine
+ */
+class RequestPluginEvent : public QueuedEvent
+{
+public:
+ RequestPluginEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& uri);
+
+ void pre_process();
+ void execute(SampleCount nframes, FrameTime start, FrameTime end);
+ void post_process();
+
+private:
+ string m_uri;
+ const Plugin* m_plugin;
+ CountedPtr<ClientInterface> m_client;
+};
+
+
+} // namespace Ingen
+
+#endif // REQUESTPLUGINEVENT_H