summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/mmf/mmf_medianode.cpp
diff options
context:
space:
mode:
authoraxis <qt-info@nokia.com>2010-01-21 12:20:33 (GMT)
committeraxis <qt-info@nokia.com>2010-01-21 12:20:33 (GMT)
commit833bea1f71ed685e5f371d93f6f5c2da7be546e5 (patch)
tree09e3f60311ebf8af123a9e61f27908dd87118109 /src/3rdparty/phonon/mmf/mmf_medianode.cpp
parentd609f7d1963e06d05fa6f7e4a098a304a177bc68 (diff)
parentd83e82e5c8a7fa0f6b1dcc4b1ab56f22afd942f6 (diff)
downloadQt-833bea1f71ed685e5f371d93f6f5c2da7be546e5.zip
Qt-833bea1f71ed685e5f371d93f6f5c2da7be546e5.tar.gz
Qt-833bea1f71ed685e5f371d93f6f5c2da7be546e5.tar.bz2
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/qt-s60-public
Conflicts: mkspecs/features/symbian/platform_paths.prf
Diffstat (limited to 'src/3rdparty/phonon/mmf/mmf_medianode.cpp')
-rw-r--r--src/3rdparty/phonon/mmf/mmf_medianode.cpp153
1 files changed, 92 insertions, 61 deletions
diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.cpp b/src/3rdparty/phonon/mmf/mmf_medianode.cpp
index 253c5e7..ca413d9 100644
--- a/src/3rdparty/phonon/mmf/mmf_medianode.cpp
+++ b/src/3rdparty/phonon/mmf/mmf_medianode.cpp
@@ -29,92 +29,123 @@ using namespace Phonon::MMF;
\internal
*/
-MMF::MediaNode::MediaNode(QObject *parent) : QObject::QObject(parent)
- , m_source(0)
- , m_target(0)
- , m_isApplied(false)
+MMF::MediaNode::MediaNode(QObject *parent)
+ : QObject(parent)
+ , m_mediaObject(qobject_cast<MediaObject *>(this))
+ , m_input(0)
{
-}
-
-bool MMF::MediaNode::connectMediaNode(MediaNode *target)
-{
- m_target = target;
- m_target->setSource(this);
- return applyNodesOnMediaObject(target);
}
-bool MMF::MediaNode::disconnectMediaNode(MediaNode *target)
+MMF::MediaNode::~MediaNode()
{
- Q_UNUSED(target);
- m_target = 0;
- m_isApplied = false;
- return true;
+ // Phonon framework ensures nodes are disconnected before being destroyed.
+ Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO,
+ "Media node not disconnected before destruction");
}
-void MMF::MediaNode::setSource(MediaNode *source)
+bool MMF::MediaNode::connectOutput(MediaNode *output)
{
- m_source = source;
+ Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer");
+
+ bool connected = false;
+
+ // Check that this connection will not result in a graph which
+ // containing more than one MediaObject
+ const bool mediaObjectMisMatch =
+ m_mediaObject
+ && output->m_mediaObject
+ && m_mediaObject != output->m_mediaObject;
+
+ const bool canConnect =
+ !output->isMediaObject()
+ && !output->m_input
+ && !m_outputs.contains(output);
+
+ if (canConnect && !mediaObjectMisMatch) {
+ output->m_input = this;
+ m_outputs += output;
+ updateMediaObject();
+ connected = true;
+ }
+
+ return connected;
}
-MMF::MediaNode *MMF::MediaNode::source() const
+bool MMF::MediaNode::disconnectOutput(MediaNode *output)
{
- return m_source;
+ Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer");
+
+ bool disconnected = false;
+
+ if (m_outputs.contains(output) && this == output->m_input) {
+ output->m_input = 0;
+ const bool removed = m_outputs.removeOne(output);
+ Q_ASSERT_X(removed, Q_FUNC_INFO, "Output removal failed");
+
+ Q_ASSERT_X(!m_outputs.contains(output), Q_FUNC_INFO,
+ "Output list contains duplicate entries");
+
+ // Perform traversal across each of the two graphs separately
+ updateMediaObject();
+ output->updateMediaObject();
+
+ disconnected = true;
+ }
+
+ return disconnected;
}
-MMF::MediaNode *MMF::MediaNode::target() const
+bool MMF::MediaNode::isMediaObject() const
{
- return m_target;
+ return (qobject_cast<const MediaObject *>(this) != 0);
}
-bool MMF::MediaNode::applyNodesOnMediaObject(MediaNode *)
+void MMF::MediaNode::updateMediaObject()
{
- // Algorithmically, this can be expressed in a more efficient way by
- // exercising available assumptions, but it complicates code for input
- // data(length of the graph) which typically is very small.
-
- // First, we go to the very beginning of the graph.
- MMF::MediaNode *current = this;
- do {
- MediaNode *const candidate = current->source();
- if (candidate)
- current = candidate;
- else
- break;
- }
- while (current);
-
- // Now we do two things, while walking to the other end:
- // 1. Find the MediaObject, if present
- // 2. Collect a list of all unapplied MediaNodes
-
- QList<MediaNode *> unapplied;
- MMF::MediaObject *mo = 0;
+ QList<MediaNode *> nodes;
+ MediaObject *mediaObject = 0;
- do {
- if (!current->m_isApplied)
- unapplied.append(current);
+ // Traverse the graph, collecting a list of nodes, and locating
+ // the MediaObject node, if present
+ visit(nodes, mediaObject);
- if (!mo)
- mo = qobject_cast<MMF::MediaObject *>(current);
+ MediaNode *node = 0;
+ foreach(node, nodes)
+ node->setMediaObject(mediaObject);
+}
- current = current->target();
+void MMF::MediaNode::setMediaObject(MediaObject *mediaObject)
+{
+ if(!isMediaObject() && m_mediaObject != mediaObject) {
+ if (!mediaObject)
+ disconnectMediaObject(m_mediaObject);
+ else {
+ Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO, "MediaObject already set");
+ connectMediaObject(mediaObject);
+ }
+ m_mediaObject = mediaObject;
}
- while (current);
+}
- // Now, lets activate all the objects, if we found the MediaObject.
+void MMF::MediaNode::visit(QList<MediaNode *>& visited, MediaObject*& mediaObject)
+{
+ if (isMediaObject()) {
+ // There can never be more than one MediaObject per graph, due to the
+ // mediaObjectMisMatch test in connectOutput().
+ Q_ASSERT_X(!mediaObject, Q_FUNC_INFO, "MediaObject already found");
+ mediaObject = static_cast<MediaObject *>(this);
+ }
- if (mo) {
- for (int i = 0; i < unapplied.count(); ++i) {
- MediaNode *const at = unapplied.at(i);
+ visited += this;
- // We don't want to apply MediaObject on itself.
- if (at != mo)
- at->activateOnMediaObject(mo);
- }
- }
+ if (m_input && !visited.contains(m_input))
+ m_input->visit(visited, mediaObject);
- return true;
+ MediaNode *output = 0;
+ foreach (output, m_outputs)
+ if (!visited.contains(output))
+ output->visit(visited, mediaObject);
}
QT_END_NAMESPACE