Difference between revisions of "Projects/Marble/RunnerHOWTO"

Jump to: navigation, search
(add a first bit of runner stuff)
 
m (Text replace - "<code>" to "<syntaxhighlight lang="text">")
 
(4 intermediate revisions by 3 users not shown)
Line 8: Line 8:
 
# The current text is sent to the MarbleRunnerManager
 
# The current text is sent to the MarbleRunnerManager
 
# The MarbleRunnerManager gives the text to all of the runners
 
# The MarbleRunnerManager gives the text to all of the runners
# The runners emit the runnerStarted() signal. The MarbleRunnerManager uses this to count how many runners are still active.
+
# The MarbleRunnerManager starts each runner thread and registers it as active
# The runners finish by emitting the runnerFinished(QVector<GeoDataPlacemark*>) signal. Note that if the runner fails to produce results for some reason, this signal should be emitted with an empty QVector, as it's needed to keep track of which runners are still working.
+
# The runners finish by emitting the runnerFinished(QVector<GeoDataPlacemark*>) signal. Note that if the runner fails to produce results for some reason, this signal must be emitted with an empty QVector, as it's needed to keep track of which runners are still working.
 
# The MarbleRunnerManager gives results back to the MarbleControlBox.
 
# The MarbleRunnerManager gives results back to the MarbleControlBox.
  
The main work of the runner is done in the parse(const QString &input) slot;
+
The main work of the runner is done in the thread's run() method. It should emit runnerFinished() at any exit point. The input is provided to the base class via the parse() method which stores the input.
it should emit runnerStarted() at the beginning and runnerFinished() at any exit point.
+
  
 
'''ExampleRunner.h'''
 
'''ExampleRunner.h'''
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
  
 
#ifndef EXAMPLERUNNER_H
 
#ifndef EXAMPLERUNNER_H
Line 33: Line 32:
 
     ~ExampleRunner();
 
     ~ExampleRunner();
 
     GeoDataFeature::GeoDataVisualCategory category() const;
 
     GeoDataFeature::GeoDataVisualCategory category() const;
 
+
     virtual void run();
public slots:
+
     void parse(const QString &input);
+
 
};
 
};
  
Line 42: Line 39:
 
#endif
 
#endif
  
</code>
+
</syntaxhighlight>
  
 
This basically just defines the class; it doesn't do anything else.
 
This basically just defines the class; it doesn't do anything else.
Line 48: Line 45:
 
'''ExampleRunner.cpp'''
 
'''ExampleRunner.cpp'''
  
<code cppqt>
+
<syntaxhighlight lang="cpp-qt">
 
#include "ExampleRunner.h"
 
#include "ExampleRunner.h"
  
Line 78: Line 75:
 
}
 
}
  
void ExampleRunner::parse(const QString &input)
+
void ExampleRunner::run()
 
{
 
{
    emit runnerStarted();
 
 
     QVector<GeoDataPlacemark*> vector;
 
     QVector<GeoDataPlacemark*> vector;
 
     if(input.toLower() == tr("middle of nowhere")) {
 
     if(input.toLower() == tr("middle of nowhere")) {
 
         GeoDataPlacemark *placemark = new GeoDataPlacemark();
 
         GeoDataPlacemark *placemark = new GeoDataPlacemark();
 
         placemark->setCoordinate( -90.1833 *DEG2RAD, 51.4666 *DEG2RAD);
 
         placemark->setCoordinate( -90.1833 *DEG2RAD, 51.4666 *DEG2RAD);
         placemark->setName( input );
+
         placemark->setName( m_input );
 
         placemark->setVisualCategory( category() );
 
         placemark->setVisualCategory( category() );
 
         placemark->setPopularity( 1000000000 );
 
         placemark->setPopularity( 1000000000 );
Line 98: Line 94:
 
#include "ExampleRunner.moc"
 
#include "ExampleRunner.moc"
  
</code>
+
</syntaxhighlight>
  
 
ExampleRunner::category() returns the visual category of the results produced by this runner; in this case we use Default because there isn't an existing category for Techbase examples.
 
ExampleRunner::category() returns the visual category of the results produced by this runner; in this case we use Default because there isn't an existing category for Techbase examples.
  
runnerStarted() gets emitted at the beginning to notify the runner manager that we've started parsing; then we do a very simple case-insensitive check to see if it matches.
+
The input is taken doing a very simple case-insensitive check to see if it matches. Results are GeoDataPlacemarks, and it's useful to set various parameters for them: set the category to the runner's category, set the name, set the popularity / popularity index (see the documentation for GeoDataPlacemark for details), etc...
 
+
Results are GeoDataPlacemarks, and it's useful to set various parameters for them: set the category to the runner's category, set the name, set the popularity / popularity index (see the documentation for GeoDataPlacemark for details), etc...
+
  
 
Then the pointer to the placemark is put into the results vector and the runner emits runnerFinished(), returning it to the runner manager. If it didn't match, it returns an empty vector.
 
Then the pointer to the placemark is put into the results vector and the runner emits runnerFinished(), returning it to the runner manager. If it didn't match, it returns an empty vector.
  
To add the runner to Marble, you would have to put the source files into the src/lib/runners directory, and add them to CMakeLists.txt, then add a part in src/lib/MarbleRunnerManager.cpp that creates the object and connects it exactly the same way as the other two.
+
To add the runner to Marble, you would have to put the source files into the src/lib/runners directory, and add them to CMakeLists.txt, then add a part in src/lib/MarbleRunnerManager.cpp that creates the object and connects it exactly the same way as the other two, like so:
 +
 
 +
<syntaxhighlight lang="text">
 +
Index: src/lib/MarbleRunnerManager.h                       
 +
===================================================================
 +
--- src/lib/MarbleRunnerManager.h      (revision 886350)         
 +
+++ src/lib/MarbleRunnerManager.h      (working copy)           
 +
@@ -33,6 +33,7 @@                                                 
 +
                                                                 
 +
class LatLonRunner;                                             
 +
class OnfRunner;                                                 
 +
+class ExampleRunner;                                             
 +
                                                                 
 +
class MarbleRunnerManager : public QObject                       
 +
{                                                               
 +
@@ -60,6 +61,7 @@                                                 
 +
                                                                 
 +
    LatLonRunner *m_latlonRunner;                               
 +
    OnfRunner *m_onfRunner;                                     
 +
+    ExampleRunner *m_exampleRunner;                             
 +
};                                                               
 +
                                                                 
 +
}                                                               
 +
Index: src/lib/MarbleRunnerManager.cpp                           
 +
===================================================================
 +
--- src/lib/MarbleRunnerManager.cpp    (revision 886350)         
 +
+++ src/lib/MarbleRunnerManager.cpp    (working copy)           
 +
@@ -27,6 +27,7 @@                                                 
 +
                                                                 
 +
#include "LatLonRunner.h"                                       
 +
#include "OnfRunner.h"                                           
 +
+#include "ExampleRunner.h"                                       
 +
                                                                 
 +
#include <QtCore/QObject>                                       
 +
#include <QtCore/QString>                                       
 +
@@ -66,6 +67,16 @@                                               
 +
              this,        SLOT( slotRunnerFinished( QVector<GeoDataPlacemark*> ) ));
 +
    connect( this,        SIGNAL( engage(QString) ),                               
 +
              m_onfRunner, SLOT( parse(QString) ));                                 
 +
+                                                                                   
 +
+    m_exampleRunner = new ExampleRunner(0);                                       
 +
+    m_exampleRunner->start();                                                     
 +
+    m_exampleRunner->moveToThread(m_exampleRunner);                               
 +
+    connect( m_exampleRunner, SIGNAL( runnerStarted() ),                           
 +
+            this,        SLOT( slotRunnerStarted() ));                           
 +
+    connect( m_exampleRunner, SIGNAL( runnerFinished( QVector<GeoDataPlacemark*> ) ),
 +
+            this,        SLOT( slotRunnerFinished( QVector<GeoDataPlacemark*> ) ));
 +
+    connect( this,        SIGNAL( engage(QString) ),                               
 +
+            m_exampleRunner, SLOT( parse(QString) ));                             
 +
}                                                                                   
 +
 
 +
MarbleRunnerManager::~MarbleRunnerManager()
 +
Index: src/lib/CMakeLists.txt
 +
===================================================================
 +
--- src/lib/CMakeLists.txt      (revision 886350)
 +
+++ src/lib/CMakeLists.txt      (working copy)
 +
@@ -161,6 +161,7 @@
 +
    runners/MarbleAbstractRunner.cpp
 +
    runners/LatLonRunner.cpp
 +
    runners/OnfRunner.cpp
 +
+    runners/ExampleRunner.cpp
 +
)
 +
 
 +
set (marblewidget_UI
 +
</syntaxhighlight>
 +
 
 +
The result of this is that when you search for "Middle of Nowhere", you get:
 +
[[Image:MiddleOfNowhere.png]]

Latest revision as of 21:49, 29 June 2011

The basic idea of the Marble Runners is borrowed from KRunner. A user search could represent a bunch of different things: a geographical coordinate, an address, a wikipedia article, directions, etc...

Because each of these searches is different in type as well as speed (e.g. a OSM Namefinder search takes much longer than parsing coordinates) each type of search is done in its own runner which is a seperate thread.

The piece that manages all the runners is the MarbleRunnerManager. It receives search text from the MarbleControlBox (where the lineedit is) and then gives it to all of the runners.

  1. User presses return in the line edit
  2. The current text is sent to the MarbleRunnerManager
  3. The MarbleRunnerManager gives the text to all of the runners
  4. The MarbleRunnerManager starts each runner thread and registers it as active
  5. The runners finish by emitting the runnerFinished(QVector<GeoDataPlacemark*>) signal. Note that if the runner fails to produce results for some reason, this signal must be emitted with an empty QVector, as it's needed to keep track of which runners are still working.
  6. The MarbleRunnerManager gives results back to the MarbleControlBox.

The main work of the runner is done in the thread's run() method. It should emit runnerFinished() at any exit point. The input is provided to the base class via the parse() method which stores the input.

ExampleRunner.h

#ifndef EXAMPLERUNNER_H
#define EXAMPLERUNNER_H
 
#include "MarbleAbstractRunner.h"
 
namespace Marble
{
 
class ExampleRunner : public MarbleAbstractRunner
{
    Q_OBJECT
public:
    ExampleRunner(QObject *parent = 0);
    ~ExampleRunner();
    GeoDataFeature::GeoDataVisualCategory category() const;
    virtual void run();
};
 
}
 
#endif

This basically just defines the class; it doesn't do anything else.

ExampleRunner.cpp

#include "ExampleRunner.h"
 
#include "MarbleAbstractRunner.h"
#include "GeoDataFeature.h"
#include "GeoDataPlacemark.h"
#include "GeoDataCoordinates.h"
 
#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVector>
 
namespace Marble
{
 
ExampleRunner::ExampleRunner(QObject *parent) : MarbleAbstractRunner(parent)
{
}
 
 
GeoDataFeature::GeoDataVisualCategory ExampleRunner::category() const
{
    return GeoDataFeature::Default;
}
 
ExampleRunner::~ExampleRunner()
{
}
 
void ExampleRunner::run()
{
    QVector<GeoDataPlacemark*> vector;
    if(input.toLower() == tr("middle of nowhere")) {
        GeoDataPlacemark *placemark = new GeoDataPlacemark();
        placemark->setCoordinate( -90.1833 *DEG2RAD, 51.4666 *DEG2RAD);
        placemark->setName( m_input );
        placemark->setVisualCategory( category() );
        placemark->setPopularity( 1000000000 );
        placemark->setPopularityIndex( 18 );
        vector.append( placemark );
    }
    emit runnerFinished(vector);
}
 
}
 
#include "ExampleRunner.moc"

ExampleRunner::category() returns the visual category of the results produced by this runner; in this case we use Default because there isn't an existing category for Techbase examples.

The input is taken doing a very simple case-insensitive check to see if it matches. Results are GeoDataPlacemarks, and it's useful to set various parameters for them: set the category to the runner's category, set the name, set the popularity / popularity index (see the documentation for GeoDataPlacemark for details), etc...

Then the pointer to the placemark is put into the results vector and the runner emits runnerFinished(), returning it to the runner manager. If it didn't match, it returns an empty vector.

To add the runner to Marble, you would have to put the source files into the src/lib/runners directory, and add them to CMakeLists.txt, then add a part in src/lib/MarbleRunnerManager.cpp that creates the object and connects it exactly the same way as the other two, like so:

Index: src/lib/MarbleRunnerManager.h                         
===================================================================
--- src/lib/MarbleRunnerManager.h       (revision 886350)          
+++ src/lib/MarbleRunnerManager.h       (working copy)             
@@ -33,6 +33,7 @@                                                  
 
 class LatLonRunner;                                               
 class OnfRunner;                                                  
+class ExampleRunner;                                              
 
 class MarbleRunnerManager : public QObject                        
 {                                                                 
@@ -60,6 +61,7 @@                                                  
 
     LatLonRunner *m_latlonRunner;                                 
     OnfRunner *m_onfRunner;                                       
+    ExampleRunner *m_exampleRunner;                               
 };                                                                
 
 }                                                                 
Index: src/lib/MarbleRunnerManager.cpp                             
===================================================================
--- src/lib/MarbleRunnerManager.cpp     (revision 886350)          
+++ src/lib/MarbleRunnerManager.cpp     (working copy)             
@@ -27,6 +27,7 @@                                                  
 
 #include "LatLonRunner.h"                                         
 #include "OnfRunner.h"                                            
+#include "ExampleRunner.h"                                        
 
 #include <QtCore/QObject>                                         
 #include <QtCore/QString>                                         
@@ -66,6 +67,16 @@                                                 
              this,        SLOT( slotRunnerFinished( QVector<GeoDataPlacemark*> ) ));
     connect( this,        SIGNAL( engage(QString) ),                                
              m_onfRunner, SLOT( parse(QString) ));                                  
+                                                                                    
+    m_exampleRunner = new ExampleRunner(0);                                         
+    m_exampleRunner->start();                                                       
+    m_exampleRunner->moveToThread(m_exampleRunner);                                 
+    connect( m_exampleRunner, SIGNAL( runnerStarted() ),                            
+             this,        SLOT( slotRunnerStarted() ));                             
+    connect( m_exampleRunner, SIGNAL( runnerFinished( QVector<GeoDataPlacemark*> ) ),
+             this,        SLOT( slotRunnerFinished( QVector<GeoDataPlacemark*> ) )); 
+    connect( this,        SIGNAL( engage(QString) ),                                 
+             m_exampleRunner, SLOT( parse(QString) ));                               
 }                                                                                    
 
 MarbleRunnerManager::~MarbleRunnerManager()
Index: src/lib/CMakeLists.txt
===================================================================
--- src/lib/CMakeLists.txt      (revision 886350)
+++ src/lib/CMakeLists.txt      (working copy)
@@ -161,6 +161,7 @@
     runners/MarbleAbstractRunner.cpp
     runners/LatLonRunner.cpp
     runners/OnfRunner.cpp
+    runners/ExampleRunner.cpp
 )
 
 set (marblewidget_UI

The result of this is that when you search for "Middle of Nowhere", you get: MiddleOfNowhere.png


This page was last modified on 29 June 2011, at 21:49. This page has been accessed 4,822 times. Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal