[KDev4] Opening project with real ASync way

Andreas Pakulat apaku at gmx.de
Sun May 27 23:50:54 UTC 2007


On 27.05.07 08:36:43, dukju ahn wrote:
> 2007/5/27, dukju ahn <dukjuahn at gmail.com>:
> >It works very well. But there is one problem. Because now
> >ProjectBaseItems are created on separated thread, we can't invoke
> >setIcon() at the constructor of ProjectBaseItem and its subclasses.
> >Otherwise it segfaulted. Especially KIO::pixmapForUrl() was the reason
> >of crash.
> >
> >One solution would be to invoke setIcon() in the slot connected to
> >KJob::done(). Starting from top item, we go recursively into every
> >children and call childItem->setIcon().
> 
> Here is the completed patch. The advantages are two
> 
> 1. GUI doesn't hang while openning a big project

Thats good.

> 2. Project parsing became much faster because the setIcon() in each
> ProjectBaseItem isn't invoked for full recursive file/dirs. Rather, we
> just setIcon() only for toplevel items. Icon for Children items are set up
> when the user expands treeview.
> I've found that setIcon() is very time-consuming operation.

Are you making sure to call setIcon only once already? I mean after the
initial expansion its not needed to call setIcon again.

I'll do other comments inline in the code.

> Index: projecttreeview.cpp
> ===================================================================
> --- projecttreeview.cpp	(revision 668449)
> +++ projecttreeview.cpp	(working copy)
> @@ -54,6 +54,7 @@
>  
>      connect( this, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( popupContextMenu( QPoint ) ) );
>      connect( this, SIGNAL( activated( QModelIndex ) ), this, SLOT( slotActivated( QModelIndex ) ) );
> +    connect( this, SIGNAL( expanded(const QModelIndex&) ), this, SLOT( slotExpanded( const QModelIndex& ) ) );
>  }

I'm not sure at the moment how the projectmodel itself works, but
eventually we can avoid having to change the view and do it in the
model. There are virtuals that can be implemented when a node is
expanded, in particular fetchMore().

> +void ImportProjectThread::run()
> +{
> +    if ( d->m_folder )
> +        startNextJob( d->m_folder );
> +    kDebug() << "ImportProjectThread::run() returning" << endl;
> +}
> +
> +void ImportProjectThread::startNextJob(ProjectFolderItem *dom)
> +{
> +    d->m_workingList << d->m_importer->parse(dom);
> +    while ( !d->m_workingList.isEmpty() )
> +    {
> +        ProjectFolderItem *folder = d->m_workingList.first();
> +        d->m_workingList.pop_front();
> +
> +        startNextJob(folder);
> +    }
> +}

If I see this correctly this is a depth-first approach right? I think a
width-first (or whatever you call that in english, where you first run
over all items at the current level before you decend into the next) is
better, else a user opens the projectmanagers first item and the items
are not all there yet.  

> -void ImportProjectJob::startNextJob(ProjectFolderItem *dom)
> +void ImportProjectJob::processList()
>  {

Hmm, is this method still needed?

> +    connect( project, SIGNAL(importingFinished(IProject*)), this, SLOT(projectImportingFinished(IProject*)) );

I guess I'm missing something but why can't the project private do the
stuff in that slot directly instead of adding this indirection, a signal
and a friend declaration? All that the project private class needs is
asking Core::self() for the projectcontrollerinternal and execute a
that slot with the project. Then I think the project private class also
doesn't need a Project* but can live with a plain IProject*.

Andreas

-- 
You love your home and want it to be beautiful.




More information about the KDevelop-devel mailing list