#include <cassert>
-#include "pbd/convert.h"
#include "pbd/debug.h"
+#include "pbd/enum_convert.h"
#include "pbd/enumwriter.h"
#include "pbd/error.h"
#include "pbd/failed_constructor.h"
+#include "pbd/stacktrace.h"
#include "pbd/xml++.h"
#include "ardour/presentation_info.h"
+#include "ardour/selection.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
+
+namespace PBD {
+ DEFINE_ENUM_CONVERT(ARDOUR::PresentationInfo::Flag);
+}
using namespace ARDOUR;
using namespace PBD;
using std::string;
string PresentationInfo::state_node_name = X_("PresentationInfo");
-PBD::Signal0<void> PresentationInfo::Change;
+
+PBD::Signal1<void,PropertyChange const &> PresentationInfo::Change;
+Glib::Threads::Mutex PresentationInfo::static_signal_lock;
+int PresentationInfo::_change_signal_suspended = 0;
+PBD::PropertyChange PresentationInfo::_pending_static_changes;
+int PresentationInfo::selection_counter= 0;
namespace ARDOUR {
namespace Properties {
}
}
+void
+PresentationInfo::suspend_change_signal ()
+{
+ g_atomic_int_add (&_change_signal_suspended, 1);
+}
+
+void
+PresentationInfo::unsuspend_change_signal ()
+{
+ Glib::Threads::Mutex::Lock lm (static_signal_lock);
+
+ if (g_atomic_int_get (const_cast<gint*> (&_change_signal_suspended)) == 1) {
+
+ /* atomically grab currently pending flags */
+
+ PropertyChange pc = _pending_static_changes;
+ _pending_static_changes.clear ();
+
+ if (!pc.empty()) {
+
+ /* emit the signal with further emissions still blocked
+ * by _change_signal_suspended, but not by the lock.
+ *
+ * This means that if the handlers modify other PI
+ * states, the signal for that won't be sent while they
+ * are handling the current signal.
+ */
+ lm.release ();
+ Change (pc); /* EMIT SIGNAL */
+ lm.acquire ();
+ }
+ }
+
+ g_atomic_int_add (const_cast<gint*>(&_change_signal_suspended), -1);
+}
+
+void
+PresentationInfo::send_static_change (const PropertyChange& what_changed)
+{
+ if (what_changed.empty()) {
+ return;
+ }
+
+
+ if (g_atomic_int_get (&_change_signal_suspended)) {
+ Glib::Threads::Mutex::Lock lm (static_signal_lock);
+ _pending_static_changes.add (what_changed);
+ return;
+ }
+
+ Change (what_changed);
+}
+
const PresentationInfo::order_t PresentationInfo::max_order = UINT32_MAX;
const PresentationInfo::Flag PresentationInfo::Bus = PresentationInfo::Flag (PresentationInfo::AudioBus|PresentationInfo::MidiBus);
const PresentationInfo::Flag PresentationInfo::Track = PresentationInfo::Flag (PresentationInfo::AudioTrack|PresentationInfo::MidiTrack);
/* OrderSet is set */
}
PresentationInfo::PresentationInfo (PresentationInfo const& other)
- : _order (other.order())
+ : PBD::Stateful ()
+ , _order (other.order())
, _flags (other.flags())
, _color (other.color())
{
PresentationInfo::get_state ()
{
XMLNode* node = new XMLNode (state_node_name);
- node->add_property ("order", PBD::to_string (_order, std::dec));
- node->add_property ("flags", enum_2_string (_flags));
- node->add_property ("color", PBD::to_string (_color, std::dec));
+ node->set_property ("order", _order);
+ node->set_property ("flags", _flags);
+ node->set_property ("color", _color);
return *node;
}
return -1;
}
- XMLProperty const* prop;
PropertyChange pc;
- if ((prop = node.property (X_("order"))) != 0) {
- order_t o = atoi (prop->value());
+ order_t o;
+ if (node.get_property (X_("order"), o)) {
if (o != _order) {
pc.add (Properties::order);
_order = o;
}
- _order = atoi (prop->value());
+ _order = o; // huh?
}
- if ((prop = node.property (X_("flags"))) != 0) {
- Flag f = Flag (string_2_enum (prop->value(), f));
+ Flag f;
+ if (node.get_property (X_("flags"), f)) {
if ((f&Hidden) != (_flags&Hidden)) {
pc.add (Properties::hidden);
}
_flags = f;
}
- if ((prop = node.property (X_("color"))) != 0) {
- color_t c = atoi (prop->value());
+ color_t c;
+ if (node.get_property (X_("color"), c)) {
if (c != _color) {
- pc.add (Properties::order);
+ pc.add (Properties::color);
_color = c;
}
}
XMLNode* child = *niter;
if (child->name() == PresentationInfo::state_node_name) {
- XMLProperty const* prop = child->property (X_("flags"));
- if (prop) {
- Flag f = (Flag) string_2_enum (prop->value(), f);
+ Flag f;
+ if (child->get_property (X_("flags"), f)) {
return f;
}
}
if (c != _color) {
_color = c;
send_change (PropertyChange (Properties::color));
+ send_static_change (PropertyChange (Properties::color));
}
}
* this is heuristic, but it is fairly realistic. who will ever set
* a color to completely transparent black? only the constructor ..
*/
-
return _color != 0;
}
-void
-PresentationInfo::set_selected (bool yn)
-{
- if (yn != selected()) {
- if (yn) {
- _flags = Flag (_flags | Selected);
- } else {
- _flags = Flag (_flags & ~Selected);
- }
- send_change (PropertyChange (Properties::selected));
- }
-}
-
void
PresentationInfo::set_hidden (bool yn)
{
}
send_change (PropertyChange (Properties::hidden));
+ send_static_change (PropertyChange (Properties::hidden));
}
}
if (order != _order) {
_order = order;
send_change (PropertyChange (Properties::order));
+ send_static_change (PropertyChange (Properties::order));
}
}