/* dtkComposerTransmitterReceiver.tpp --- * * Author: Thibaud Kloczko, Inria. * Created: Tue Feb 14 12:56:04 2012 (+0100) */ /* Commentary: * */ /* Change log: * */ #ifndef DTKCOMPOSERTRANSMITTERRECEIVER_TPP #define DTKCOMPOSERTRANSMITTERRECEIVER_TPP #include "dtkComposerTransmitterEmitter.h" #include "dtkComposerTransmitterVariant.h" #include // ///////////////////////////////////////////////////////////////// // dtkComposerTransmitterReceiver implementation // ///////////////////////////////////////////////////////////////// //! Constructs an empty receiver. /*! * */ template dtkComposerTransmitterReceiver::dtkComposerTransmitterReceiver(dtkComposerNode *parent) : dtkComposerTransmitterAbstractReceiver(parent) { m_data = NULL; d->data_type = qMetaTypeId(m_data); active_emitter = NULL; active_variant = NULL; }; //! Destroys the receiver. /*! * */ template dtkComposerTransmitterReceiver::~dtkComposerTransmitterReceiver(void) { m_data = NULL; active_emitter = NULL; active_variant = NULL; }; //! /*! * */ template void dtkComposerTransmitterReceiver::clearData(void) { d->variant.clear(); d->object = NULL; d->container = NULL; d->matrix = NULL; if (m_data) delete m_data; m_data = NULL; } //! Returns the data as a modifiable reference. /*! * */ template T *dtkComposerTransmitterReceiver::dataFromEmitter(void) { if (active_emitter) return active_emitter->data(); if (active_variant) return active_variant->data(); return NULL; }; //! Returns the data as a modifiable reference. /*! * */ template T *dtkComposerTransmitterReceiver::data(void) { T *data = this->dataFromEmitter(); if (!data) return NULL; switch (this->dataTransmission()) { case dtkComposerTransmitter::AutoCopy: if (this->enableCopy()) { if (!m_data) { if (dtkTypeInfo::dtkAbstractObjectPointer) m_data = reinterpret_cast(reinterpret_cast(data)->clone()); else m_data = new T(*data); } else { *m_data = *data; } return m_data; } else { return data; } break; case dtkComposerTransmitter::Copy: if (!m_data) { if (dtkTypeInfo::dtkAbstractObjectPointer) m_data = reinterpret_cast(reinterpret_cast(data)->clone()); else m_data = new T(*data); } else { *m_data = *data; } return m_data; break; case dtkComposerTransmitter::Reference: return data; break; default: return NULL; break; }; return NULL; }; //! Returns the data as a modifiable reference. /*! * */ template T *dtkComposerTransmitterReceiver::constData(void) { if (this->dataTransmission() != dtkComposerTransmitter::Copy) { return this->dataFromEmitter(); } else { T *data = this->dataFromEmitter(); if (!data) return NULL; if (!m_data) { if (dtkTypeInfo::dtkAbstractObjectPointer) m_data = reinterpret_cast(reinterpret_cast(data)->clone()); else m_data = new T(*data); } else { *m_data = *data; } return m_data; } return NULL; }; //! Returns the data as a modifiable reference. /*! * */ template dtkAbstractObject *dtkComposerTransmitterReceiver::object(void) { T *data = this->data(); if (data && dtkTypeInfo::dtkAbstractObjectPointer) return reinterpret_cast(data); return NULL; }; //! Returns the data as a modifiable reference. /*! * */ template dtkMatrixReal *dtkComposerTransmitterReceiver::matrix(void) { T *data = this->data(); if (data && dtkTypeInfo::dtkMatrixRealPointer) return reinterpret_cast(data); return NULL; }; //! Returns the data as a modifiable reference. /*! * */ template QVariant& dtkComposerTransmitterReceiver::variant(void) { d->variant.setValue(this->data()); return d->variant; }; //! /*! * */ template QVector dtkComposerTransmitterReceiver::allData(void) { QVector list; int i; int count = this->emitters.count(); for (i = 0; i < count; ++i) if (this->emitters.at(i)->active()) { list << this->emitters.at(i)->data(); } count = this->variants.count(); dtkComposerTransmitterVariant *var = NULL; for (i = 0; i < count; ++i) { var = this->variants.at(i); if (var->active()) { list << var->data(); } } return list; }; //! /*! * */ template void dtkComposerTransmitterReceiver::activateEmitter(dtkComposerTransmitter *emitter) { active_emitter = NULL; active_variant = NULL; foreach (dtkComposerTransmitterEmitter *e, emitters) { if (emitter == static_cast(e)) { active_emitter = e; break; } } } //! /*! * */ template void dtkComposerTransmitterReceiver::activateEmitter(dtkComposerTransmitterVariant *emitter) { active_emitter = NULL; active_variant = NULL; foreach (dtkComposerTransmitterVariant *v, variants) { if (emitter == v) { active_variant = v; break; } } } //! /*! * */ template void dtkComposerTransmitterReceiver::setReady(bool ready) { if (d->ready == ready) return; d->ready = ready; if (this->active_emitter) { this->active_emitter->updateCopyCounter(ready); } else if (this->active_variant) { this->active_variant->updateCopyCounter(ready); } } //! Returns. /*! * */ template bool dtkComposerTransmitterReceiver::enableCopy(void) { // if (active_emitter) // return active_emitter->enableCopy(); // if (active_variant) // return active_variant->enableCopy(); // return false; if (this->active_emitter) { return this->active_emitter->copyCounterIsGreaterThanOne(); } if (this->active_variant) { return this->active_variant->copyCounterIsGreaterThanOne(); } return false; } //! Returns. /*! * */ template bool dtkComposerTransmitterReceiver::isEmpty(void) const { if (emitters.isEmpty() && variants.isEmpty()) return true; return false; }; //! Returns the kind of the transmitter. /*! * */ template dtkComposerTransmitter::Kind dtkComposerTransmitterReceiver::kind(void) const { return dtkComposerTransmitter::Receiver; }; template QString dtkComposerTransmitterReceiver::kindName(void) const { return "Receiver"; }; //! /*! * */ template bool dtkComposerTransmitterReceiver::connect(dtkComposerTransmitter *transmitter) { if (transmitter->kind() == Emitter) { if (this->dataType() == transmitter->dataType()) { dtkComposerTransmitterEmitter *emitter = reinterpret_cast *>(transmitter); if (!emitters.contains(emitter)) { emitters << emitter; active_emitter = emitter; active_variant = NULL; emitter->appendReceiver(this); emitter->updateCopyCounter(true); return true; } } } else if (transmitter->kind() == Variant) { dtkComposerTransmitterVariant *v = dynamic_cast(transmitter); if (v->dataTypes().isEmpty() && !variants.contains(v)) { variants << v; active_variant = v; active_emitter = NULL; v->appendReceiver(this); v->updateCopyCounter(true); return true; } else { foreach (int t, v->dataTypes()) { if (t == this->dataType() && !variants.contains(v)) { variants << v; active_variant = v; active_emitter = NULL; v->appendReceiver(this); v->updateCopyCounter(true); return true; } } } } return false; }; //! /*! * */ template bool dtkComposerTransmitterReceiver::disconnect(dtkComposerTransmitter *transmitter) { transmitter->removeReceiver(this); bool ok = false; if (transmitter->kind() == Variant) { dtkComposerTransmitterVariant *v = static_cast(transmitter); ok = variants.removeOne(v); if (v == active_variant) { active_variant = NULL; foreach (dtkComposerTransmitterVariant *var, variants) { if (var->active()) active_variant = var; } if (!active_variant) { foreach (dtkComposerTransmitterEmitter *em, emitters) { if (em->active()) active_emitter = em; } } } } else { if (this->dataType() == transmitter->dataType()) { dtkComposerTransmitterEmitter *emitter = reinterpret_cast *>(transmitter); ok = emitters.removeOne(emitter); if (emitter == active_emitter) { active_emitter = NULL; foreach (dtkComposerTransmitterEmitter *em, emitters) { if (em->active()) active_emitter = em; } if (!active_emitter) { foreach (dtkComposerTransmitterVariant *var, variants) { if (var->active()) active_variant = var; } } } } } if (ok) { transmitter->updateCopyCounter(false); } return ok; }; // ///////////////////////////////////////////////////////////////// // dtkComposerTransmitterReceiverVector implementation // ///////////////////////////////////////////////////////////////// #include template inline dtkComposerTransmitterReceiverVector::dtkComposerTransmitterReceiverVector(dtkComposerNode *parent) : dtkComposerTransmitterAbstractReceiver(parent) { m_vector = NULL; d->data_type = qMetaTypeId(reinterpret_cast(0)); active_emitter = NULL; active_variant = NULL; }; template inline dtkComposerTransmitterReceiverVector::~dtkComposerTransmitterReceiverVector(void) { }; //! /*! * */ template void dtkComposerTransmitterReceiverVector::clearData(void) { d->variant.clear(); d->object = NULL; d->matrix = NULL; if (d->container) delete d->container; d->container = NULL; if (m_vector) delete m_vector; m_vector = NULL; }; template dtkContainerVector *dtkComposerTransmitterReceiverVector::dataFromEmitter(void) { if (active_emitter) return active_emitter->data(); if (active_variant) return active_variant->container()->vector(); return NULL; }; template dtkContainerVector *dtkComposerTransmitterReceiverVector::data(void) { dtkContainerVector *vector = this->dataFromEmitter(); if (!vector) return NULL; switch (this->dataTransmission()) { case dtkComposerTransmitter::AutoCopy: if (this->enableCopy()) { if (!m_vector) m_vector = vector->clone(); else *(m_vector) = *vector; return m_vector; } else { return vector; } break; case dtkComposerTransmitter::Copy: if (!m_vector) m_vector = vector->clone(); else *(m_vector) = *vector; return m_vector; break; case dtkComposerTransmitter::Reference: return vector; break; default: break; }; return NULL; }; template dtkContainerVector *dtkComposerTransmitterReceiverVector::constData(void) { if (this->dataTransmission() != dtkComposerTransmitter::Copy) { return this->dataFromEmitter(); } else { dtkContainerVector *vector = this->dataFromEmitter(); if (!vector) return NULL; if (!m_vector) m_vector = vector->clone(); else *(m_vector) = *vector; return m_vector; } return NULL; }; //! Returns the data as a modifiable reference. /*! * */ template dtkAbstractObject *dtkComposerTransmitterReceiverVector::object(void) { return this->container(); }; //! /*! * */ template dtkAbstractContainerWrapper *dtkComposerTransmitterReceiverVector::container(void) { dtkContainerVector *vector = this->data(); if (!vector) return NULL; if (!d->container) d->container = new dtkContainerVectorWrapper(vector); else d->container->setVector(vector); return d->container; }; //! /*! * */ template QVariant& dtkComposerTransmitterReceiverVector::variant(void) { d->variant.setValue(this->container()); return d->variant; }; //! /*! * */ template void dtkComposerTransmitterReceiverVector::activateEmitter(dtkComposerTransmitter *emitter) { active_emitter = NULL; active_variant = NULL; foreach (dtkComposerTransmitterEmitterVector *e, emitters) { if (emitter == static_cast(e)) { active_emitter = e; break; } } } //! /*! * */ template void dtkComposerTransmitterReceiverVector::activateEmitter(dtkComposerTransmitterVariant *emitter) { active_emitter = NULL; active_variant = NULL; foreach (dtkComposerTransmitterVariant *v, variants) { if (emitter == v) { active_variant = v; break; } } } template void dtkComposerTransmitterReceiverVector::setReady(bool ready) { if (ready == d->ready) return; d->ready = ready; if (this->active_emitter) { this->active_emitter->updateCopyCounter(ready); } else if (this->active_variant) { this->active_variant->updateCopyCounter(ready); } } //! Returns. /*! * */ template bool dtkComposerTransmitterReceiverVector::enableCopy(void) { // if (active_emitter) // return active_emitter->enableCopy(); // if (active_variant) // return active_variant->enableCopy(); // return false; if (this->active_emitter) { return this->active_emitter->copyCounterIsGreaterThanOne(); } if (this->active_variant) { return this->active_variant->copyCounterIsGreaterThanOne(); } return false; } //! /*! * */ template bool dtkComposerTransmitterReceiverVector::isEmpty(void) const { if (emitters.isEmpty() && variants.isEmpty()) return true; return false; }; //! Returns the kind of the transmitter. /*! * */ template dtkComposerTransmitter::Kind dtkComposerTransmitterReceiverVector::kind(void) const { return dtkComposerTransmitter::ReceiverVector; }; template QString dtkComposerTransmitterReceiverVector::kindName(void) const { return "ReceiverContainer"; }; //! /*! * */ template bool dtkComposerTransmitterReceiverVector::connect(dtkComposerTransmitter *transmitter) { if (transmitter->kind() == dtkComposerTransmitter::EmitterVector) { if (this->dataType() == transmitter->dataType()) { dtkComposerTransmitterEmitterVector *emitter = reinterpret_cast *>(transmitter); if (!emitters.contains(emitter)) { emitters << emitter; active_emitter = emitter; active_variant = NULL; emitter->appendReceiver(this); emitter->updateCopyCounter(true); return true; } } } else if (transmitter->kind() == dtkComposerTransmitter::Variant) { dtkComposerTransmitterVariant *v = dynamic_cast(transmitter); if (v->dataTypes().isEmpty() && !variants.contains(v)) { variants << v; active_variant = v; active_emitter = NULL; v->appendReceiver(this); v->updateCopyCounter(true); return true; } else { foreach (int t, v->dataTypes()) { if (t == this->dataType() && !variants.contains(v)) { variants << v; active_variant = v; active_emitter = NULL; v->appendReceiver(this); v->updateCopyCounter(true); return true; } } } } return false; }; //! /*! * */ template bool dtkComposerTransmitterReceiverVector::disconnect(dtkComposerTransmitter *transmitter) { transmitter->removeReceiver(this); bool ok = false; if (transmitter->kind() == dtkComposerTransmitter::Variant) { dtkComposerTransmitterVariant *v = static_cast(transmitter); ok = variants.removeOne(v); if (v == active_variant) { active_variant = NULL; foreach (dtkComposerTransmitterVariant *var, variants) { if (var->active()) active_variant = var; } if (!active_variant) { foreach (dtkComposerTransmitterEmitterVector *em, emitters) { if (em->active()) active_emitter = em; } } } } else { if (this->dataType() == transmitter->dataType()) { dtkComposerTransmitterEmitterVector *emitter = reinterpret_cast *>(transmitter); ok = emitters.removeOne(emitter); if (emitter == active_emitter) { active_emitter = NULL; foreach (dtkComposerTransmitterEmitterVector *em, emitters) { if (em->active()) active_emitter = em; } if (!active_emitter) { foreach (dtkComposerTransmitterVariant *var, variants) { if (var->active()) active_variant = var; } } } } } return ok; }; #endif