summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-02-12 15:04:20 +0100
committerDavid Robillard <d@drobilla.net>2017-02-12 15:31:47 +0100
commitb1198f0842e6e4d6b1c01f07d91b42ef4a212788 (patch)
tree93fdf4da89a6f5f634707fb8c989e0d9ee1a3c65
parent81d45973412c675e3c0b4a10b64d811a219feeae (diff)
downloadingen-b1198f0842e6e4d6b1c01f07d91b42ef4a212788.tar.gz
ingen-b1198f0842e6e4d6b1c01f07d91b42ef4a212788.tar.bz2
ingen-b1198f0842e6e4d6b1c01f07d91b42ef4a212788.zip
Use smart pointers to handle real-time memory disposal
-rw-r--r--ingen/types.hpp6
-rw-r--r--src/server/BlockImpl.cpp7
-rw-r--r--src/server/BlockImpl.hpp23
-rw-r--r--src/server/BufferFactory.cpp6
-rw-r--r--src/server/BufferFactory.hpp6
-rw-r--r--src/server/CompiledGraph.cpp10
-rw-r--r--src/server/CompiledGraph.hpp4
-rw-r--r--src/server/DuplexPort.cpp6
-rw-r--r--src/server/DuplexPort.hpp4
-rw-r--r--src/server/Engine.cpp2
-rw-r--r--src/server/Engine.hpp2
-rw-r--r--src/server/GraphImpl.cpp30
-rw-r--r--src/server/GraphImpl.hpp27
-rw-r--r--src/server/InputPort.cpp12
-rw-r--r--src/server/InputPort.hpp10
-rw-r--r--src/server/LV2Block.cpp40
-rw-r--r--src/server/LV2Block.hpp34
-rw-r--r--src/server/NodeImpl.hpp4
-rw-r--r--src/server/PortImpl.cpp31
-rw-r--r--src/server/PortImpl.hpp68
-rw-r--r--src/server/PreProcessContext.hpp20
-rw-r--r--src/server/events/Connect.cpp21
-rw-r--r--src/server/events/Connect.hpp22
-rw-r--r--src/server/events/Copy.cpp8
-rw-r--r--src/server/events/Copy.hpp12
-rw-r--r--src/server/events/CreateBlock.cpp8
-rw-r--r--src/server/events/CreateBlock.hpp2
-rw-r--r--src/server/events/CreateGraph.cpp9
-rw-r--r--src/server/events/CreateGraph.hpp14
-rw-r--r--src/server/events/CreatePort.cpp20
-rw-r--r--src/server/events/CreatePort.hpp4
-rw-r--r--src/server/events/Delete.cpp20
-rw-r--r--src/server/events/Delete.hpp4
-rw-r--r--src/server/events/Delta.cpp12
-rw-r--r--src/server/events/Delta.hpp2
-rw-r--r--src/server/events/Disconnect.cpp18
-rw-r--r--src/server/events/Disconnect.hpp25
-rw-r--r--src/server/events/DisconnectAll.cpp11
-rw-r--r--src/server/events/DisconnectAll.hpp16
-rw-r--r--src/server/events/Mark.cpp10
-rw-r--r--src/server/events/Mark.hpp2
-rw-r--r--src/server/internals/BlockDelay.cpp2
-rw-r--r--src/server/internals/Controller.cpp2
-rw-r--r--src/server/internals/Note.cpp17
-rw-r--r--src/server/internals/Note.hpp13
-rw-r--r--src/server/internals/Time.cpp2
-rw-r--r--src/server/internals/Trigger.cpp2
-rw-r--r--wscript2
48 files changed, 306 insertions, 326 deletions
diff --git a/ingen/types.hpp b/ingen/types.hpp
index e6cbc3b5..d1055e22 100644
--- a/ingen/types.hpp
+++ b/ingen/types.hpp
@@ -19,6 +19,8 @@
#include <memory>
+#include "raul/Maid.hpp"
+
namespace Ingen {
#if __cplusplus >= 201103L
@@ -27,9 +29,13 @@ using SPtr = std::shared_ptr<T>;
template <class T>
using WPtr = std::weak_ptr<T>;
+
+template <class T>
+using MPtr = Raul::managed_ptr<T>;
#else
#define SPtr std::shared_ptr
#define WPtr std::weak_ptr
+#define MPtr Raul::managed_ptr
#endif
template <class T>
diff --git a/src/server/BlockImpl.cpp b/src/server/BlockImpl.cpp
index d3a5b02d..bdcf1500 100644
--- a/src/server/BlockImpl.cpp
+++ b/src/server/BlockImpl.cpp
@@ -40,7 +40,6 @@ BlockImpl::BlockImpl(PluginImpl* plugin,
SampleRate srate)
: NodeImpl(plugin->uris(), parent, symbol)
, _plugin(plugin)
- , _ports(NULL)
, _polyphony((polyphonic && parent) ? parent->internal_poly() : 1)
, _mark(Mark::UNVISITED)
, _polyphonic(polyphonic)
@@ -60,8 +59,6 @@ BlockImpl::~BlockImpl()
if (is_linked()) {
parent_graph()->remove_block(*this);
}
-
- delete _ports;
}
Node*
@@ -120,7 +117,7 @@ BlockImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
}
bool
-BlockImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
+BlockImpl::apply_poly(RunContext& context, uint32_t poly)
{
if (!_polyphonic)
poly = 1;
@@ -129,7 +126,7 @@ BlockImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
if (_ports)
for (uint32_t i = 0; i < num_ports(); ++i)
- _ports->at(i)->apply_poly(context, maid, poly);
+ _ports->at(i)->apply_poly(context, poly);
return true;
}
diff --git a/src/server/BlockImpl.hpp b/src/server/BlockImpl.hpp
index 8f937dc5..2e3e5fcd 100644
--- a/src/server/BlockImpl.hpp
+++ b/src/server/BlockImpl.hpp
@@ -60,6 +60,8 @@ class BlockImpl : public NodeImpl
, public boost::intrusive::slist_base_hook<> // In GraphImpl
{
public:
+ typedef Raul::Array<PortImpl*> Ports;
+
BlockImpl(PluginImpl* plugin,
const Raul::Symbol& symbol,
bool poly,
@@ -152,8 +154,7 @@ public:
virtual void set_polyphonic(bool p) { _polyphonic = p; }
virtual bool prepare_poly(BufferFactory& bufs, uint32_t poly);
- virtual bool apply_poly(
- RunContext& context, Raul::Maid& maid, uint32_t poly);
+ virtual bool apply_poly(RunContext& context, uint32_t poly);
/** Information about the Plugin this Block is an instance of.
* Not the best name - not all blocks come from plugins (ie Graph)
@@ -186,15 +187,15 @@ public:
protected:
PortImpl* nth_port_by_type(uint32_t n, bool input, PortType type);
- PluginImpl* _plugin;
- Raul::Array<PortImpl*>* _ports; ///< Access in audio thread only
- uint32_t _polyphony;
- std::set<BlockImpl*> _providers; ///< Blocks connected to this one's input ports
- std::set<BlockImpl*> _dependants; ///< Blocks this one's output ports are connected to
- Mark _mark; ///< Mark for graph compilation algorithm
- bool _polyphonic;
- bool _activated;
- bool _enabled;
+ PluginImpl* _plugin;
+ MPtr<Ports> _ports; ///< Access in audio thread only
+ uint32_t _polyphony;
+ std::set<BlockImpl*> _providers; ///< Blocks connected to this one's input ports
+ std::set<BlockImpl*> _dependants; ///< Blocks this one's output ports are connected to
+ Mark _mark; ///< Mark for graph compilation algorithm
+ bool _polyphonic;
+ bool _activated;
+ bool _enabled;
};
} // namespace Server
diff --git a/src/server/BufferFactory.cpp b/src/server/BufferFactory.cpp
index 2fa98b67..fea74eca 100644
--- a/src/server/BufferFactory.cpp
+++ b/src/server/BufferFactory.cpp
@@ -52,6 +52,12 @@ BufferFactory::forge()
return _engine.world()->forge();
}
+Raul::Maid&
+BufferFactory::maid()
+{
+ return *_engine.maid();
+}
+
void
BufferFactory::free_list(Buffer* head)
{
diff --git a/src/server/BufferFactory.hpp b/src/server/BufferFactory.hpp
index 09722b4e..8265fc98 100644
--- a/src/server/BufferFactory.hpp
+++ b/src/server/BufferFactory.hpp
@@ -32,6 +32,8 @@
#include "PortType.hpp"
#include "types.hpp"
+namespace Raul { class Maid; }
+
namespace Ingen {
class URIs;
@@ -71,7 +73,9 @@ public:
void set_block_length(SampleCount block_length);
void set_seq_size(uint32_t seq_size) { _seq_size = seq_size; }
- Forge& forge();
+ Forge& forge();
+ Raul::Maid& maid();
+
URIs& uris() { return _uris; }
Engine& engine() { return _engine; }
diff --git a/src/server/CompiledGraph.cpp b/src/server/CompiledGraph.cpp
index fdf59cd4..b808cb90 100644
--- a/src/server/CompiledGraph.cpp
+++ b/src/server/CompiledGraph.cpp
@@ -48,13 +48,13 @@ CompiledGraph::CompiledGraph(GraphImpl* graph)
compile_graph(graph);
}
-CompiledGraph*
-CompiledGraph::compile(GraphImpl* graph)
+MPtr<CompiledGraph>
+CompiledGraph::compile(Raul::Maid& maid, GraphImpl& graph)
{
try {
- return new CompiledGraph(graph);
+ return maid.make_managed<CompiledGraph>(&graph);
} catch (FeedbackException e) {
- Log& log = graph->engine().log();
+ Log& log = graph.engine().log();
if (e.node && e.root) {
log.error(fmt("Feedback compiling %1% from %2%\n")
% e.node->path() % e.root->path());
@@ -62,7 +62,7 @@ CompiledGraph::compile(GraphImpl* graph)
log.error(fmt("Feedback compiling %1%\n")
% e.node->path());
}
- return NULL;
+ return MPtr<CompiledGraph>();
}
}
diff --git a/src/server/CompiledGraph.hpp b/src/server/CompiledGraph.hpp
index 7dc40865..eeeb6111 100644
--- a/src/server/CompiledGraph.hpp
+++ b/src/server/CompiledGraph.hpp
@@ -47,13 +47,15 @@ class CompiledGraph : public Raul::Maid::Disposable
, public Raul::Noncopyable
{
public:
- static CompiledGraph* compile(GraphImpl* graph);
+ static MPtr<CompiledGraph> compile(Raul::Maid& maid, GraphImpl& graph);
void run(RunContext& context);
void dump(std::function<void (const std::string&)> sink) const;
private:
+ friend class Raul::Maid; ///< Allow make_managed to construct
+
CompiledGraph(GraphImpl* graph);
typedef std::set<BlockImpl*> BlockSet;
diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp
index 41312e65..0fa11a72 100644
--- a/src/server/DuplexPort.cpp
+++ b/src/server/DuplexPort.cpp
@@ -132,7 +132,7 @@ DuplexPort::on_property(const Raul::URI& uri, const Atom& value)
bool
DuplexPort::get_buffers(BufferFactory& bufs,
PortImpl::GetFn get,
- Raul::Array<Voice>* voices,
+ const MPtr<Voices>& voices,
uint32_t poly,
size_t num_in_arcs) const
{
@@ -187,14 +187,14 @@ DuplexPort::prepare_poly(BufferFactory& bufs, uint32_t poly)
}
bool
-DuplexPort::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
+DuplexPort::apply_poly(RunContext& context, uint32_t poly)
{
if (!parent()->parent() ||
poly != parent()->parent_graph()->internal_poly()) {
return false;
}
- return PortImpl::apply_poly(context, maid, poly);
+ return PortImpl::apply_poly(context, poly);
}
void
diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp
index 8d0443a6..47c24b9e 100644
--- a/src/server/DuplexPort.hpp
+++ b/src/server/DuplexPort.hpp
@@ -67,11 +67,11 @@ public:
bool prepare_poly(BufferFactory& bufs, uint32_t poly);
- bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly);
+ bool apply_poly(RunContext& context, uint32_t poly);
bool get_buffers(BufferFactory& bufs,
PortImpl::GetFn get,
- Raul::Array<Voice>* voices,
+ const MPtr<Voices>& voices,
uint32_t poly,
size_t num_in_arcs) const;
diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp
index 6b0c909c..d12f474c 100644
--- a/src/server/Engine.cpp
+++ b/src/server/Engine.cpp
@@ -67,6 +67,7 @@ bool ThreadManager::single_threaded(true);
Engine::Engine(Ingen::World* world)
: _world(world)
+ , _maid(new Raul::Maid)
, _block_factory(new BlockFactory(world))
, _broadcaster(new Broadcaster())
, _buffer_factory(new BufferFactory(*this, world->uris()))
@@ -74,7 +75,6 @@ Engine::Engine(Ingen::World* world)
, _event_writer(new EventWriter(*this))
, _interface(_event_writer)
, _atom_interface(nullptr)
- , _maid(new Raul::Maid())
, _options(new LV2Options(world->uris()))
, _undo_stack(new UndoStack(_world->uris(), _world->uri_map()))
, _redo_stack(new UndoStack(_world->uris(), _world->uri_map()))
diff --git a/src/server/Engine.hpp b/src/server/Engine.hpp
index a4b85562..6e8e74c9 100644
--- a/src/server/Engine.hpp
+++ b/src/server/Engine.hpp
@@ -186,6 +186,7 @@ private:
bool changed = false;
};
+ Raul::Maid* _maid;
BlockFactory* _block_factory;
Broadcaster* _broadcaster;
BufferFactory* _buffer_factory;
@@ -194,7 +195,6 @@ private:
SPtr<EventWriter> _event_writer;
SPtr<Interface> _interface;
AtomReader* _atom_interface;
- Raul::Maid* _maid;
SPtr<LV2Options> _options;
UndoStack* _undo_stack;
UndoStack* _redo_stack;
diff --git a/src/server/GraphImpl.cpp b/src/server/GraphImpl.cpp
index dd7be036..6b1d0464 100644
--- a/src/server/GraphImpl.cpp
+++ b/src/server/GraphImpl.cpp
@@ -52,7 +52,6 @@ GraphImpl::GraphImpl(Engine& engine,
, _engine(engine)
, _poly_pre(internal_poly)
, _poly_process(internal_poly)
- , _compiled_graph(NULL)
, _process(false)
{
assert(internal_poly >= 1);
@@ -61,7 +60,6 @@ GraphImpl::GraphImpl(Engine& engine,
GraphImpl::~GraphImpl()
{
- delete _compiled_graph;
delete _plugin;
}
@@ -87,14 +85,14 @@ GraphImpl::duplicate(Engine& engine,
PortMap port_map;
// Add duplicates of all ports
- dup->_ports = new Raul::Array<PortImpl*>(num_ports(), NULL);
- for (Ports::iterator p = _inputs.begin(); p != _inputs.end(); ++p) {
+ dup->_ports = bufs.maid().make_managed<Ports>(num_ports(), nullptr);
+ for (PortList::iterator p = _inputs.begin(); p != _inputs.end(); ++p) {
DuplexPort* p_dup = p->duplicate(engine, p->symbol(), dup);
dup->_inputs.push_front(*p_dup);
(*dup->_ports)[p->index()] = p_dup;
port_map.insert({&*p, p_dup});
}
- for (Ports::iterator p = _outputs.begin(); p != _outputs.end(); ++p) {
+ for (PortList::iterator p = _outputs.begin(); p != _outputs.end(); ++p) {
DuplexPort* p_dup = p->duplicate(engine, p->symbol(), dup);
dup->_outputs.push_front(*p_dup);
(*dup->_ports)[p->index()] = p_dup;
@@ -185,7 +183,7 @@ GraphImpl::apply_internal_poly(RunContext& context,
// TODO: Subgraph dynamic polyphony (i.e. changing port polyphony)
for (auto& b : _blocks) {
- b.apply_poly(context, maid, poly);
+ b.apply_poly(context, poly);
}
for (auto& b : _blocks) {
@@ -299,15 +297,13 @@ GraphImpl::has_arc(const PortImpl* tail, const PortImpl* dst_port) const
return (i != _arcs.end());
}
-CompiledGraph*
-GraphImpl::swap_compiled_graph(CompiledGraph* cg)
+void
+GraphImpl::set_compiled_graph(MPtr<CompiledGraph>&& cg)
{
- CompiledGraph* const old = _compiled_graph;
- if (old && cg != old) {
+ if (_compiled_graph && _compiled_graph != cg) {
_engine.reset_load();
}
- _compiled_graph = cg;
- return old;
+ _compiled_graph = std::move(cg);
}
uint32_t
@@ -334,20 +330,20 @@ GraphImpl::clear_ports()
_outputs.clear();
}
-Raul::Array<PortImpl*>*
-GraphImpl::build_ports_array()
+MPtr<BlockImpl::Ports>
+GraphImpl::build_ports_array(Raul::Maid& maid)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
const size_t n = _inputs.size() + _outputs.size();
- Raul::Array<PortImpl*>* const result = new Raul::Array<PortImpl*>(n);
+ MPtr<Ports> result = maid.make_managed<Ports>(n);
size_t i = 0;
- for (Ports::iterator p = _inputs.begin(); p != _inputs.end(); ++p, ++i)
+ for (PortList::iterator p = _inputs.begin(); p != _inputs.end(); ++p, ++i)
result->at(i) = &*p;
- for (Ports::iterator p = _outputs.begin(); p != _outputs.end(); ++p, ++i)
+ for (PortList::iterator p = _outputs.begin(); p != _outputs.end(); ++p, ++i)
result->at(i) = &*p;
assert(i == n);
diff --git a/src/server/GraphImpl.hpp b/src/server/GraphImpl.hpp
index 57e60792..62af07f6 100644
--- a/src/server/GraphImpl.hpp
+++ b/src/server/GraphImpl.hpp
@@ -119,7 +119,7 @@ public:
uint32_t num_ports_non_rt() const;
typedef boost::intrusive::slist<
- DuplexPort, boost::intrusive::constant_time_size<true> > Ports;
+ DuplexPort, boost::intrusive::constant_time_size<true> > PortList;
void add_input(DuplexPort& port) {
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
@@ -165,12 +165,13 @@ public:
bool has_arc(const PortImpl* tail, const PortImpl* head) const;
/** Set a new compiled graph to run, and return the old one. */
- CompiledGraph* swap_compiled_graph(CompiledGraph* cp) INGEN_WARN_UNUSED_RESULT;
+ void set_compiled_graph(MPtr<CompiledGraph>&& cg);
- Raul::Array<PortImpl*>* external_ports() { return _ports; }
- void external_ports(Raul::Array<PortImpl*>* pa) { _ports = pa; }
+ const MPtr<Ports>& external_ports() { return _ports; }
- Raul::Array<PortImpl*>* build_ports_array();
+ void set_external_ports(MPtr<Ports>&& pa) { _ports = std::move(pa); }
+
+ MPtr<Ports> build_ports_array(Raul::Maid& maid);
/** Whether to run this graph's DSP bits in the audio thread */
bool enabled() const { return _process; }
@@ -183,14 +184,14 @@ public:
Engine& engine() { return _engine; }
private:
- Engine& _engine;
- uint32_t _poly_pre; ///< Pre-process thread only
- uint32_t _poly_process; ///< Process thread only
- CompiledGraph* _compiled_graph; ///< Process thread only
- Ports _inputs; ///< Pre-process thread only
- Ports _outputs; ///< Pre-process thread only
- Blocks _blocks; ///< Pre-process thread only
- bool _process; ///< True iff graph is enabled
+ Engine& _engine;
+ uint32_t _poly_pre; ///< Pre-process thread only
+ uint32_t _poly_process; ///< Process thread only
+ MPtr<CompiledGraph> _compiled_graph; ///< Process thread only
+ PortList _inputs; ///< Pre-process thread only
+ PortList _outputs; ///< Pre-process thread only
+ Blocks _blocks; ///< Pre-process thread only
+ bool _process; ///< True iff graph is enabled
};
} // namespace Server
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index 1b4c4501..b0e2ee61 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -55,9 +55,9 @@ InputPort::InputPort(BufferFactory& bufs,
}
bool
-InputPort::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
+InputPort::apply_poly(RunContext& context, uint32_t poly)
{
- bool ret = PortImpl::apply_poly(context, maid, poly);
+ bool ret = PortImpl::apply_poly(context, poly);
if (!ret)
poly = 1;
@@ -69,7 +69,7 @@ InputPort::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
bool
InputPort::get_buffers(BufferFactory& bufs,
PortImpl::GetFn get,
- Raul::Array<Voice>* voices,
+ const MPtr<Voices>& voices,
uint32_t poly,
size_t num_in_arcs) const
{
@@ -99,9 +99,9 @@ InputPort::get_buffers(BufferFactory& bufs,
}
bool
-InputPort::pre_get_buffers(BufferFactory& bufs,
- Raul::Array<Voice>* voices,
- uint32_t poly) const
+InputPort::pre_get_buffers(BufferFactory& bufs,
+ MPtr<Voices>& voices,
+ uint32_t poly) const
{
return get_buffers(bufs, &BufferFactory::get_buffer, voices, poly, _num_arcs);
}
diff --git a/src/server/InputPort.hpp b/src/server/InputPort.hpp
index 1fa0293d..73911789 100644
--- a/src/server/InputPort.hpp
+++ b/src/server/InputPort.hpp
@@ -67,7 +67,7 @@ public:
/** Return the maximum polyphony of an output connected to this input. */
virtual uint32_t max_tail_poly(RunContext& context) const;
- bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly);
+ bool apply_poly(RunContext& context, uint32_t poly);
/** Add an arc. Realtime safe.
*
@@ -91,9 +91,9 @@ public:
* pre-process thread to allocate buffers for application of a
* connection/disconnection/etc in the next process cycle.
*/
- bool pre_get_buffers(BufferFactory& bufs,
- Raul::Array<Voice>* voices,
- uint32_t poly) const;
+ bool pre_get_buffers(BufferFactory& bufs,
+ MPtr<Voices>& voices,
+ uint32_t poly) const;
bool setup_buffers(RunContext& ctx, BufferFactory& bufs, uint32_t poly);
@@ -118,7 +118,7 @@ public:
protected:
bool get_buffers(BufferFactory& bufs,
PortImpl::GetFn get,
- Raul::Array<Voice>* voices,
+ const MPtr<Voices>& voices,
uint32_t poly,
size_t num_in_arcs) const;
diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp
index be02f3ed..ab2582d1 100644
--- a/src/server/LV2Block.cpp
+++ b/src/server/LV2Block.cpp
@@ -64,8 +64,6 @@ LV2Block::LV2Block(LV2Plugin* plugin,
SampleRate srate)
: BlockImpl(plugin, symbol, polyphonic, parent, srate)
, _lv2_plugin(plugin)
- , _instances(NULL)
- , _prepared_instances(NULL)
, _worker_iface(NULL)
{
assert(_lv2_plugin);
@@ -73,10 +71,12 @@ LV2Block::LV2Block(LV2Plugin* plugin,
LV2Block::~LV2Block()
{
- delete _instances;
+ // Explicitly drop instances first to prevent reference cycles
+ drop_instances(_instances);
+ drop_instances(_prepared_instances);
}
-SPtr<LilvInstance>
+SPtr<LV2Block::Instance>
LV2Block::make_instance(URIs& uris,
SampleRate rate,
uint32_t voice,
@@ -90,7 +90,7 @@ LV2Block::make_instance(URIs& uris,
parent_graph()->engine().log().error(
fmt("Failed to instantiate <%1%>\n")
% _lv2_plugin->uri().c_str());
- return SPtr<LilvInstance>();
+ return SPtr<Instance>();
}
const LV2_Options_Interface* options_iface = NULL;
@@ -145,7 +145,7 @@ LV2Block::make_instance(URIs& uris,
parent_graph()->engine().log().error(
fmt("%1% auto-morphed to unknown type %2%\n")
% port->path().c_str() % type);
- return SPtr<LilvInstance>();
+ return SPtr<Instance>();
}
} else {
parent_graph()->engine().log().error(
@@ -156,7 +156,7 @@ LV2Block::make_instance(URIs& uris,
}
}
- return SPtr<LilvInstance>(inst, lilv_instance_free);
+ return std::make_shared<Instance>(inst);
}
bool
@@ -172,19 +172,19 @@ LV2Block::prepare_poly(BufferFactory& bufs, uint32_t poly)
const SampleRate rate = bufs.engine().driver()->sample_rate();
assert(!_prepared_instances);
- _prepared_instances = new Instances(poly, *_instances, SPtr<void>());
+ _prepared_instances = bufs.maid().make_managed<Instances>(
+ poly, *_instances, SPtr<Instance>());
for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) {
- SPtr<LilvInstance> inst = make_instance(bufs.uris(), rate, i, true);
+ SPtr<Instance> inst = make_instance(bufs.uris(), rate, i, true);
if (!inst) {
- delete _prepared_instances;
- _prepared_instances = NULL;
+ _prepared_instances.reset();
return false;
}
_prepared_instances->at(i) = inst;
if (_activated) {
- lilv_instance_activate(inst.get());
+ lilv_instance_activate(inst->instance);
}
}
@@ -192,19 +192,17 @@ LV2Block::prepare_poly(BufferFactory& bufs, uint32_t poly)
}
bool
-LV2Block::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
+LV2Block::apply_poly(RunContext& context, uint32_t poly)
{
if (!_polyphonic)
poly = 1;
if (_prepared_instances) {
- maid.dispose(_instances);
- _instances = _prepared_instances;
- _prepared_instances = NULL;
+ _instances = std::move(_prepared_instances);
}
assert(poly <= _instances->size());
- return BlockImpl::apply_poly(context, maid, poly);
+ return BlockImpl::apply_poly(context, poly);
}
/** Instantiate self from LV2 plugin descriptor.
@@ -227,7 +225,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state)
LilvNode* lv2_connectionOptional = lilv_new_uri(
bufs.engine().world()->lilv_world(), LV2_CORE__connectionOptional);
- _ports = new Raul::Array<PortImpl*>(num_ports, NULL);
+ _ports = bufs.maid().make_managed<BlockImpl::Ports>(num_ports, nullptr);
bool ret = true;
@@ -416,8 +414,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state)
lilv_node_free(lv2_connectionOptional);
if (!ret) {
- delete _ports;
- _ports = NULL;
+ _ports.reset();
return ret;
}
@@ -425,7 +422,8 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state)
// Actually create plugin instances and port buffers.
const SampleRate rate = bufs.engine().driver()->sample_rate();
- _instances = new Instances(_polyphony, SPtr<void>());
+ _instances = bufs.maid().make_managed<Instances>(
+ _polyphony, SPtr<Instance>());
for (uint32_t i = 0; i < _polyphony; ++i) {
_instances->at(i) = make_instance(bufs.uris(), rate, i, false);
if (!_instances->at(i)) {
diff --git a/src/server/LV2Block.hpp b/src/server/LV2Block.hpp
index b6be8ccf..2ccde602 100644
--- a/src/server/LV2Block.hpp
+++ b/src/server/LV2Block.hpp
@@ -58,7 +58,7 @@ public:
GraphImpl* parent);
bool prepare_poly(BufferFactory& bufs, uint32_t poly);
- bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly);
+ bool apply_poly(RunContext& context, uint32_t poly);
void activate(BufferFactory& bufs);
void deactivate();
@@ -83,16 +83,32 @@ public:
static LilvState* load_state(World* world, const std::string& path);
protected:
- SPtr<LilvInstance> make_instance(URIs& uris,
- SampleRate rate,
- uint32_t voice,
- bool preparing);
+ struct Instance : public Raul::Noncopyable {
+ explicit Instance(LilvInstance* i) : instance(i) {}
+
+ ~Instance() { lilv_instance_free(instance); }
+
+ LilvInstance* const instance;
+ };
+
+ SPtr<Instance> make_instance(URIs& uris,
+ SampleRate rate,
+ uint32_t voice,
+ bool preparing);
inline LilvInstance* instance(uint32_t voice) {
- return (LilvInstance*)(*_instances)[voice].get();
+ return (LilvInstance*)(*_instances)[voice]->instance;
}
- typedef Raul::Array< SPtr<void> > Instances;
+ typedef Raul::Array< SPtr<Instance> > Instances;
+
+ void drop_instances(const MPtr<Instances>& instances) {
+ if (instances) {
+ for (size_t i = 0; i < instances->size(); ++i) {
+ (*instances)[i].reset();
+ }
+ }
+ }
struct Response : public Raul::Maid::Disposable
, public Raul::Noncopyable
@@ -122,8 +138,8 @@ protected:
LV2_Worker_Respond_Handle handle, uint32_t size, const void* data);
LV2Plugin* _lv2_plugin;
- Instances* _instances;
- Instances* _prepared_instances;
+ MPtr<Instances> _instances;
+ MPtr<Instances> _prepared_instances;
const LV2_Worker_Interface* _worker_iface;
std::mutex _work_mutex;
Responses _responses;
diff --git a/src/server/NodeImpl.hpp b/src/server/NodeImpl.hpp
index 517fbdb6..26ef5925 100644
--- a/src/server/NodeImpl.hpp
+++ b/src/server/NodeImpl.hpp
@@ -84,10 +84,8 @@ public:
*
* \param context Process context (process thread only).
* \param poly Must be <= the most recent value passed to prepare_poly.
- * \param maid Any objects no longer needed will be pushed to this
*/
- virtual bool apply_poly(
- RunContext& context, Raul::Maid& maid, uint32_t poly) = 0;
+ virtual bool apply_poly(RunContext& context, uint32_t poly) = 0;
/** Return true iff this is main (the top level Node).
*
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index 245173a7..19f71953 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -66,8 +66,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
, _value(value)
, _min(bufs.forge().make(0.0f))
, _max(bufs.forge().make(1.0f))
- , _voices(new Raul::Array<Voice>(static_cast<size_t>(poly)))
- , _prepared_voices(NULL)
+ , _voices(bufs.maid().make_managed<Voices>(poly))
, _connected_flag(false)
, _monitored(false)
, _force_monitor_update(false)
@@ -106,13 +105,12 @@ PortImpl::PortImpl(BufferFactory& bufs,
PortImpl::~PortImpl()
{
- delete _voices;
}
bool
PortImpl::get_buffers(BufferFactory& bufs,
GetFn get,
- Raul::Array<Voice>* voices,
+ const MPtr<Voices>& voices,
uint32_t poly,
size_t num_in_arcs) const
{
@@ -208,18 +206,11 @@ PortImpl::deactivate()
_peak = 0.0f;
}
-Raul::Array<PortImpl::Voice>*
-PortImpl::set_voices(RunContext& context, Raul::Array<Voice>* voices)
+void
+PortImpl::set_voices(RunContext& context, MPtr<Voices>&& voices)
{
- Raul::Array<Voice>* ret = NULL;
- if (voices != _voices) {
- ret = _voices;
- _voices = voices;
- }
-
+ _voices = std::move(voices);
connect_buffers();
-
- return ret;
}
void
@@ -339,12 +330,12 @@ PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
} else if (_poly == poly) {
return true;
} else if (_prepared_voices && _prepared_voices->size() != poly) {
- delete _prepared_voices;
- _prepared_voices = NULL;
+ _prepared_voices.reset();
}
if (!_prepared_voices) {
- _prepared_voices = new Raul::Array<Voice>(poly, *_voices, Voice());
+ _prepared_voices = bufs.maid().make_managed<Voices>(
+ poly, *_voices, Voice());
}
get_buffers(bufs, &BufferFactory::get_buffer,
@@ -354,7 +345,7 @@ PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
}
bool
-PortImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
+PortImpl::apply_poly(RunContext& context, uint32_t poly)
{
if (_parent->is_main() ||
(_type == PortType::ATOM && !_value.is_valid())) {
@@ -368,9 +359,7 @@ PortImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
_poly = poly;
// Apply a new set of voices from a preceding call to prepare_poly
- maid.dispose(set_voices(context, _prepared_voices));
- assert(_voices == _prepared_voices);
- _prepared_voices = NULL;
+ _voices = std::move(_prepared_voices);
if (is_a(PortType::CONTROL) || is_a(PortType::CV)) {
set_control_value(context, context.start(), _value.get<float>());
diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp
index fd35b52d..e195de9d 100644
--- a/src/server/PortImpl.hpp
+++ b/src/server/PortImpl.hpp
@@ -25,7 +25,6 @@
#include "BufferRef.hpp"
#include "NodeImpl.hpp"
#include "PortType.hpp"
-#include "RunContext.hpp"
#include "types.hpp"
namespace Raul { class Maid; }
@@ -35,6 +34,7 @@ namespace Server {
class BlockImpl;
class BufferFactory;
+class RunContext;
/** A port (input or output) on a Block.
*
@@ -84,6 +84,8 @@ public:
BufferRef buffer;
};
+ typedef Raul::Array<Voice> Voices;
+
PortImpl(BufferFactory& bufs,
BlockImpl* block,
const Raul::Symbol& name,
@@ -102,13 +104,8 @@ public:
/** A port's parent is always a block, so static cast should be safe */
BlockImpl* parent_block() const { return (BlockImpl*)_parent; }
- /** Set the buffers array for this port.
- *
- * Audio thread. Returned value must be freed by caller.
- * \a buffers must be poly() long
- */
- Raul::Array<Voice>* set_voices(RunContext& context,
- Raul::Array<Voice>* voices);
+ /** Set the the voices (buffers) for this port in the audio thread. */
+ void set_voices(RunContext& context, MPtr<Voices>&& voices);
/** Prepare for a new (external) polyphony value.
*
@@ -121,8 +118,7 @@ public:
* Audio thread.
* \a poly Must be < the most recent value passed to prepare_poly.
*/
- virtual bool apply_poly(
- RunContext& context, Raul::Maid& maid, uint32_t poly);
+ virtual bool apply_poly(RunContext& context, uint32_t poly);
/** Return the number of arcs (pre-process thraed). */
virtual size_t num_arcs() const { return 0; }
@@ -280,35 +276,35 @@ protected:
*/
virtual bool get_buffers(BufferFactory& bufs,
GetFn get,
- Raul::Array<Voice>* voices,
+ const MPtr<Voices>& voices,
uint32_t poly,
size_t num_in_arcs) const;
- BufferFactory& _bufs;
- uint32_t _index;
- uint32_t _poly;
- uint32_t _buffer_size;
- uint32_t _frames_since_monitor;
- float _monitor_value;
- float _peak;
- PortType _type;
- LV2_URID _buffer_type;
- Atom _value;
- Atom _min;
- Atom _max;
- Raul::Array<Voice>* _voices;
- Raul::Array<Voice>* _prepared_voices;
- BufferRef _user_buffer;
- std::atomic_flag _connected_flag;
- bool _monitored;
- bool _force_monitor_update;
- bool _is_morph;
- bool _is_auto_morph;
- bool _is_logarithmic;
- bool _is_sample_rate;
- bool _is_toggled;
- bool _is_driver_port;
- bool _is_output;
+ BufferFactory& _bufs;
+ uint32_t _index;
+ uint32_t _poly;
+ uint32_t _buffer_size;
+ uint32_t _frames_since_monitor;
+ float _monitor_value;
+ float _peak;
+ PortType _type;
+ LV2_URID _buffer_type;
+ Atom _value;
+ Atom _min;
+ Atom _max;
+ MPtr<Voices> _voices;
+ MPtr<Voices> _prepared_voices;
+ BufferRef _user_buffer;
+ std::atomic_flag _connected_flag;
+ bool _monitored;
+ bool _force_monitor_update;
+ bool _is_morph;
+ bool _is_auto_morph;
+ bool _is_logarithmic;
+ bool _is_sample_rate;
+ bool _is_toggled;
+ bool _is_driver_port;
+ bool _is_output;
};
} // namespace Server
diff --git a/src/server/PreProcessContext.hpp b/src/server/PreProcessContext.hpp
index bf1115e8..ee9bed86 100644
--- a/src/server/PreProcessContext.hpp
+++ b/src/server/PreProcessContext.hpp
@@ -21,6 +21,8 @@
#include "GraphImpl.hpp"
+namespace Raul { class Maid; }
+
namespace Ingen {
namespace Server {
@@ -44,17 +46,29 @@ public:
* 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()) {
+ bool must_compile(GraphImpl& graph) {
+ if (!graph.enabled()) {
return false;
} else if (_in_bundle) {
- _dirty_graphs.insert(graph);
+ _dirty_graphs.insert(&graph);
return false;
} else {
return true;
}
}
+ /** Compile graph and return the result if necessary.
+ *
+ * This may return null when an atomic bundle is deferring compilation, in
+ * which case the graph is flagged as dirty for later compilation.
+ */
+ MPtr<CompiledGraph> maybe_compile(Raul::Maid& maid, GraphImpl& graph) {
+ if (must_compile(graph)) {
+ return CompiledGraph::compile(maid, graph);
+ }
+ return MPtr<CompiledGraph>();
+ }
+
/** Return all graphs that require compilation after an atomic bundle. */
const DirtyGraphs& dirty_graphs() const { return _dirty_graphs; }
DirtyGraphs& dirty_graphs() { return _dirty_graphs; }
diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp
index eb758940..e933a490 100644
--- a/src/server/events/Connect.cpp
+++ b/src/server/events/Connect.cpp
@@ -20,6 +20,7 @@
#include "ArcImpl.hpp"
#include "Broadcaster.hpp"
+#include "BufferFactory.hpp"
#include "Connect.hpp"
#include "Engine.hpp"
#include "GraphImpl.hpp"
@@ -44,8 +45,6 @@ Connect::Connect(Engine& engine,
, _head_path(head_path)
, _graph(NULL)
, _head(NULL)
- , _compiled_graph(NULL)
- , _voices(NULL)
{}
bool
@@ -125,8 +124,9 @@ Connect::pre_process(PreProcessContext& ctx)
tail_block->dependants().insert(head_block);
}
- if (ctx.must_compile(_graph)) {
- if (!(_compiled_graph = CompiledGraph::compile(_graph))) {
+ if (ctx.must_compile(*_graph)) {
+ if (!(_compiled_graph = CompiledGraph::compile(
+ *_engine.maid(), *_graph))) {
head_block->providers().erase(tail_block);
tail_block->dependants().erase(head_block);
return Event::pre_process_done(Status::COMPILATION_FAILED);
@@ -138,10 +138,9 @@ Connect::pre_process(PreProcessContext& ctx)
_head->increment_num_arcs();
if (!_head->is_driver_port()) {
- _voices = new Raul::Array<PortImpl::Voice>(_head->poly());
- _head->pre_get_buffers(*_engine.buffer_factory(),
- _voices,
- _head->poly());
+ BufferFactory& bufs = *_engine.buffer_factory();
+ _voices = bufs.maid().make_managed<PortImpl::Voices>(_head->poly());
+ _head->pre_get_buffers(bufs, _voices, _head->poly());
}
tail_output->inherit_neighbour(_head, _tail_remove, _tail_add);
@@ -156,11 +155,11 @@ Connect::execute(RunContext& context)
if (_status == Status::SUCCESS) {
_head->add_arc(context, _arc.get());
if (!_head->is_driver_port()) {
- _engine.maid()->dispose(_head->set_voices(context, _voices));
+ _head->set_voices(context, std::move(_voices));
}
_head->connect_buffers();
if (_compiled_graph) {
- _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
+ _graph->set_compiled_graph(std::move(_compiled_graph));
}
}
}
@@ -180,8 +179,6 @@ 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 359c9f3b..8e7a5030 100644
--- a/src/server/events/Connect.hpp
+++ b/src/server/events/Connect.hpp
@@ -57,17 +57,17 @@ public:
void undo(Interface& target);
private:
- const Raul::Path _tail_path;
- const Raul::Path _head_path;
- GraphImpl* _graph;
- InputPort* _head;
- CompiledGraph* _compiled_graph;
- SPtr<ArcImpl> _arc;
- Raul::Array<PortImpl::Voice>* _voices;
- Resource::Properties _tail_remove;
- Resource::Properties _tail_add;
- Resource::Properties _head_remove;
- Resource::Properties _head_add;
+ const Raul::Path _tail_path;
+ const Raul::Path _head_path;
+ GraphImpl* _graph;
+ InputPort* _head;
+ MPtr<CompiledGraph> _compiled_graph;
+ SPtr<ArcImpl> _arc;
+ MPtr<PortImpl::Voices> _voices;
+ Resource::Properties _tail_remove;
+ Resource::Properties _tail_add;
+ Resource::Properties _head_remove;
+ Resource::Properties _head_add;
};
} // namespace Events
diff --git a/src/server/events/Copy.cpp b/src/server/events/Copy.cpp
index 4356e312..58c9a89c 100644
--- a/src/server/events/Copy.cpp
+++ b/src/server/events/Copy.cpp
@@ -45,7 +45,6 @@ Copy::Copy(Engine& engine,
, _old_block(NULL)
, _parent(NULL)
, _block(NULL)
- , _compiled_graph(NULL)
{}
bool
@@ -126,9 +125,7 @@ Copy::engine_to_engine(PreProcessContext& ctx)
_engine.store()->add(_block);
// Compile graph with new block added for insertion in audio thread
- if (ctx.must_compile(_parent)) {
- _compiled_graph = CompiledGraph::compile(_parent);
- }
+ _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_parent);
return Event::pre_process_done(Status::SUCCESS);
}
@@ -198,7 +195,7 @@ void
Copy::execute(RunContext& context)
{
if (_block && _compiled_graph) {
- _compiled_graph = _parent->swap_compiled_graph(_compiled_graph);
+ _parent->set_compiled_graph(std::move(_compiled_graph));
}
}
@@ -209,7 +206,6 @@ 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 55310757..e95d905e 100644
--- a/src/server/events/Copy.hpp
+++ b/src/server/events/Copy.hpp
@@ -56,12 +56,12 @@ private:
bool engine_to_filesystem(PreProcessContext& ctx);
bool filesystem_to_engine(PreProcessContext& ctx);
- const Raul::URI _old_uri;
- const Raul::URI _new_uri;
- SPtr<BlockImpl> _old_block;
- GraphImpl* _parent;
- BlockImpl* _block;
- CompiledGraph* _compiled_graph;
+ const Raul::URI _old_uri;
+ const Raul::URI _new_uri;
+ SPtr<BlockImpl> _old_block;
+ GraphImpl* _parent;
+ BlockImpl* _block;
+ MPtr<CompiledGraph> _compiled_graph;
};
} // namespace Events
diff --git a/src/server/events/CreateBlock.cpp b/src/server/events/CreateBlock.cpp
index a43a8bf0..255746b1 100644
--- a/src/server/events/CreateBlock.cpp
+++ b/src/server/events/CreateBlock.cpp
@@ -46,12 +46,10 @@ CreateBlock::CreateBlock(Engine& engine,
, _properties(properties)
, _graph(NULL)
, _block(NULL)
- , _compiled_graph(NULL)
{}
CreateBlock::~CreateBlock()
{
- delete _compiled_graph;
}
bool
@@ -150,9 +148,7 @@ CreateBlock::pre_process(PreProcessContext& ctx)
/* 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 (ctx.must_compile(_graph)) {
- _compiled_graph = CompiledGraph::compile(_graph);
- }
+ _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_graph);
_update.put_block(_block);
@@ -163,7 +159,7 @@ void
CreateBlock::execute(RunContext& context)
{
if (_status == Status::SUCCESS && _compiled_graph) {
- _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
+ _graph->set_compiled_graph(std::move(_compiled_graph));
}
}
diff --git a/src/server/events/CreateBlock.hpp b/src/server/events/CreateBlock.hpp
index b0aa6aa4..047c01f3 100644
--- a/src/server/events/CreateBlock.hpp
+++ b/src/server/events/CreateBlock.hpp
@@ -58,7 +58,7 @@ private:
ClientUpdate _update;
GraphImpl* _graph;
BlockImpl* _block;
- CompiledGraph* _compiled_graph;
+ MPtr<CompiledGraph> _compiled_graph;
};
} // namespace Events
diff --git a/src/server/events/CreateGraph.cpp b/src/server/events/CreateGraph.cpp
index a59aadc6..7ebaeedc 100644
--- a/src/server/events/CreateGraph.cpp
+++ b/src/server/events/CreateGraph.cpp
@@ -42,7 +42,6 @@ CreateGraph::CreateGraph(Engine& engine,
, _properties(properties)
, _graph(NULL)
, _parent(NULL)
- , _compiled_graph(NULL)
{}
CreateGraph::~CreateGraph()
@@ -50,8 +49,6 @@ CreateGraph::~CreateGraph()
for (Event* ev : _child_events) {
delete ev;
}
-
- delete _compiled_graph;
}
void
@@ -173,9 +170,7 @@ CreateGraph::pre_process(PreProcessContext& ctx)
if (_parent->enabled()) {
_graph->enable();
}
- if (ctx.must_compile(_parent)) {
- _compiled_graph = CompiledGraph::compile(_parent);
- }
+ _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_parent);
}
_graph->activate(*_engine.buffer_factory());
@@ -201,7 +196,7 @@ CreateGraph::execute(RunContext& context)
{
if (_graph) {
if (_parent && _compiled_graph) {
- _compiled_graph = _parent->swap_compiled_graph(_compiled_graph);
+ _parent->set_compiled_graph(std::move(_compiled_graph));
}
for (Event* ev : _child_events) {
diff --git a/src/server/events/CreateGraph.hpp b/src/server/events/CreateGraph.hpp
index 7eee9c08..896a18f9 100644
--- a/src/server/events/CreateGraph.hpp
+++ b/src/server/events/CreateGraph.hpp
@@ -56,13 +56,13 @@ public:
private:
void build_child_events();
- const Raul::Path _path;
- Resource::Properties _properties;
- ClientUpdate _update;
- GraphImpl* _graph;
- GraphImpl* _parent;
- CompiledGraph* _compiled_graph;
- std::list<Event*> _child_events;
+ const Raul::Path _path;
+ Resource::Properties _properties;
+ ClientUpdate _update;
+ GraphImpl* _graph;
+ GraphImpl* _parent;
+ MPtr<CompiledGraph> _compiled_graph;
+ std::list<Event*> _child_events;
};
} // namespace Events
diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp
index bb8bb4d4..b6cabbeb 100644
--- a/src/server/events/CreatePort.cpp
+++ b/src/server/events/CreatePort.cpp
@@ -48,8 +48,6 @@ CreatePort::CreatePort(Engine& engine,
, _buf_type(0)
, _graph(NULL)
, _graph_port(NULL)
- , _ports_array(NULL)
- , _old_ports_array(NULL)
, _engine_port(NULL)
, _properties(properties)
{
@@ -156,8 +154,10 @@ CreatePort::pre_process(PreProcessContext& ctx)
_engine_port = _engine.driver()->create_port(_graph_port);
}
- _ports_array = new Raul::Array<PortImpl*>(old_n_ports + 1, NULL);
- _update = _graph_port->properties();
+ _ports_array = bufs.maid().make_managed<GraphImpl::Ports>(
+ old_n_ports + 1, nullptr);
+
+ _update = _graph_port->properties();
assert(_graph_port->index() == (uint32_t)index_i->second.get<int32_t>());
assert(_graph->num_ports_non_rt() == (uint32_t)old_n_ports + 1);
@@ -171,15 +171,15 @@ void
CreatePort::execute(RunContext& context)
{
if (_status == Status::SUCCESS) {
- _old_ports_array = _graph->external_ports();
- if (_old_ports_array) {
- for (uint32_t i = 0; i < _old_ports_array->size(); ++i) {
- (*_ports_array)[i] = (*_old_ports_array)[i];
+ const MPtr<GraphImpl::Ports>& old_ports = _graph->external_ports();
+ if (old_ports) {
+ for (uint32_t i = 0; i < old_ports->size(); ++i) {
+ (*_ports_array)[i] = (*old_ports)[i];
}
}
assert(!(*_ports_array)[_graph_port->index()]);
(*_ports_array)[_graph_port->index()] = _graph_port;
- _graph->external_ports(_ports_array);
+ _graph->set_external_ports(std::move(_ports_array));
if (_engine_port) {
_engine.driver()->add_port(context, _engine_port);
@@ -194,8 +194,6 @@ CreatePort::post_process()
if (respond() == Status::SUCCESS) {
_engine.broadcaster()->put(Node::path_to_uri(_path), _update);
}
-
- delete _old_ports_array;
}
void
diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp
index f3e2092d..2d32f1dd 100644
--- a/src/server/events/CreatePort.hpp
+++ b/src/server/events/CreatePort.hpp
@@ -24,6 +24,7 @@
#include "raul/Array.hpp"
#include "raul/Path.hpp"
+#include "BlockImpl.hpp"
#include "Event.hpp"
#include "PortType.hpp"
@@ -67,8 +68,7 @@ private:
LV2_URID _buf_type;
GraphImpl* _graph;
DuplexPort* _graph_port;
- Raul::Array<PortImpl*>* _ports_array; ///< New external port array for Graph
- Raul::Array<PortImpl*>* _old_ports_array;
+ MPtr<BlockImpl::Ports> _ports_array; ///< New external port array for Graph
EnginePort* _engine_port; ///< Driver port if on the root
Resource::Properties _properties;
Resource::Properties _update;
diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp
index b77f7c3e..788dfa2b 100644
--- a/src/server/events/Delete.cpp
+++ b/src/server/events/Delete.cpp
@@ -43,8 +43,6 @@ Delete::Delete(Engine& engine,
: Event(engine, client, id, time)
, _uri(uri)
, _engine_port(NULL)
- , _ports_array(NULL)
- , _compiled_graph(NULL)
, _disconnect_event(NULL)
{
if (Node::uri_is_path(uri)) {
@@ -55,7 +53,6 @@ Delete::Delete(Engine& engine,
Delete::~Delete()
{
delete _disconnect_event;
- delete _compiled_graph;
for (ControlBindings::Binding* b : _removed_bindings) {
delete b;
}
@@ -97,21 +94,15 @@ Delete::pre_process(PreProcessContext& ctx)
parent->remove_block(*_block);
_disconnect_event = new DisconnectAll(_engine, parent, _block.get());
_disconnect_event->pre_process(ctx);
-
- if (ctx.must_compile(parent)) {
- _compiled_graph = CompiledGraph::compile(parent);
- }
+ _compiled_graph = ctx.maybe_compile(*_engine.maid(), *parent);
} else if (_port) {
parent->remove_port(*_port);
_disconnect_event = new DisconnectAll(_engine, parent, _port.get());
_disconnect_event->pre_process(ctx);
- if (ctx.must_compile(parent)) {
- _compiled_graph = CompiledGraph::compile(parent);
- }
-
+ _compiled_graph = ctx.maybe_compile(*_engine.maid(), *parent);
if (parent->enabled()) {
- _ports_array = parent->build_ports_array();
+ _ports_array = parent->build_ports_array(*_engine.maid());
assert(_ports_array->size() == parent->num_ports_non_rt());
}
@@ -141,8 +132,7 @@ Delete::execute(RunContext& context)
GraphImpl* parent = _block ? _block->parent_graph() : NULL;
if (_port) {
parent = _port->parent_graph();
- _engine.maid()->dispose(parent->external_ports());
- parent->external_ports(_ports_array);
+ parent->set_external_ports(std::move(_ports_array));
if (_engine_port) {
_engine.driver()->remove_port(context, _engine_port);
@@ -150,7 +140,7 @@ Delete::execute(RunContext& context)
}
if (parent && _compiled_graph) {
- _compiled_graph = parent->swap_compiled_graph(_compiled_graph);
+ parent->set_compiled_graph(std::move(_compiled_graph));
}
}
diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp
index 1b34faf6..224cad3b 100644
--- a/src/server/events/Delete.hpp
+++ b/src/server/events/Delete.hpp
@@ -65,8 +65,8 @@ private:
SPtr<BlockImpl> _block; ///< Non-NULL iff a block
SPtr<DuplexPort> _port; ///< Non-NULL iff a port
EnginePort* _engine_port;
- Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Graph
- CompiledGraph* _compiled_graph; ///< Graph's new process order
+ MPtr<GraphImpl::Ports> _ports_array; ///< New (external) ports for Graph
+ MPtr<CompiledGraph> _compiled_graph; ///< Graph's new process order
DisconnectAll* _disconnect_event;
Store::Objects _removed_objects;
diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp
index 2ad258fd..2c13f9d4 100644
--- a/src/server/events/Delta.cpp
+++ b/src/server/events/Delta.cpp
@@ -60,7 +60,6 @@ Delta::Delta(Engine& engine,
, _remove(remove)
, _object(NULL)
, _graph(NULL)
- , _compiled_graph(NULL)
, _binding(NULL)
, _state(NULL)
, _context(context)
@@ -87,7 +86,6 @@ Delta::~Delta()
delete s;
delete _create_event;
- delete _compiled_graph;
}
void
@@ -355,7 +353,8 @@ Delta::pre_process(PreProcessContext& ctx)
op = SpecialType::ENABLE;
// FIXME: defer this until all other metadata has been processed
if (value.get<int32_t>() && !_graph->enabled()) {
- if (!(_compiled_graph = CompiledGraph::compile(_graph))) {
+ if (!(_compiled_graph = CompiledGraph::compile(
+ *_engine.maid(), *_graph))) {
_status = Status::COMPILATION_FAILED;
}
}
@@ -476,7 +475,7 @@ Delta::execute(RunContext& context)
if (_graph) {
if (value.get<int32_t>()) {
if (_compiled_graph) {
- _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
+ _graph->set_compiled_graph(std::move(_compiled_graph));
}
_graph->enable();
} else {
@@ -489,10 +488,9 @@ Delta::execute(RunContext& context)
case SpecialType::POLYPHONIC: {
GraphImpl* parent = reinterpret_cast<GraphImpl*>(object->parent());
if (value.get<int32_t>()) {
- object->apply_poly(
- context, *_engine.maid(), parent->internal_poly_process());
+ object->apply_poly(context, parent->internal_poly_process());
} else {
- object->apply_poly(context, *_engine.maid(), 1);
+ object->apply_poly(context, 1);
}
} break;
case SpecialType::POLYPHONY:
diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp
index d2326cd9..d751afc7 100644
--- a/src/server/events/Delta.hpp
+++ b/src/server/events/Delta.hpp
@@ -104,7 +104,7 @@ private:
ClientUpdate _update;
Ingen::Resource* _object;
GraphImpl* _graph;
- CompiledGraph* _compiled_graph;
+ MPtr<CompiledGraph> _compiled_graph;
ControlBindings::Binding* _binding;
LilvState* _state;
Resource::Graph _context;
diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp
index 3233cac4..9320163a 100644
--- a/src/server/events/Disconnect.cpp
+++ b/src/server/events/Disconnect.cpp
@@ -48,14 +48,12 @@ Disconnect::Disconnect(Engine& engine,
, _head_path(head_path)
, _graph(NULL)
, _impl(NULL)
- , _compiled_graph(NULL)
{
}
Disconnect::~Disconnect()
{
delete _impl;
- delete _compiled_graph;
}
Disconnect::Impl::Impl(Engine& e,
@@ -66,7 +64,6 @@ Disconnect::Impl::Impl(Engine& e,
, _tail(t)
, _head(h)
, _arc(graph->remove_arc(_tail, _head))
- , _voices(NULL)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
@@ -89,10 +86,9 @@ Disconnect::Impl::Impl(Engine& e,
if (_head->num_arcs() == 0) {
if (!_head->is_driver_port()) {
- _voices = new Raul::Array<PortImpl::Voice>(_head->poly());
- _head->pre_get_buffers(*_engine.buffer_factory(),
- _voices,
- _head->poly());
+ BufferFactory& bufs = *_engine.buffer_factory();
+ _voices = bufs.maid().make_managed<PortImpl::Voices>(_head->poly());
+ _head->pre_get_buffers(bufs, _voices, _head->poly());
if (_head->is_a(PortType::CONTROL) ||
_head->is_a(PortType::CV)) {
@@ -166,9 +162,7 @@ Disconnect::pre_process(PreProcessContext& ctx)
dynamic_cast<PortImpl*>(tail),
dynamic_cast<InputPort*>(head));
- if (ctx.must_compile(_graph)) {
- _compiled_graph = CompiledGraph::compile(_graph);
- }
+ _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_graph);
return Event::pre_process_done(Status::SUCCESS);
}
@@ -186,7 +180,7 @@ Disconnect::Impl::execute(RunContext& context, bool set_head_buffers)
if (set_head_buffers) {
if (_voices) {
- _engine.maid()->dispose(_head->set_voices(context, _voices));
+ _head->set_voices(context, std::move(_voices));
} else {
_head->setup_buffers(context, *_engine.buffer_factory(), _head->poly());
}
@@ -204,7 +198,7 @@ Disconnect::execute(RunContext& context)
if (_status == Status::SUCCESS) {
if (_impl->execute(context, true)) {
if (_compiled_graph) {
- _compiled_graph = _graph->swap_compiled_graph(_compiled_graph);
+ _graph->set_compiled_graph(std::move(_compiled_graph));
}
} else {
_status = Status::NOT_FOUND;
diff --git a/src/server/events/Disconnect.hpp b/src/server/events/Disconnect.hpp
index fa16f01f..3a7e0cff 100644
--- a/src/server/events/Disconnect.hpp
+++ b/src/server/events/Disconnect.hpp
@@ -60,10 +60,7 @@ public:
class Impl {
public:
- Impl(Engine& e,
- GraphImpl* graph,
- PortImpl* t,
- InputPort* h);
+ Impl(Engine& e, GraphImpl* graph, PortImpl* t, InputPort* h);
bool execute(RunContext& context, bool set_head_buffers);
@@ -71,19 +68,19 @@ public:
inline InputPort* head() { return _head; }
private:
- Engine& _engine;
- PortImpl* _tail;
- InputPort* _head;
- SPtr<ArcImpl> _arc;
- Raul::Array<PortImpl::Voice>* _voices;
+ Engine& _engine;
+ PortImpl* _tail;
+ InputPort* _head;
+ SPtr<ArcImpl> _arc;
+ MPtr<PortImpl::Voices> _voices;
};
private:
- const Raul::Path _tail_path;
- const Raul::Path _head_path;
- GraphImpl* _graph;
- Impl* _impl;
- CompiledGraph* _compiled_graph;
+ const Raul::Path _tail_path;
+ const Raul::Path _head_path;
+ GraphImpl* _graph;
+ Impl* _impl;
+ MPtr<CompiledGraph> _compiled_graph;
};
} // namespace Events
diff --git a/src/server/events/DisconnectAll.cpp b/src/server/events/DisconnectAll.cpp
index 597f8e9b..16b62302 100644
--- a/src/server/events/DisconnectAll.cpp
+++ b/src/server/events/DisconnectAll.cpp
@@ -51,7 +51,6 @@ DisconnectAll::DisconnectAll(Engine& engine,
, _parent(NULL)
, _block(NULL)
, _port(NULL)
- , _compiled_graph(NULL)
, _deleting(false)
{
}
@@ -67,7 +66,6 @@ DisconnectAll::DisconnectAll(Engine& engine,
, _parent(parent)
, _block(dynamic_cast<BlockImpl*>(object))
, _port(dynamic_cast<PortImpl*>(object))
- , _compiled_graph(NULL)
, _deleting(true)
{
}
@@ -76,8 +74,6 @@ DisconnectAll::~DisconnectAll()
{
for (auto& i : _impls)
delete i;
-
- delete _compiled_graph;
}
bool
@@ -138,8 +134,9 @@ DisconnectAll::pre_process(PreProcessContext& ctx)
dynamic_cast<InputPort*>(a->head())));
}
- if (!_deleting && ctx.must_compile(_parent)) {
- if (!(_compiled_graph = CompiledGraph::compile(_parent))) {
+ if (!_deleting && ctx.must_compile(*_parent)) {
+ if (!(_compiled_graph = CompiledGraph::compile(
+ *_engine.maid(), *_parent))) {
return Event::pre_process_done(Status::COMPILATION_FAILED);
}
}
@@ -158,7 +155,7 @@ DisconnectAll::execute(RunContext& context)
}
if (_compiled_graph) {
- _compiled_graph = _parent->swap_compiled_graph(_compiled_graph);
+ _parent->set_compiled_graph(std::move(_compiled_graph));
}
}
diff --git a/src/server/events/DisconnectAll.hpp b/src/server/events/DisconnectAll.hpp
index 1fc1f757..abfa0572 100644
--- a/src/server/events/DisconnectAll.hpp
+++ b/src/server/events/DisconnectAll.hpp
@@ -64,14 +64,14 @@ public:
private:
typedef std::list<Disconnect::Impl*> Impls;
- Raul::Path _parent_path;
- Raul::Path _path;
- GraphImpl* _parent;
- BlockImpl* _block;
- PortImpl* _port;
- Impls _impls;
- CompiledGraph* _compiled_graph;
- bool _deleting;
+ Raul::Path _parent_path;
+ Raul::Path _path;
+ GraphImpl* _parent;
+ BlockImpl* _block;
+ PortImpl* _port;
+ Impls _impls;
+ MPtr<CompiledGraph> _compiled_graph;
+ bool _deleting;
};
} // namespace Events
diff --git a/src/server/events/Mark.cpp b/src/server/events/Mark.cpp
index c72cc14f..eee2d552 100644
--- a/src/server/events/Mark.cpp
+++ b/src/server/events/Mark.cpp
@@ -35,9 +35,6 @@ Mark::Mark(Engine& engine,
Mark::~Mark()
{
- for (const auto& g : _compiled_graphs) {
- delete g.second;
- }
}
bool
@@ -57,9 +54,10 @@ Mark::pre_process(PreProcessContext& ctx)
ctx.set_in_bundle(false);
if (!ctx.dirty_graphs().empty()) {
for (GraphImpl* g : ctx.dirty_graphs()) {
- CompiledGraph* cg = CompiledGraph::compile(g);
+ MPtr<CompiledGraph> cg = CompiledGraph::compile(
+ *_engine.maid(), *g);
if (cg) {
- _compiled_graphs.insert(std::make_pair(g, cg));
+ _compiled_graphs.insert(std::make_pair(g, std::move(cg)));
}
}
ctx.dirty_graphs().clear();
@@ -74,7 +72,7 @@ void
Mark::execute(RunContext& context)
{
for (auto& g : _compiled_graphs) {
- g.second = g.first->swap_compiled_graph(g.second);
+ g.first->set_compiled_graph(std::move(g.second));
}
}
diff --git a/src/server/events/Mark.hpp b/src/server/events/Mark.hpp
index 68ba5149..4a5e83bf 100644
--- a/src/server/events/Mark.hpp
+++ b/src/server/events/Mark.hpp
@@ -53,7 +53,7 @@ public:
Execution get_execution() const;
private:
- typedef std::map<GraphImpl*, CompiledGraph*> CompiledGraphs;
+ typedef std::map<GraphImpl*, MPtr<CompiledGraph>> CompiledGraphs;
CompiledGraphs _compiled_graphs;
Type _type;
diff --git a/src/server/internals/BlockDelay.cpp b/src/server/internals/BlockDelay.cpp
index d52ae721..c0e8dded 100644
--- a/src/server/internals/BlockDelay.cpp
+++ b/src/server/internals/BlockDelay.cpp
@@ -47,7 +47,7 @@ BlockDelayNode::BlockDelayNode(InternalPlugin* plugin,
: InternalBlock(plugin, symbol, polyphonic, parent, srate)
{
const Ingen::URIs& uris = bufs.uris();
- _ports = new Raul::Array<PortImpl*>(2);
+ _ports = bufs.maid().make_managed<Ports>(2);
_in_port = new InputPort(bufs, this, Raul::Symbol("in"), 0, 1,
PortType::AUDIO, 0, bufs.forge().make(0.0f));
diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp
index 4b6f9c02..0366cbf0 100644
--- a/src/server/internals/Controller.cpp
+++ b/src/server/internals/Controller.cpp
@@ -51,7 +51,7 @@ ControllerNode::ControllerNode(InternalPlugin* plugin,
, _learning(false)
{
const Ingen::URIs& uris = bufs.uris();
- _ports = new Raul::Array<PortImpl*>(7);
+ _ports = bufs.maid().make_managed<Ports>(7);
const Atom zero = bufs.forge().make(0.0f);
const Atom one = bufs.forge().make(1.0f);
diff --git a/src/server/internals/Note.cpp b/src/server/internals/Note.cpp
index 564ae34c..cc592794 100644
--- a/src/server/internals/Note.cpp
+++ b/src/server/internals/Note.cpp
@@ -53,12 +53,11 @@ NoteNode::NoteNode(InternalPlugin* plugin,
GraphImpl* parent,
SampleRate srate)
: InternalBlock(plugin, symbol, polyphonic, parent, srate)
- , _voices(new Raul::Array<Voice>(_polyphony))
- , _prepared_voices(NULL)
+ , _voices(bufs.maid().make_managed<Voices>(_polyphony))
, _sustain(false)
{
const Ingen::URIs& uris = bufs.uris();
- _ports = new Raul::Array<PortImpl*>(8);
+ _ports = bufs.maid().make_managed<Ports>(8);
const Atom zero = bufs.forge().make(0.0f);
const Atom one = bufs.forge().make(1.0f);
@@ -131,7 +130,6 @@ NoteNode::NoteNode(InternalPlugin* plugin,
NoteNode::~NoteNode()
{
- delete _voices;
}
bool
@@ -145,22 +143,21 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly)
if (_prepared_voices && poly <= _prepared_voices->size())
return true;
- _prepared_voices = new Raul::Array<Voice>(poly, *_voices, Voice());
+ _prepared_voices = bufs.maid().make_managed<Voices>(
+ poly, *_voices, Voice());
return true;
}
bool
-NoteNode::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly)
+NoteNode::apply_poly(RunContext& context, uint32_t poly)
{
- if (!BlockImpl::apply_poly(context, maid, poly))
+ if (!BlockImpl::apply_poly(context, poly))
return false;
if (_prepared_voices) {
assert(_polyphony <= _prepared_voices->size());
- maid.dispose(_voices);
- _voices = _prepared_voices;
- _prepared_voices = NULL;
+ _voices = std::move(_prepared_voices);
}
assert(_polyphony <= _voices->size());
diff --git a/src/server/internals/Note.hpp b/src/server/internals/Note.hpp
index 08d1b358..e8593768 100644
--- a/src/server/internals/Note.hpp
+++ b/src/server/internals/Note.hpp
@@ -48,7 +48,7 @@ public:
~NoteNode();
bool prepare_poly(BufferFactory& bufs, uint32_t poly);
- bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly);
+ bool apply_poly(RunContext& context, uint32_t poly);
void run(RunContext& context);
@@ -84,12 +84,15 @@ private:
SampleCount time;
};
+ typedef Raul::Array<Voice> Voices;
+
void free_voice(RunContext& context, uint32_t voice, FrameTime time);
- Raul::Array<Voice>* _voices;
- Raul::Array<Voice>* _prepared_voices;
- Key _keys[128];
- bool _sustain; ///< Whether or not hold pedal is depressed
+ MPtr<Voices> _voices;
+ MPtr<Voices> _prepared_voices;
+
+ Key _keys[128];
+ bool _sustain; ///< Whether or not hold pedal is depressed
InputPort* _midi_in_port;
OutputPort* _freq_port;
diff --git a/src/server/internals/Time.cpp b/src/server/internals/Time.cpp
index 0f4bdd56..2da2a2ae 100644
--- a/src/server/internals/Time.cpp
+++ b/src/server/internals/Time.cpp
@@ -45,7 +45,7 @@ TimeNode::TimeNode(InternalPlugin* plugin,
: InternalBlock(plugin, symbol, false, parent, srate)
{
const Ingen::URIs& uris = bufs.uris();
- _ports = new Raul::Array<PortImpl*>(1);
+ _ports = bufs.maid().make_managed<Ports>(1);
_notify_port = new OutputPort(
bufs, this, Raul::Symbol("notify"), 0, 1,
diff --git a/src/server/internals/Trigger.cpp b/src/server/internals/Trigger.cpp
index 68089283..88bfd3f1 100644
--- a/src/server/internals/Trigger.cpp
+++ b/src/server/internals/Trigger.cpp
@@ -51,7 +51,7 @@ TriggerNode::TriggerNode(InternalPlugin* plugin,
, _learning(false)
{
const Ingen::URIs& uris = bufs.uris();
- _ports = new Raul::Array<PortImpl*>(6);
+ _ports = bufs.maid().make_managed<Ports>(6);
const Atom zero = bufs.forge().make(0.0f);
diff --git a/wscript b/wscript
index bdd4ef1f..7a15d63f 100644
--- a/wscript
+++ b/wscript
@@ -85,7 +85,7 @@ def configure(conf):
autowaf.check_pkg(conf, 'sratom-0', uselib_store='SRATOM',
atleast_version='0.4.6', mandatory=True)
autowaf.check_pkg(conf, 'raul', uselib_store='RAUL',
- atleast_version='0.8.6', mandatory=True)
+ atleast_version='0.8.7', mandatory=True)
autowaf.check_pkg(conf, 'serd-0', uselib_store='SERD',
atleast_version='0.18.0', mandatory=False)
autowaf.check_pkg(conf, 'sord-0', uselib_store='SORD',