ede0ee0b72837a6674146aeacd0bba34116e6893
[situare] / src / map / mapfetcher.h
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Jussi Laitinen - jussi.laitinen@ixonos.com
6        Sami Rämö - sami.ramo@ixonos.com
7
8    Situare is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License
10    version 2 as published by the Free Software Foundation.
11
12    Situare is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Situare; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20    USA.
21 */
22
23 #ifndef MAPFETCHER_H
24 #define MAPFETCHER_H
25
26 #include <QtCore>
27 #include <QNetworkAccessManager>
28
29 class QNetworkReply;
30 class QUrl;
31
32 /**
33 * @brief MapFetcher handles requests to get map tiles.
34 *
35 * @author Jussi Laitinen jussi.laitinen@ixonos.com
36 */
37 class MapFetcher : public QObject
38 {
39     Q_OBJECT
40
41     /**
42     * @brief Struct for download requests
43     *
44     * @typedef Request
45     */
46     typedef struct _Request {
47         bool cacheChecked; ///< Is this request already checked from the cache
48         QUrl url; ///< URL
49     } Request;
50
51 public:
52     /**
53     * @brief Constructor for MapFetcher.
54     *
55     * @param manager Network access manager
56     * @param parent parent object
57     */
58     MapFetcher(QNetworkAccessManager *manager, QObject *parent = 0);
59
60 /*******************************************************************************
61  * CLASS SPECIFIC MEMBER FUNCTIONS AND SLOTS
62  ******************************************************************************/
63 public:
64     /**
65     * @brief Set size of the download queue
66     *
67     * @param size New size
68     */
69     void setDownloadQueueSize(int size);
70
71 public slots:
72
73     /**
74     * @brief Enqueue fetching of map image
75     *
76     * Image fetching is triggered after events have been processed
77     * so the UI stays responsive.
78     *
79     * @param url URL of the image to be fetched
80     */
81     void enqueueFetchMapImage(QUrl url);
82
83 private:
84
85     /**
86     * @brief Limit pending requests list size to m_pendingRequestsSize
87     *
88     */
89     void limitPendingRequestsListSize();
90
91     /**
92     * @brief Loads image from cache if it's available and emits imageReveived
93     * signal with url and image. If image is in cache returns true, false
94     * otherwise.
95     *
96     * @param url
97     * @return bool true if image was loaded from cache, false otherwise
98     */
99     bool loadImageFromCache(const QUrl &url);
100
101     /**
102     * @brief Find first item based on criteria if the request is already checked from the cache
103     *
104     * If cacheChecked is true, then returns index of the first request which is already
105     * checked from the cache. If cacheChecked is false then returns first item which
106     * isn't checked from the cache. Returns -1 if the item is not found.
107     *
108     * @param cacheChecked Search criteria
109     * @return Index of the first matching request, or -1 if not found.
110     */
111     int newestRequestIndex(bool cacheChecked);
112
113 private slots:
114
115     /**
116     * @brief This slot is called when network manager has finished
117     * the download. Loads image and emits imageReceived signal with
118     * url and image. If there was a error in reply emits error-signal.
119     *
120     * @param reply
121     */
122     void downloadFinished(QNetworkReply *reply);
123
124     /**
125     * @brief Check next request if it is found from cache
126     *
127     * Next queued request, which is not already checked against cache, is taken
128     * from the queue and checked against cache. If not found from cache, then
129     * cache checked flag is set. New download is started if there aren't too
130     * many simultaneus downloads already running.
131     */
132     void checkNextRequestFromCache();
133
134     /**
135     * @brief This slot is called when next download is started. Takes url
136     * from queue, sends request and puts request to download queue.
137     */
138     void startNextDownload();
139
140 /*******************************************************************************
141  * SIGNALS
142  ******************************************************************************/
143 signals:    
144     /**
145     * @brief Signal which is emitted when a map tile
146     * is received from the server and loaded to pixmap.
147     *
148     * @param url URL to image
149     * @param image image pixmap
150     */
151     void mapImageReceived(const QUrl &url, const QPixmap &image);
152
153     /**
154     * @brief Signal which is emitted when there is error
155     * in network reply.
156     *
157     * @param message error message
158     */
159     void error(const QString &message);
160
161 /*******************************************************************************
162  * DATA MEMBERS
163  ******************************************************************************/
164 private:
165     static const int MAX_PARALLEL_DOWNLOADS = 2; ///< Max simultaneous parallel downloads
166
167     QList<QNetworkReply*> m_currentDownloads; ///< List of current downloads
168     int m_pendingRequestsSize; ///< Max number of pending requests
169     bool m_fetchMapImagesTimerRunning; ///< is the singleshot timer already running
170     QNetworkAccessManager *m_manager; ///< Network access manager
171     QList<Request> m_pendingRequests; ///< List of map image fetching requests
172 };
173
174 #endif