summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ingen/ingen.h8
-rw-r--r--src/server/Engine.cpp8
-rw-r--r--src/server/Event.hpp3
-rw-r--r--src/server/GraphImpl.cpp9
-rw-r--r--src/server/GraphImpl.hpp7
-rw-r--r--src/server/PostProcessor.cpp2
-rw-r--r--src/server/PreProcessContext.hpp70
-rw-r--r--src/server/PreProcessor.cpp14
-rw-r--r--src/server/events/Connect.cpp11
-rw-r--r--src/server/events/Connect.hpp2
-rw-r--r--src/server/events/Copy.cpp23
-rw-r--r--src/server/events/Copy.hpp8
-rw-r--r--src/server/events/CreateBlock.cpp10
-rw-r--r--src/server/events/CreateBlock.hpp2
-rw-r--r--src/server/events/CreateGraph.cpp13
-rw-r--r--src/server/events/CreateGraph.hpp2
-rw-r--r--src/server/events/CreatePort.cpp2
-rw-r--r--src/server/events/CreatePort.hpp2
-rw-r--r--src/server/events/Delete.cpp21
-rw-r--r--src/server/events/Delete.hpp2
-rw-r--r--src/server/events/Delta.cpp13
-rw-r--r--src/server/events/Delta.hpp2
-rw-r--r--src/server/events/Disconnect.cpp11
-rw-r--r--src/server/events/Disconnect.hpp2
-rw-r--r--src/server/events/DisconnectAll.cpp11
-rw-r--r--src/server/events/DisconnectAll.hpp2
-rw-r--r--src/server/events/Get.cpp2
-rw-r--r--src/server/events/Get.hpp2
-rw-r--r--src/server/events/Mark.cpp27
-rw-r--r--src/server/events/Mark.hpp11
-rw-r--r--src/server/events/Move.cpp2
-rw-r--r--src/server/events/Move.hpp2
-rw-r--r--src/server/events/SetPortValue.cpp2
-rw-r--r--src/server/events/SetPortValue.hpp2
-rw-r--r--src/server/events/Undo.cpp2
-rw-r--r--src/server/events/Undo.hpp2
36 files changed, 233 insertions, 81 deletions
diff --git a/ingen/ingen.h b/ingen/ingen.h
index e4a36ade..11fd592a 100644
--- a/ingen/ingen.h
+++ b/ingen/ingen.h
@@ -34,6 +34,14 @@
# define INGEN_API
#endif
+#ifndef INGEN_WARN_UNUSED_RESULT
+# if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4
+# define INGEN_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+# else
+# define INGEN_WARN_UNUSED_RESULT
+# endif
+#endif
+
#define INGEN_NS "http://drobilla.net/ns/ingen#"
#define INGEN__Arc INGEN_NS "Arc"
diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp
index 893f6f92..0b468ce1 100644
--- a/src/server/Engine.cpp
+++ b/src/server/Engine.cpp
@@ -47,6 +47,7 @@
#include "GraphImpl.hpp"
#include "LV2Options.hpp"
#include "PostProcessor.hpp"
+#include "PreProcessContext.hpp"
#include "PreProcessor.hpp"
#include "RunContext.hpp"
#include "ThreadManager.hpp"
@@ -374,9 +375,10 @@ Engine::activate()
*this, SPtr<Interface>(), -1, 0, Raul::Path("/"), graph_properties);
// Execute in "fake" process context (we are single threaded)
- RunContext context(run_context());
- ev.pre_process();
- ev.execute(context);
+ PreProcessContext pctx;
+ RunContext rctx(run_context());
+ ev.pre_process(pctx);
+ ev.execute(rctx);
ev.post_process();
_root_graph = ev.graph();
diff --git a/src/server/Event.hpp b/src/server/Event.hpp
index 8ed25c0f..203e5d1d 100644
--- a/src/server/Event.hpp
+++ b/src/server/Event.hpp
@@ -35,6 +35,7 @@ namespace Server {
class Engine;
class RunContext;
+class PreProcessContext;
/** An event (command) to perform some action on Ingen.
*
@@ -60,7 +61,7 @@ public:
enum class Execution { NORMAL, BLOCK, UNBLOCK };
/** Pre-process event before execution (non-realtime). */
- virtual bool pre_process() = 0;
+ virtual bool pre_process(PreProcessContext& ctx) = 0;
/** Execute this event in the audio thread (realtime). */
virtual void execute(RunContext& context) = 0;
diff --git a/src/server/GraphImpl.cpp b/src/server/GraphImpl.cpp
index bdd0a69a..c1ee6a2b 100644
--- a/src/server/GraphImpl.cpp
+++ b/src/server/GraphImpl.cpp
@@ -297,14 +297,15 @@ GraphImpl::has_arc(const PortImpl* tail, const PortImpl* dst_port) const
return (i != _arcs.end());
}
-void
-GraphImpl::set_compiled_graph(CompiledGraph* cg)
+CompiledGraph*
+GraphImpl::swap_compiled_graph(CompiledGraph* cg)
{
- if (_compiled_graph && _compiled_graph != cg) {
- _engine.maid()->dispose(_compiled_graph);
+ CompiledGraph* const old = _compiled_graph;
+ if (old && cg != old) {
_engine.reset_load();
}
_compiled_graph = cg;
+ return old;
}
uint32_t
diff --git a/src/server/GraphImpl.hpp b/src/server/GraphImpl.hpp
index 124614de..f7d0be32 100644
--- a/src/server/GraphImpl.hpp
+++ b/src/server/GraphImpl.hpp
@@ -19,6 +19,8 @@
#include <cstdlib>
+#include "ingen/ingen.h"
+
#include "BlockImpl.hpp"
#include "CompiledGraph.hpp"
#include "DuplexPort.hpp"
@@ -160,7 +162,8 @@ public:
bool has_arc(const PortImpl* tail, const PortImpl* head) const;
- void set_compiled_graph(CompiledGraph* cp);
+ /** Set a new compiled graph to run, and return the old one. */
+ CompiledGraph* swap_compiled_graph(CompiledGraph* cp) INGEN_WARN_UNUSED_RESULT;
Raul::Array<PortImpl*>* external_ports() { return _ports; }
void external_ports(Raul::Array<PortImpl*>* pa) { _ports = pa; }
@@ -185,7 +188,7 @@ private:
Ports _inputs; ///< Pre-process thread only
Ports _outputs; ///< Pre-process thread only
Blocks _blocks; ///< Pre-process thread only
- bool _process;
+ bool _process; ///< True iff graph is enabled
};
} // namespace Server
diff --git a/src/server/PostProcessor.cpp b/src/server/PostProcessor.cpp
index 65323f7f..6c709518 100644
--- a/src/server/PostProcessor.cpp
+++ b/src/server/PostProcessor.cpp
@@ -30,7 +30,7 @@ class Sentinel : public Event {
public:
Sentinel(Engine& engine) : Event(engine) {}
- bool pre_process() { return false; }
+ bool pre_process(PreProcessContext& ctx) { return false; }
void execute(RunContext& context) {}
void post_process() {}
};
diff --git a/src/server/PreProcessContext.hpp b/src/server/PreProcessContext.hpp
new file mode 100644
index 00000000..bf1115e8
--- /dev/null
+++ b/src/server/PreProcessContext.hpp
@@ -0,0 +1,70 @@
+/*
+ This file is part of Ingen.
+ Copyright 2007-2016 David Robillard <http://drobilla.net/>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef INGEN_ENGINE_PREPROCESSCONTEXT_HPP
+#define INGEN_ENGINE_PREPROCESSCONTEXT_HPP
+
+#include <unordered_set>
+
+#include "GraphImpl.hpp"
+
+namespace Ingen {
+namespace Server {
+
+/** Event pre-processing context.
+ *
+ * \ingroup engine
+ */
+class PreProcessContext
+{
+public:
+ typedef std::unordered_set<GraphImpl*> DirtyGraphs;
+
+ /** Return true iff an atomic bundle is currently being pre-processed. */
+ bool in_bundle() const { return _in_bundle; }
+
+ /** Set/unset atomic bundle flag. */
+ void set_in_bundle(bool b) { _in_bundle = b; }
+
+ /** Return true iff graph should be compiled now (after a change).
+ *
+ * This may return false when an atomic bundle is deferring compilation, in
+ * which case the graph is flagged as dirty for later compilation.
+ */
+ bool must_compile(GraphImpl* graph) {
+ if (!graph->enabled()) {
+ return false;
+ } else if (_in_bundle) {
+ _dirty_graphs.insert(graph);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /** Return all graphs that require compilation after an atomic bundle. */
+ const DirtyGraphs& dirty_graphs() const { return _dirty_graphs; }
+ DirtyGraphs& dirty_graphs() { return _dirty_graphs; }
+
+private:
+ DirtyGraphs _dirty_graphs;
+ bool _in_bundle = false;
+};
+
+} // namespace Server
+} // namespace Ingen
+
+#endif // INGEN_ENGINE_PREPROCESSCONTEXT_HPP
diff --git a/src/server/PreProcessor.cpp b/src/server/PreProcessor.cpp
index f0008afc..9933bde2 100644
--- a/src/server/PreProcessor.cpp
+++ b/src/server/PreProcessor.cpp
@@ -18,10 +18,12 @@
#include "ingen/AtomSink.hpp"
#include "ingen/AtomWriter.hpp"
+#include "ingen/Configuration.hpp"
#include "Engine.hpp"
#include "Event.hpp"
#include "PostProcessor.hpp"
+#include "PreProcessContext.hpp"
#include "PreProcessor.hpp"
#include "RunContext.hpp"
#include "ThreadManager.hpp"
@@ -131,6 +133,14 @@ PreProcessor::process(RunContext& context, PostProcessor& dest, size_t limit)
}
if (n_processed > 0) {
+ Engine& engine = context.engine();
+ if (engine.world()->conf().option("trace").get<int32_t>()) {
+ const uint64_t start = engine.cycle_start_time(context);
+ const uint64_t end = engine.current_time(context);
+ fprintf(stderr, "Processed %zu events in %zu us\n",
+ n_processed, end - start);
+ }
+
Event* next = (Event*)last->next();
last->next(NULL);
dest.append(context, head, last);
@@ -149,6 +159,8 @@ PreProcessor::process(RunContext& context, PostProcessor& dest, size_t limit)
void
PreProcessor::run()
{
+ PreProcessContext ctx;
+
UndoStack& undo_stack = *_engine.undo_stack();
UndoStack& redo_stack = *_engine.redo_stack();
AtomWriter undo_writer(
@@ -168,7 +180,7 @@ PreProcessor::run()
}
assert(!ev->is_prepared());
- if (ev->pre_process()) {
+ if (ev->pre_process(ctx)) {
switch (ev->get_mode()) {
case Event::Mode::NORMAL:
case Event::Mode::REDO:
diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp
index 17fa640f..35084ea6 100644
--- a/src/server/events/Connect.cpp
+++ b/src/server/events/Connect.cpp
@@ -26,8 +26,9 @@
#include "InputPort.hpp"
#include "OutputPort.hpp"
#include "PortImpl.hpp"
-#include "types.hpp"
+#include "PreProcessContext.hpp"
#include "internals/BlockDelay.hpp"
+#include "types.hpp"
namespace Ingen {
namespace Server {
@@ -49,7 +50,7 @@ Connect::Connect(Engine& engine,
{}
bool
-Connect::pre_process()
+Connect::pre_process(PreProcessContext& ctx)
{
std::lock_guard<std::mutex> lock(_engine.store()->mutex());
@@ -125,7 +126,7 @@ Connect::pre_process()
tail_block->dependants().insert(head_block);
}
- if (_graph->enabled()) {
+ if (ctx.must_compile(_graph)) {
if (!(_compiled_graph = CompiledGraph::compile(_graph))) {
head_block->providers().erase(tail_block);
tail_block->dependants().erase(head_block);
@@ -161,7 +162,7 @@ Connect::execute(RunContext& context)
}
_head->connect_buffers();
if (_compiled_graph) {
- _graph->set_compiled_graph(_compiled_graph);
+ _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
}
}
}
@@ -181,6 +182,8 @@ Connect::post_process()
Node::path_to_uri(_tail_path), _tail_remove, _tail_add);
}
}
+
+ delete _compiled_graph;
}
void
diff --git a/src/server/events/Connect.hpp b/src/server/events/Connect.hpp
index 84b2854b..9b98b167 100644
--- a/src/server/events/Connect.hpp
+++ b/src/server/events/Connect.hpp
@@ -52,7 +52,7 @@ public:
const Raul::Path& tail,
const Raul::Path& head);
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/Copy.cpp b/src/server/events/Copy.cpp
index 8959e4e1..03519610 100644
--- a/src/server/events/Copy.cpp
+++ b/src/server/events/Copy.cpp
@@ -26,6 +26,7 @@
#include "Engine.hpp"
#include "EnginePort.hpp"
#include "GraphImpl.hpp"
+#include "PreProcessContext.hpp"
#include "events/Copy.hpp"
namespace Ingen {
@@ -48,7 +49,7 @@ Copy::Copy(Engine& engine,
{}
bool
-Copy::pre_process()
+Copy::pre_process(PreProcessContext& ctx)
{
std::lock_guard<std::mutex> lock(_engine.store()->mutex());
@@ -69,16 +70,16 @@ Copy::pre_process()
if (Node::uri_is_path(_new_uri)) {
// Copy to path within the engine
- return engine_to_engine();
+ return engine_to_engine(ctx);
} else if (_new_uri.scheme() == "file") {
// Copy to filesystem path (i.e. save)
- return engine_to_filesystem();
+ return engine_to_filesystem(ctx);
} else {
return Event::pre_process_done(Status::BAD_REQUEST);
}
} else if (_old_uri.scheme() == "file") {
if (Node::uri_is_path(_new_uri)) {
- filesystem_to_engine();
+ filesystem_to_engine(ctx);
} else {
// Ingen is not your file manager
return Event::pre_process_done(Status::BAD_REQUEST);
@@ -89,7 +90,7 @@ Copy::pre_process()
}
bool
-Copy::engine_to_engine()
+Copy::engine_to_engine(PreProcessContext& ctx)
{
// Only support a single source for now
const Raul::Path new_path = Node::uri_to_path(_new_uri);
@@ -125,7 +126,7 @@ Copy::engine_to_engine()
_engine.store()->add(_block);
// Compile graph with new block added for insertion in audio thread
- if (_parent->enabled()) {
+ if (ctx.must_compile(_parent)) {
_compiled_graph = CompiledGraph::compile(_parent);
}
@@ -142,7 +143,7 @@ ends_with(const std::string& str, const std::string& end)
}
bool
-Copy::engine_to_filesystem()
+Copy::engine_to_filesystem(PreProcessContext& ctx)
{
// Ensure source is a graph
SPtr<GraphImpl> graph = dynamic_ptr_cast<GraphImpl>(_old_block);
@@ -168,7 +169,7 @@ Copy::engine_to_filesystem()
}
bool
-Copy::filesystem_to_engine()
+Copy::filesystem_to_engine(PreProcessContext& ctx)
{
if (!_engine.world()->parser()) {
return Event::pre_process_done(Status::INTERNAL_ERROR);
@@ -196,9 +197,8 @@ Copy::filesystem_to_engine()
void
Copy::execute(RunContext& context)
{
- if (_block) {
- _parent->set_compiled_graph(_compiled_graph);
- _compiled_graph = NULL; // Graph takes ownership
+ if (_block && _compiled_graph) {
+ _compiled_graph = _parent->swap_compiled_graph(_compiled_graph);
}
}
@@ -209,6 +209,7 @@ Copy::post_process()
if (respond() == Status::SUCCESS) {
_engine.broadcaster()->copy(_old_uri, _new_uri);
}
+ delete _compiled_graph;
}
void
diff --git a/src/server/events/Copy.hpp b/src/server/events/Copy.hpp
index 68ee31da..55310757 100644
--- a/src/server/events/Copy.hpp
+++ b/src/server/events/Copy.hpp
@@ -46,15 +46,15 @@ public:
const Raul::URI& old_uri,
const Raul::URI& new_uri);
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
private:
- bool engine_to_engine();
- bool engine_to_filesystem();
- bool filesystem_to_engine();
+ bool engine_to_engine(PreProcessContext& ctx);
+ bool engine_to_filesystem(PreProcessContext& ctx);
+ bool filesystem_to_engine(PreProcessContext& ctx);
const Raul::URI _old_uri;
const Raul::URI _new_uri;
diff --git a/src/server/events/CreateBlock.cpp b/src/server/events/CreateBlock.cpp
index d1060fa4..231df4e2 100644
--- a/src/server/events/CreateBlock.cpp
+++ b/src/server/events/CreateBlock.cpp
@@ -28,6 +28,7 @@
#include "GraphImpl.hpp"
#include "PluginImpl.hpp"
#include "PortImpl.hpp"
+#include "PreProcessContext.hpp"
namespace Ingen {
namespace Server {
@@ -53,7 +54,7 @@ CreateBlock::~CreateBlock()
}
bool
-CreateBlock::pre_process()
+CreateBlock::pre_process(PreProcessContext& ctx)
{
typedef Resource::Properties::const_iterator iterator;
@@ -137,7 +138,7 @@ CreateBlock::pre_process()
/* Compile graph with new block added for insertion in audio thread
TODO: Since the block is not connected at this point, a full compilation
could be avoided and the block simply appended. */
- if (_graph->enabled()) {
+ if (ctx.must_compile(_graph)) {
_compiled_graph = CompiledGraph::compile(_graph);
}
@@ -149,9 +150,8 @@ CreateBlock::pre_process()
void
CreateBlock::execute(RunContext& context)
{
- if (_status == Status::SUCCESS) {
- _graph->set_compiled_graph(_compiled_graph);
- _compiled_graph = NULL; // Graph takes ownership
+ if (_status == Status::SUCCESS && _compiled_graph) {
+ _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
}
}
diff --git a/src/server/events/CreateBlock.hpp b/src/server/events/CreateBlock.hpp
index 00205c6a..b0aa6aa4 100644
--- a/src/server/events/CreateBlock.hpp
+++ b/src/server/events/CreateBlock.hpp
@@ -47,7 +47,7 @@ public:
~CreateBlock();
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/CreateGraph.cpp b/src/server/events/CreateGraph.cpp
index a2e4e6c4..ae359e17 100644
--- a/src/server/events/CreateGraph.cpp
+++ b/src/server/events/CreateGraph.cpp
@@ -23,6 +23,7 @@
#include "Driver.hpp"
#include "Engine.hpp"
#include "GraphImpl.hpp"
+#include "PreProcessContext.hpp"
#include "events/CreateGraph.hpp"
#include "events/CreatePort.hpp"
@@ -92,7 +93,7 @@ CreateGraph::build_child_events()
}
bool
-CreateGraph::pre_process()
+CreateGraph::pre_process(PreProcessContext& ctx)
{
if (_engine.store()->get(_path)) {
return Event::pre_process_done(Status::EXISTS, _path);
@@ -163,6 +164,8 @@ CreateGraph::pre_process()
_parent->add_block(*_graph);
if (_parent->enabled()) {
_graph->enable();
+ }
+ if (ctx.must_compile(_parent)) {
_compiled_graph = CompiledGraph::compile(_parent);
}
}
@@ -179,7 +182,7 @@ CreateGraph::pre_process()
// Build and pre-process child events to create standard ports
build_child_events();
for (SPtr<Event> ev : _child_events) {
- ev->pre_process();
+ ev->pre_process(ctx);
}
return Event::pre_process_done(Status::SUCCESS);
@@ -189,8 +192,8 @@ void
CreateGraph::execute(RunContext& context)
{
if (_graph) {
- if (_parent) {
- _parent->set_compiled_graph(_compiled_graph);
+ if (_parent && _compiled_graph) {
+ _compiled_graph = _parent->swap_compiled_graph(_compiled_graph);
}
for (SPtr<Event> ev : _child_events) {
@@ -213,6 +216,8 @@ CreateGraph::post_process()
}
}
_child_events.clear();
+
+ delete _compiled_graph;
}
void
diff --git a/src/server/events/CreateGraph.hpp b/src/server/events/CreateGraph.hpp
index 9cae32ba..794742ac 100644
--- a/src/server/events/CreateGraph.hpp
+++ b/src/server/events/CreateGraph.hpp
@@ -44,7 +44,7 @@ public:
const Raul::Path& path,
const Resource::Properties& properties);
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp
index 9384ce09..60e57a71 100644
--- a/src/server/events/CreatePort.cpp
+++ b/src/server/events/CreatePort.cpp
@@ -86,7 +86,7 @@ CreatePort::CreatePort(Engine& engine,
}
bool
-CreatePort::pre_process()
+CreatePort::pre_process(PreProcessContext& ctx)
{
if (_port_type == PortType::UNKNOWN) {
return Event::pre_process_done(Status::UNKNOWN_TYPE, _path);
diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp
index c002df59..f3e2092d 100644
--- a/src/server/events/CreatePort.hpp
+++ b/src/server/events/CreatePort.hpp
@@ -51,7 +51,7 @@ public:
const Raul::Path& path,
const Resource::Properties& properties);
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp
index 0d202f84..bab2594a 100644
--- a/src/server/events/Delete.cpp
+++ b/src/server/events/Delete.cpp
@@ -29,6 +29,7 @@
#include "GraphImpl.hpp"
#include "PluginImpl.hpp"
#include "PortImpl.hpp"
+#include "PreProcessContext.hpp"
namespace Ingen {
namespace Server {
@@ -54,10 +55,11 @@ Delete::Delete(Engine& engine,
Delete::~Delete()
{
delete _disconnect_event;
+ delete _compiled_graph;
}
bool
-Delete::pre_process()
+Delete::pre_process(PreProcessContext& ctx)
{
if (_path.is_root() || _path == "/control" || _path == "/notify") {
return Event::pre_process_done(Status::NOT_DELETABLE, _path);
@@ -91,19 +93,22 @@ Delete::pre_process()
if (_block) {
parent->remove_block(*_block);
_disconnect_event = new DisconnectAll(_engine, parent, _block.get());
- _disconnect_event->pre_process();
+ _disconnect_event->pre_process(ctx);
- if (parent->enabled()) {
+ if (ctx.must_compile(parent)) {
_compiled_graph = CompiledGraph::compile(parent);
}
} else if (_port) {
parent->remove_port(*_port);
_disconnect_event = new DisconnectAll(_engine, parent, _port.get());
- _disconnect_event->pre_process();
+ _disconnect_event->pre_process(ctx);
- if (parent->enabled()) {
+ if (ctx.must_compile(parent)) {
_compiled_graph = CompiledGraph::compile(parent);
- _ports_array = parent->build_ports_array();
+ }
+
+ if (parent->enabled()) {
+ _ports_array = parent->build_ports_array();
assert(_ports_array->size() == parent->num_ports_non_rt());
}
@@ -137,8 +142,8 @@ Delete::execute(RunContext& context)
}
}
- if (parent) {
- parent->set_compiled_graph(_compiled_graph);
+ if (parent && _compiled_graph) {
+ _compiled_graph = parent->swap_compiled_graph(_compiled_graph);
}
}
diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp
index 5cd40b14..fd797804 100644
--- a/src/server/events/Delete.hpp
+++ b/src/server/events/Delete.hpp
@@ -54,7 +54,7 @@ public:
~Delete();
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp
index 8c94fac7..62d08367 100644
--- a/src/server/events/Delta.cpp
+++ b/src/server/events/Delta.cpp
@@ -79,6 +79,7 @@ Delta::~Delta()
delete s;
delete _create_event;
+ delete _compiled_graph;
}
void
@@ -98,7 +99,6 @@ Delta::add_set_event(const char* port_symbol,
_engine, _request_client, _request_id, _time,
port, Atom(size, type, value), true);
- ev->pre_process();
_set_events.push_back(ev);
}
@@ -155,7 +155,7 @@ get_file_node(LilvWorld* lworld, const URIs& uris, const Atom& value)
*/
bool
-Delta::pre_process()
+Delta::pre_process(PreProcessContext& ctx)
{
const Ingen::URIs& uris = _engine.world()->uris();
@@ -231,7 +231,7 @@ Delta::pre_process()
path, _properties);
}
if (_create_event) {
- if (_create_event->pre_process()) {
+ if (_create_event->pre_process(ctx)) {
_object = _engine.store()->get(path); // Get object for setting
} else {
return Event::pre_process_done(Status::CREATION_FAILED, _subject);
@@ -322,7 +322,6 @@ Delta::pre_process()
} else if (key == uris.ingen_value || key == uris.ingen_activity) {
SetPortValue* ev = new SetPortValue(
_engine, _request_client, _request_id, _time, port, value);
- ev->pre_process();
_set_events.push_back(ev);
} else if (key == uris.midi_binding) {
if (port->is_a(PortType::CONTROL) || port->is_a(PortType::CV)) {
@@ -449,6 +448,10 @@ Delta::pre_process()
_types.push_back(op);
}
+ for (auto& s : _set_events) {
+ s->pre_process(ctx);
+ }
+
if (poly_changed) {
lock.unlock();
_poly_lock.lock();
@@ -496,7 +499,7 @@ Delta::execute(RunContext& context)
if (_graph) {
if (value.get<int32_t>()) {
if (_compiled_graph) {
- _graph->set_compiled_graph(_compiled_graph);
+ _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
}
_graph->enable();
} else {
diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp
index 24330199..9e6cbecd 100644
--- a/src/server/events/Delta.hpp
+++ b/src/server/events/Delta.hpp
@@ -73,7 +73,7 @@ public:
uint32_t size,
uint32_t type);
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp
index ed9312d5..476a0cee 100644
--- a/src/server/events/Disconnect.cpp
+++ b/src/server/events/Disconnect.cpp
@@ -29,6 +29,7 @@
#include "InputPort.hpp"
#include "OutputPort.hpp"
#include "PortImpl.hpp"
+#include "PreProcessContext.hpp"
#include "RunContext.hpp"
#include "ThreadManager.hpp"
#include "events/Disconnect.hpp"
@@ -55,6 +56,7 @@ Disconnect::Disconnect(Engine& engine,
Disconnect::~Disconnect()
{
delete _impl;
+ delete _compiled_graph;
}
Disconnect::Impl::Impl(Engine& e,
@@ -112,7 +114,7 @@ Disconnect::Impl::Impl(Engine& e,
}
bool
-Disconnect::pre_process()
+Disconnect::pre_process(PreProcessContext& ctx)
{
std::lock_guard<std::mutex> lock(_engine.store()->mutex());
@@ -166,8 +168,9 @@ Disconnect::pre_process()
dynamic_cast<OutputPort*>(tail),
dynamic_cast<InputPort*>(head));
- if (_graph->enabled())
+ if (ctx.must_compile(_graph)) {
_compiled_graph = CompiledGraph::compile(_graph);
+ }
return Event::pre_process_done(Status::SUCCESS);
}
@@ -204,7 +207,9 @@ Disconnect::execute(RunContext& context)
{
if (_status == Status::SUCCESS) {
if (_impl->execute(context, true)) {
- _graph->set_compiled_graph(_compiled_graph);
+ if (_compiled_graph) {
+ _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
+ }
} else {
_status = Status::NOT_FOUND;
}
diff --git a/src/server/events/Disconnect.hpp b/src/server/events/Disconnect.hpp
index 69d9469c..19ffcf3b 100644
--- a/src/server/events/Disconnect.hpp
+++ b/src/server/events/Disconnect.hpp
@@ -54,7 +54,7 @@ public:
~Disconnect();
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/DisconnectAll.cpp b/src/server/events/DisconnectAll.cpp
index e4866d30..2dea6a76 100644
--- a/src/server/events/DisconnectAll.cpp
+++ b/src/server/events/DisconnectAll.cpp
@@ -31,6 +31,7 @@
#include "InputPort.hpp"
#include "OutputPort.hpp"
#include "PortImpl.hpp"
+#include "PreProcessContext.hpp"
#include "events/Disconnect.hpp"
#include "events/DisconnectAll.hpp"
#include "util.hpp"
@@ -76,10 +77,12 @@ DisconnectAll::~DisconnectAll()
{
for (auto& i : _impls)
delete i;
+
+ delete _compiled_graph;
}
bool
-DisconnectAll::pre_process()
+DisconnectAll::pre_process(PreProcessContext& ctx)
{
std::unique_lock<std::mutex> lock(_engine.store()->mutex(), std::defer_lock);
@@ -136,7 +139,7 @@ DisconnectAll::pre_process()
dynamic_cast<InputPort*>(a->head())));
}
- if (!_deleting && _parent->enabled()) {
+ if (!_deleting && ctx.must_compile(_parent)) {
if (!(_compiled_graph = CompiledGraph::compile(_parent))) {
return Event::pre_process_done(Status::COMPILATION_FAILED);
}
@@ -155,7 +158,9 @@ DisconnectAll::execute(RunContext& context)
}
}
- _parent->set_compiled_graph(_compiled_graph);
+ if (_compiled_graph) {
+ _compiled_graph = _parent->swap_compiled_graph(_compiled_graph);
+ }
}
void
diff --git a/src/server/events/DisconnectAll.hpp b/src/server/events/DisconnectAll.hpp
index 1ddfc536..1fc1f757 100644
--- a/src/server/events/DisconnectAll.hpp
+++ b/src/server/events/DisconnectAll.hpp
@@ -56,7 +56,7 @@ public:
~DisconnectAll();
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp
index b018c1a9..dfa16ef5 100644
--- a/src/server/events/Get.cpp
+++ b/src/server/events/Get.cpp
@@ -46,7 +46,7 @@ Get::Get(Engine& engine,
{}
bool
-Get::pre_process()
+Get::pre_process(PreProcessContext& ctx)
{
std::lock_guard<std::mutex> lock(_engine.store()->mutex());
diff --git a/src/server/events/Get.hpp b/src/server/events/Get.hpp
index f685df21..35955d9a 100644
--- a/src/server/events/Get.hpp
+++ b/src/server/events/Get.hpp
@@ -47,7 +47,7 @@ public:
SampleCount timestamp,
const Raul::URI& uri);
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context) {}
void post_process();
diff --git a/src/server/events/Mark.cpp b/src/server/events/Mark.cpp
index 11690487..c72cc14f 100644
--- a/src/server/events/Mark.cpp
+++ b/src/server/events/Mark.cpp
@@ -15,6 +15,7 @@
*/
#include "Engine.hpp"
+#include "PreProcessContext.hpp"
#include "UndoStack.hpp"
#include "events/Mark.hpp"
@@ -32,8 +33,15 @@ Mark::Mark(Engine& engine,
, _depth(0)
{}
+Mark::~Mark()
+{
+ for (const auto& g : _compiled_graphs) {
+ delete g.second;
+ }
+}
+
bool
-Mark::pre_process()
+Mark::pre_process(PreProcessContext& ctx)
{
UndoStack* const stack = ((_mode == Mode::UNDO)
? _engine.redo_stack()
@@ -41,10 +49,21 @@ Mark::pre_process()
switch (_type) {
case Type::BUNDLE_START:
+ ctx.set_in_bundle(true);
_depth = stack->start_entry();
break;
case Type::BUNDLE_END:
_depth = stack->finish_entry();
+ ctx.set_in_bundle(false);
+ if (!ctx.dirty_graphs().empty()) {
+ for (GraphImpl* g : ctx.dirty_graphs()) {
+ CompiledGraph* cg = CompiledGraph::compile(g);
+ if (cg) {
+ _compiled_graphs.insert(std::make_pair(g, cg));
+ }
+ }
+ ctx.dirty_graphs().clear();
+ }
break;
}
@@ -53,7 +72,11 @@ Mark::pre_process()
void
Mark::execute(RunContext& context)
-{}
+{
+ for (auto& g : _compiled_graphs) {
+ g.second = g.first->swap_compiled_graph(g.second);
+ }
+}
void
Mark::post_process()
diff --git a/src/server/events/Mark.hpp b/src/server/events/Mark.hpp
index d2db0834..68ba5149 100644
--- a/src/server/events/Mark.hpp
+++ b/src/server/events/Mark.hpp
@@ -44,15 +44,20 @@ public:
SampleCount timestamp,
Type type);
- bool pre_process();
+ ~Mark();
+
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
Execution get_execution() const;
private:
- Type _type;
- int _depth;
+ typedef std::map<GraphImpl*, CompiledGraph*> CompiledGraphs;
+
+ CompiledGraphs _compiled_graphs;
+ Type _type;
+ int _depth;
};
} // namespace Events
diff --git a/src/server/events/Move.cpp b/src/server/events/Move.cpp
index d6eae6d6..aee74ab6 100644
--- a/src/server/events/Move.cpp
+++ b/src/server/events/Move.cpp
@@ -46,7 +46,7 @@ Move::~Move()
}
bool
-Move::pre_process()
+Move::pre_process(PreProcessContext& ctx)
{
std::lock_guard<std::mutex> lock(_engine.store()->mutex());
diff --git a/src/server/events/Move.hpp b/src/server/events/Move.hpp
index ef308a01..c45c73aa 100644
--- a/src/server/events/Move.hpp
+++ b/src/server/events/Move.hpp
@@ -45,7 +45,7 @@ public:
~Move();
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
void undo(Interface& target);
diff --git a/src/server/events/SetPortValue.cpp b/src/server/events/SetPortValue.cpp
index 0fac88c2..5bcb6dbf 100644
--- a/src/server/events/SetPortValue.cpp
+++ b/src/server/events/SetPortValue.cpp
@@ -53,7 +53,7 @@ SetPortValue::~SetPortValue()
}
bool
-SetPortValue::pre_process()
+SetPortValue::pre_process(PreProcessContext& ctx)
{
if (_port->is_output()) {
return Event::pre_process_done(Status::DIRECTION_MISMATCH, _port->path());
diff --git a/src/server/events/SetPortValue.hpp b/src/server/events/SetPortValue.hpp
index 7b49096f..aac5e033 100644
--- a/src/server/events/SetPortValue.hpp
+++ b/src/server/events/SetPortValue.hpp
@@ -47,7 +47,7 @@ public:
~SetPortValue();
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();
diff --git a/src/server/events/Undo.cpp b/src/server/events/Undo.cpp
index 0510d50f..83279744 100644
--- a/src/server/events/Undo.cpp
+++ b/src/server/events/Undo.cpp
@@ -34,7 +34,7 @@ Undo::Undo(Engine& engine,
{}
bool
-Undo::pre_process()
+Undo::pre_process(PreProcessContext& ctx)
{
UndoStack* const stack = _is_redo ? _engine.redo_stack() : _engine.undo_stack();
const Event::Mode mode = _is_redo ? Event::Mode::REDO : Event::Mode::UNDO;
diff --git a/src/server/events/Undo.hpp b/src/server/events/Undo.hpp
index c95daea9..300c74f2 100644
--- a/src/server/events/Undo.hpp
+++ b/src/server/events/Undo.hpp
@@ -38,7 +38,7 @@ public:
SampleCount timestamp,
bool is_redo);
- bool pre_process();
+ bool pre_process(PreProcessContext& ctx);
void execute(RunContext& context);
void post_process();