Model Particle fixes

Now tracks model count changes.
This commit is contained in:
Alan Alpert 2011-05-05 11:28:06 +10:00
parent 94c1a9d0e1
commit 3ea78d14ec
4 changed files with 49 additions and 17 deletions

View File

@ -694,6 +694,8 @@ void QSGVisualDataModel::setModel(const QVariant &model)
return; return;
} }
if ((d->m_visualItemModel = qvariant_cast<QSGVisualDataModel *>(model))) { if ((d->m_visualItemModel = qvariant_cast<QSGVisualDataModel *>(model))) {
QObject::connect(d->m_visualItemModel, SIGNAL(countChanged()),
this, SIGNAL(countChanged()));
QObject::connect(d->m_visualItemModel, SIGNAL(itemsInserted(int,int)), QObject::connect(d->m_visualItemModel, SIGNAL(itemsInserted(int,int)),
this, SIGNAL(itemsInserted(int,int))); this, SIGNAL(itemsInserted(int,int)));
QObject::connect(d->m_visualItemModel, SIGNAL(itemsRemoved(int,int)), QObject::connect(d->m_visualItemModel, SIGNAL(itemsRemoved(int,int)),

View File

@ -77,7 +77,6 @@ void MaskExtruder::ensureInitialized(const QRectF &r)
m_mask.clear(); m_mask.clear();
if(m_source.isEmpty()) if(m_source.isEmpty())
return; return;
qDebug() << "Rebuild required";
m_img = QImage(m_source.toLocalFile()); m_img = QImage(m_source.toLocalFile());
m_img = m_img.createAlphaMask(); m_img = m_img.createAlphaMask();
m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier

View File

@ -47,7 +47,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
ModelParticle::ModelParticle(QSGItem *parent) : ModelParticle::ModelParticle(QSGItem *parent) :
ParticleType(parent), m_ownModel(false), m_comp(0), m_model(0), m_fade(true) ParticleType(parent), m_ownModel(false), m_comp(0), m_model(0), m_fade(true), m_modelCount(0)
{ {
setFlag(QSGItem::ItemHasContents); setFlag(QSGItem::ItemHasContents);
} }
@ -79,9 +79,30 @@ void ModelParticle::setModel(const QVariant &arg)
emit modelCountChanged(); emit modelCountChanged();
connect(m_model, SIGNAL(countChanged()), connect(m_model, SIGNAL(countChanged()),
this, SIGNAL(modelCountChanged())); this, SIGNAL(modelCountChanged()));
m_available.clear(); connect(m_model, SIGNAL(countChanged()),
for(int i=0; i<m_model->count(); i++) this, SLOT(updateCount()));
m_available << i;//TODO: Track changes updateCount();
}
void ModelParticle::updateCount()
{
int newCount = 0;
if(m_model)
newCount = m_model->count();
if(newCount < 0)
return;//WTF?
if(m_modelCount == 0 || newCount == 0){
m_available.clear();
for(int i=0; i<newCount; i++)
m_available << i;
}else if(newCount < m_modelCount){
for(int i=newCount; i<m_modelCount; i++) //existing ones must leave normally, but aren't readded
m_available.removeAll(i);
}else if(newCount > m_modelCount){
for(int i=m_modelCount; i<newCount; i++)
m_available << i;
}
m_modelCount = newCount;
} }
QDeclarativeComponent *ModelParticle::delegate() const QDeclarativeComponent *ModelParticle::delegate() const
@ -105,8 +126,8 @@ void ModelParticle::setDelegate(QDeclarativeComponent *comp)
int ModelParticle::modelCount() const int ModelParticle::modelCount() const
{ {
if(m_model) if(m_model)
return m_model->count(); const_cast<ModelParticle*>(this)->updateCount();//TODO: Investigate why this doesn't get called properly
return 0; return m_modelCount;
} }
@ -144,12 +165,12 @@ void ModelParticle::load(ParticleData* d)
qWarning() << "Current model particles prefers overwrite:false"; qWarning() << "Current model particles prefers overwrite:false";
//remove old item from the particle that is dying to make room for this one //remove old item from the particle that is dying to make room for this one
m_items[pos]->setOpacity(0.); m_items[pos]->setOpacity(0.);
if(m_idx[pos] >= 0){ if(m_idx[pos] >= 0 && m_idx[pos] < m_modelCount){
m_available << m_idx[pos]; m_available << m_idx[pos];
m_model->release(m_items[pos]); m_model->release(m_items[pos]);
}else{ }else{
ModelParticleAttached* mpa; ModelParticleAttached* mpa;
if((mpa = qobject_cast<ModelParticleAttached*>(qmlAttachedPropertiesObject<ModelParticle>(m_items[pos])))) if((mpa = qobject_cast<ModelParticleAttached*>(qmlAttachedPropertiesObject<ModelParticle>(m_items[pos], false))))
mpa->detach();//reparent as well? mpa->detach();//reparent as well?
} }
m_idx[pos] = -1; m_idx[pos] = -1;
@ -159,6 +180,11 @@ void ModelParticle::load(ParticleData* d)
} }
if(m_available.isEmpty() && m_pendingItems.isEmpty()) if(m_available.isEmpty() && m_pendingItems.isEmpty())
return; return;
ModelParticleAttached* mpa = qobject_cast<ModelParticleAttached*>(qmlAttachedPropertiesObject<ModelParticle>(m_items[pos]));
if(mpa)
qDebug() << (mpa->m_mp = this);
else
qDebug() << "Bugger";
if(m_pendingItems.isEmpty()){ if(m_pendingItems.isEmpty()){
m_items[pos] = m_model->item(m_available.first()); m_items[pos] = m_model->item(m_available.first());
m_idx[pos] = m_available.first(); m_idx[pos] = m_available.first();
@ -168,8 +194,7 @@ void ModelParticle::load(ParticleData* d)
m_pendingItems.pop_front(); m_pendingItems.pop_front();
m_items[pos]->setX(d->curX() - m_items[pos]->width()/2); m_items[pos]->setX(d->curX() - m_items[pos]->width()/2);
m_items[pos]->setY(d->curY() - m_items[pos]->height()/2); m_items[pos]->setY(d->curY() - m_items[pos]->height()/2);
ModelParticleAttached* mpa; if(mpa)
if((mpa = qobject_cast<ModelParticleAttached*>(qmlAttachedPropertiesObject<ModelParticle>(m_items[pos]))))
mpa->attach(); mpa->attach();
m_idx[pos] = -2; m_idx[pos] = -2;
} }
@ -205,11 +230,8 @@ void ModelParticle::reset()
m_items.fill(0); m_items.fill(0);
m_data.fill(0); m_data.fill(0);
m_idx.fill(-1); m_idx.fill(-1);
m_available.clear(); //m_available.clear();//Should this be reset too?
//m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal? //m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal?
if(m_model)
for(int i=0; i<m_model->count(); i++)
m_available << i;//TODO: Track changes, then have this in the right place
} }
@ -250,7 +272,7 @@ void ModelParticle::prepareNextFrame()
} }
if(t >= 1.0){//Usually happens from load if(t >= 1.0){//Usually happens from load
item->setOpacity(0.); item->setOpacity(0.);
if(m_idx[i] >= 0){ if(m_idx[i] >= 0 && m_idx[i] < m_modelCount){
m_available << m_idx[i]; m_available << m_idx[i];
m_model->release(m_items[i]); m_model->release(m_items[i]);
}else{ }else{

View File

@ -96,6 +96,8 @@ public slots:
protected: protected:
virtual void reset(); virtual void reset();
void prepareNextFrame(); void prepareNextFrame();
private slots:
void updateCount();
private: private:
bool m_ownModel; bool m_ownModel;
QDeclarativeComponent* m_comp; QDeclarativeComponent* m_comp;
@ -113,16 +115,23 @@ private:
QSet<QSGItem*> m_stasis; QSet<QSGItem*> m_stasis;
qreal m_lastT; qreal m_lastT;
int m_activeCount; int m_activeCount;
int m_modelCount;
}; };
class ModelParticleAttached : public QObject class ModelParticleAttached : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(ModelParticle* particle READ particle CONSTANT);
public: public:
ModelParticleAttached(QObject* parent){;} ModelParticleAttached(QObject* parent)
: QObject(parent), m_mp(0)
{;}
ModelParticle* particle() {return m_mp;}
void detach(){emit detached();} void detach(){emit detached();}
void attach(){emit attached();} void attach(){emit attached();}
private: private:
ModelParticle* m_mp;
friend class ModelParticle;
Q_SIGNALS: Q_SIGNALS:
void detached(); void detached();
void attached(); void attached();