From 5dcac50655a6635352e4542888e091bef515f865 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 17 Jul 2012 22:36:55 +0000 Subject: Wrap notification stuff behind simple API and hide details in Context. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4545 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/Context.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++ src/server/Context.hpp | 33 +++++++++++++++++++----------- src/server/ControlBindings.cpp | 13 ++++++------ src/server/InputPort.cpp | 8 ++++---- src/server/PortImpl.cpp | 11 +++++----- src/server/PostProcessor.cpp | 9 +-------- src/server/wscript | 1 + 7 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 src/server/Context.cpp diff --git a/src/server/Context.cpp b/src/server/Context.cpp new file mode 100644 index 00000000..9979415b --- /dev/null +++ b/src/server/Context.cpp @@ -0,0 +1,46 @@ +/* + This file is part of Ingen. + Copyright 2007-2012 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#include "Context.hpp" + +namespace Ingen { +namespace Server { + +void +Context::notify(Notification::Type type, + FrameTime time, + PortImpl* port, + const Raul::Atom& value, + const ControlBindings::Type btype) +{ + const Notification n = Notification::make(type, time, port, value, btype); + _event_sink.write(sizeof(n), &n); +} + +void +Context::emit_notifications() +{ + const uint32_t read_space = _event_sink.read_space(); + Notification note; + for (uint32_t i = 0; i < read_space; i += sizeof(note)) { + if (_event_sink.read(sizeof(note), ¬e) == sizeof(note)) { + Notification::post_process(note, _engine); + } + } +} + +} // namespace Server +} // namespace Ingen diff --git a/src/server/Context.hpp b/src/server/Context.hpp index fa2a2c7e..8afe1caa 100644 --- a/src/server/Context.hpp +++ b/src/server/Context.hpp @@ -22,6 +22,7 @@ #include "ingen/shared/World.hpp" #include "types.hpp" +#include "Notification.hpp" namespace Ingen { namespace Server { @@ -61,20 +62,31 @@ public: virtual ~Context() {} - ID id() const { return _id; } + /** Send a notification from this run context. */ + void notify( + Notification::Type type = Notification::NIL, + FrameTime time = 0, + PortImpl* port = 0, + const Raul::Atom& value = Raul::Atom(), + const ControlBindings::Type btype = ControlBindings::NULL_CONTROL); - void locate(FrameTime s, SampleCount nframes, SampleCount offset) { - _start = s; - _end = s + nframes; + /** Emit pending notifications in some other non-realtime thread. */ + void emit_notifications(); + + inline ID id() const { return _id; } + + inline void locate(FrameTime s, SampleCount nframes, SampleCount offset) { + _start = s; + _end = s + nframes; _nframes = nframes; - _offset = offset; + _offset = offset; } - void locate(const Context& other) { - _start = other._start; - _end = other._end; + inline void locate(const Context& other) { + _start = other._start; + _end = other._end; _nframes = other._nframes; - _offset = other._offset; + _offset = other._offset; } inline Engine& engine() const { return _engine; } @@ -84,9 +96,6 @@ public: inline SampleCount offset() const { return _offset; } inline bool realtime() const { return _realtime; } - inline const Raul::RingBuffer & event_sink() const { return _event_sink; } - inline Raul::RingBuffer& event_sink() { return _event_sink; } - protected: Engine& _engine; ///< Engine we're running in ID _id; ///< Fast ID for this context diff --git a/src/server/ControlBindings.cpp b/src/server/ControlBindings.cpp index 48ab1ceb..844568d8 100644 --- a/src/server/ControlBindings.cpp +++ b/src/server/ControlBindings.cpp @@ -281,9 +281,7 @@ ControlBindings::set_port_value(ProcessContext& context, reinterpret_cast(port->buffer(v).get())->set_value( port_value.get_float(), context.start(), context.start()); - const Notification note = Notification::make( - Notification::PORT_VALUE, context.start(), port, port_value); - context.event_sink().write(sizeof(note), ¬e); + context.notify(Notification::PORT_VALUE, context.start(), port, port_value); } bool @@ -299,10 +297,11 @@ ControlBindings::bind(ProcessContext& context, Key key) _bindings->insert(make_pair(key, _learn_port)); - const Notification note = Notification::make( - Notification::PORT_BINDING, context.start(), _learn_port, - context.engine().world()->forge().make(key.num), key.type); - context.event_sink().write(sizeof(note), ¬e); + context.notify(Notification::PORT_BINDING, + context.start(), + _learn_port, + context.engine().world()->forge().make(key.num), + key.type); _learn_port = NULL; return true; diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp index 25059242..d94a971b 100644 --- a/src/server/InputPort.cpp +++ b/src/server/InputPort.cpp @@ -154,10 +154,10 @@ InputPort::remove_edge(ProcessContext& context, const OutputPort* tail) if (_edges.empty()) { if (is_a(PortType::AUDIO)) { // Send an update peak of 0.0 to reset to silence - const Notification note = Notification::make( - Notification::PORT_ACTIVITY, context.start(), this, - context.engine().world()->forge().make(0.0f)); - context.event_sink().write(sizeof(note), ¬e); + context.notify(Notification::PORT_ACTIVITY, + context.start(), + this, + context.engine().world()->forge().make(0.0f)); } _broadcast = false; } diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index 2fdca1ed..d4fcb6c8 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -236,9 +236,10 @@ PortImpl::broadcast_value(Context& context, bool force) if (_buffer_type == _bufs.uris().atom_Sequence) { LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)buffer(0)->atom(); if (seq->atom.size > sizeof(LV2_Atom_Sequence_Body)) { - const Notification note = Notification::make( - Notification::PORT_ACTIVITY, context.start(), this, forge.make(true)); - context.event_sink().write(sizeof(note), ¬e); + context.notify(Notification::PORT_ACTIVITY, + context.start(), + this, + forge.make(true)); } } break; @@ -246,9 +247,7 @@ PortImpl::broadcast_value(Context& context, bool force) if (val.is_valid() && (force || val != _last_broadcasted_value)) { _last_broadcasted_value = val; - const Notification note = Notification::make( - ntype, context.start(), this, val); - context.event_sink().write(sizeof(note), ¬e); + context.notify(ntype, context.start(), this, val); } } diff --git a/src/server/PostProcessor.cpp b/src/server/PostProcessor.cpp index 3604ace1..df83cc7b 100644 --- a/src/server/PostProcessor.cpp +++ b/src/server/PostProcessor.cpp @@ -66,14 +66,7 @@ PostProcessor::process() /* FIXME: process events from all threads if parallel */ /* Process audio thread generated events */ - Raul::RingBuffer& event_sink = _engine.process_context().event_sink(); - const uint32_t read_space = event_sink.read_space(); - Notification note; - for (uint32_t i = 0; i < read_space; i += sizeof(note)) { - if (event_sink.read(sizeof(note), ¬e) == sizeof(note)) { - Notification::post_process(note, _engine); - } - } + _engine.process_context().emit_notifications(); /* Process normal events */ Event* ev = _head.get(); diff --git a/src/server/wscript b/src/server/wscript index 95fcb706..1c5e57bd 100644 --- a/src/server/wscript +++ b/src/server/wscript @@ -7,6 +7,7 @@ def build(bld): Broadcaster.cpp Buffer.cpp BufferFactory.cpp + Context.cpp ControlBindings.cpp DuplexPort.cpp EdgeImpl.cpp -- cgit v1.2.1