Merge lp:~nick-dedekind/unity/lp1062107.preview-pre-caching into lp:unity
- lp1062107.preview-pre-caching
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~nick-dedekind/unity/lp1062107.preview-pre-caching |
Merge into: | lp:unity |
Diff against target: |
1176 lines (+675/-75) 22 files modified
UnityCore/CMakeLists.txt (+2/-0) UnityCore/HomeLens.cpp (+2/-2) UnityCore/HomeLens.h (+1/-1) UnityCore/Lens.cpp (+25/-25) UnityCore/Lens.h (+3/-1) UnityCore/PreviewPreCacher.cpp (+270/-0) UnityCore/PreviewPreCacher.h (+94/-0) dash/DashView.cpp (+8/-3) dash/LensView.cpp (+15/-13) dash/LensView.h (+7/-3) dash/previews/ApplicationPreview.cpp (+3/-3) dash/previews/GenericPreview.cpp (+2/-2) dash/previews/MoviePreview.cpp (+2/-2) dash/previews/MusicPreview.cpp (+2/-2) dash/previews/PreviewContainer.cpp (+1/-1) dash/previews/PreviewInfoHintWidget.cpp (+1/-1) dash/previews/SocialPreview.cpp (+3/-3) dash/previews/SocialPreviewComments.cpp (+1/-1) dash/previews/SocialPreviewContent.cpp (+4/-4) tests/CMakeLists.txt (+1/-0) tests/test_lens.cpp (+4/-8) tests/test_previews_precacher.cpp (+224/-0) |
To merge this branch: | bzr merge lp:~nick-dedekind/unity/lp1062107.preview-pre-caching |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brandon Schaefer (community) | Needs Fixing | ||
Review via email: mp+133446@code.launchpad.net |
Commit message
Added dash preview pre-caching. (LP: #1062107)
Description of the change
= Problem description =
https:/
Preview content should be speculatively cached
= The fix =
1. When the user opens a preview, results subsequent to the preview start pre-cacheing.
2. Once a user has previewed one content item underneath a category header, as long as the Dash remains open we continue to speculatively cache the preview content for the other items under the category header (even when the user returns to the results view). The pre-caching stops when a) the user closes the Dash b) the user previews the a result from underneath another category header. In this second case the Dash then starts speculatively pre-cacheing the content from underneath this new category header.
= Test coverage =
Unit tests for pre-caching queue execution.
Brandon Schaefer (brandontschaefer) wrote : | # |
Brandon Schaefer (brandontschaefer) wrote : | # |
bschaefer@
+N UnityCore/
+N UnityCore/
+N tests/test_
M UnityCore/
M UnityCore/
M UnityCore/
M UnityCore/Lens.cpp
M UnityCore/Lens.h
M dash/DashView.cpp
M dash/LensView.cpp
M dash/LensView.h
M dash/previews/
M dash/previews/
M dash/previews/
M dash/previews/
M tests/CMakeList
M tests/test_lens.cpp
Text conflict in dash/LensView.cpp
Text conflict in dash/previews/
Text conflict in tests/CMakeList
3 conflicts encountered.
Nick Dedekind (nick-dedekind) wrote : | # |
> 530 + virtual ~PreviewPreCach
> 551 + virtual void OnPreCacheCompl
>
> Could we make those pure virtual fucntions?
>
> Or if not could we just do:
> 530 + virtual ~PreviewPreCacher() {}
> 551 + virtual void OnPreCacheCompl
>
Can't be pure virtual because we need to instantiate a PreviewPreCacher.
Don't see any benefit in making them inline.
>
> 347 + if (index < 0 || index >=(int)
>
> Does this need to be casted to an int?
>
Yes. GetResultCount returns an unsigned int. Comes from the dee model.
>
> 758 + int top_social_
> style.GetAppIco
> 772 + int max_width = MAX(0, geo_cr.width - 2*(geo_
> 773 + int max_height = MAX(0, (geo_cr.height - TAIL_HEIGHT) -
> 2*((geo_cr.height - TAIL_HEIGHT)*0.1));
> 786 + title_-
> style.GetMusicD
>
> Lets use std::max() here.
Will do.
- 2880. By Nick Dedekind
-
switched preview code to use std::max
- 2881. By Nick Dedekind
-
Merged with trunk
Nick Dedekind (nick-dedekind) wrote : | # |
Use std::max for preview code.
Merged with trunk.
Andrea Azzarone (azzar1) wrote : | # |
tests/test_
I don't like the way you're testing PreviewPreCacher because you're testing a mock of it (MockPreviewPre
Also PreviewPreCacher should inherit from sigc::trackable.
Nick Dedekind (nick-dedekind) wrote : | # |
@andyrock: As stated in the description, the supplied test is only meant to check the preview pre-caching sequence (pretty much only the PreviewPreCache
Getting a lens view into the test harness to test the pre-cacher interaction is somewhat controversial and not suited to unit testing at the moment (Lens Dee related code is "too tight" for testability).
I am hoping to get some refactoring into the lenses soon so they can be properly tested. Once this is done, we can revisit this.
Nick Dedekind (nick-dedekind) wrote : | # |
Some previews (eg MusicPreview) are stateful inside libunity, therefore asking for subsiquent previews while viewing another will hose the state.
Until this is recitfied, this cannot be merged.
Unmerged revisions
- 2881. By Nick Dedekind
-
Merged with trunk
- 2880. By Nick Dedekind
-
switched preview code to use std::max
- 2879. By Nick Dedekind
-
Preview pre-caching tweaks.
- 2878. By Nick Dedekind
-
Removed debuggin code.
- 2877. By Nick Dedekind
-
Added precache files.
- 2876. By Nick Dedekind
-
Added speculative caching to previews.
- 2875. By Nick Dedekind
-
Check for width > 0 in preview layout management.
Preview Diff
1 | === modified file 'UnityCore/CMakeLists.txt' |
2 | --- UnityCore/CMakeLists.txt 2012-11-26 16:09:53 +0000 |
3 | +++ UnityCore/CMakeLists.txt 2012-12-10 10:03:24 +0000 |
4 | @@ -49,6 +49,7 @@ |
5 | ModelRowAdaptor.h |
6 | ModelRowAdaptor-inl.h |
7 | Preview.h |
8 | + PreviewPreCacher.h |
9 | RadioOptionFilter.h |
10 | RatingsFilter.h |
11 | Result.h |
12 | @@ -88,6 +89,7 @@ |
13 | MusicPreview.cpp |
14 | ModelRowAdaptor.cpp |
15 | Preview.cpp |
16 | + PreviewPreCacher.cpp |
17 | RatingsFilter.cpp |
18 | RadioOptionFilter.cpp |
19 | Result.cpp |
20 | |
21 | === modified file 'UnityCore/HomeLens.cpp' |
22 | --- UnityCore/HomeLens.cpp 2012-11-14 08:57:56 +0000 |
23 | +++ UnityCore/HomeLens.cpp 2012-12-10 10:03:24 +0000 |
24 | @@ -1218,14 +1218,14 @@ |
25 | } |
26 | } |
27 | |
28 | -void HomeLens::Preview(std::string const& uri) |
29 | +void HomeLens::Preview(std::string const& uri, GCancellable* cancellable, PreviewCallback const& slot) |
30 | { |
31 | LOG_DEBUG(logger) << "Preview '" << uri << "'"; |
32 | |
33 | Lens::Ptr lens = pimpl->FindLensForUri(uri); |
34 | |
35 | if (lens) |
36 | - lens->Preview(uri); |
37 | + lens->Preview(uri, cancellable, slot); |
38 | else |
39 | LOG_WARN(logger) << "Unable to find a lens for previewing '" << uri << "'"; |
40 | } |
41 | |
42 | === modified file 'UnityCore/HomeLens.h' |
43 | --- UnityCore/HomeLens.h 2012-11-12 11:07:23 +0000 |
44 | +++ UnityCore/HomeLens.h 2012-12-10 10:03:24 +0000 |
45 | @@ -72,7 +72,7 @@ |
46 | void GlobalSearch(std::string const& search_string, SearchFinishedCallback const& cb); |
47 | void Search(std::string const& search_string, SearchFinishedCallback const& cb); |
48 | void Activate(std::string const& uri); |
49 | - void Preview(std::string const& uri); |
50 | + void Preview(std::string const& uri, GCancellable* cancellable, PreviewCallback const& slot); |
51 | |
52 | std::vector<unsigned> GetCategoriesOrder(); |
53 | glib::Object<DeeModel> GetFilterModelForCategory(unsigned category); |
54 | |
55 | === modified file 'UnityCore/Lens.cpp' |
56 | --- UnityCore/Lens.cpp 2012-11-14 08:57:56 +0000 |
57 | +++ UnityCore/Lens.cpp 2012-12-10 10:03:24 +0000 |
58 | @@ -84,8 +84,8 @@ |
59 | void GlobalSearch(std::string const& search_string, SearchFinishedCallback const& cb); |
60 | void Search(std::string const& search_string, SearchFinishedCallback const& cb); |
61 | void Activate(std::string const& uri); |
62 | - void ActivationReply(GVariant* parameters); |
63 | - void Preview(std::string const& uri); |
64 | + void ActivationReply(GVariant* parameters, PreviewCallback const& slot); |
65 | + void Preview(std::string const& uri, GCancellable* cancellable, PreviewCallback const& slot); |
66 | void ActivatePreviewAction(std::string const& action_id, |
67 | std::string const& uri, |
68 | Hints const& hints); |
69 | @@ -143,7 +143,6 @@ |
70 | glib::DBusProxy* proxy_; |
71 | glib::Object<GCancellable> search_cancellable_; |
72 | glib::Object<GCancellable> global_search_cancellable_; |
73 | - glib::Object<GCancellable> preview_cancellable_; |
74 | |
75 | glib::Variant results_variant_; |
76 | glib::Variant global_results_variant_; |
77 | @@ -513,18 +512,18 @@ |
78 | LOG_DEBUG(logger) << "Activating '" << uri << "' on '" << id_ << "'"; |
79 | |
80 | if (!proxy_->IsConnected()) |
81 | - { |
82 | - LOG_DEBUG(logger) << "Skipping activation. Proxy not connected. ('" << id_ << "')"; |
83 | - return; |
84 | - } |
85 | + { |
86 | + LOG_DEBUG(logger) << "Skipping activation. Proxy not connected. ('" << id_ << "')"; |
87 | + return; |
88 | + } |
89 | |
90 | proxy_->Call("Activate", |
91 | g_variant_new("(su)", uri.c_str(), |
92 | UNITY_PROTOCOL_ACTION_TYPE_ACTIVATE_RESULT), |
93 | - sigc::mem_fun(this, &Lens::Impl::ActivationReply)); |
94 | + sigc::bind(sigc::mem_fun(this, &Lens::Impl::ActivationReply), std::nullptr_t())); |
95 | } |
96 | |
97 | -void Lens::Impl::ActivationReply(GVariant* parameters) |
98 | +void Lens::Impl::ActivationReply(GVariant* parameters, PreviewCallback const& slot) |
99 | { |
100 | glib::String uri; |
101 | guint32 handled; |
102 | @@ -548,7 +547,14 @@ |
103 | // but that's not really doable from here |
104 | preview->parent_lens = owner_; |
105 | preview->preview_uri = uri.Str(); |
106 | - owner_->preview_ready.emit(uri.Str(), preview); |
107 | + if (slot) |
108 | + { |
109 | + slot(uri.Str(), preview); |
110 | + } |
111 | + else |
112 | + { |
113 | + owner_->preview_ready.emit(uri.Str(), preview); |
114 | + } |
115 | return; |
116 | } |
117 | } |
118 | @@ -561,27 +567,21 @@ |
119 | } |
120 | } |
121 | |
122 | -void Lens::Impl::Preview(std::string const& uri) |
123 | +void Lens::Impl::Preview(std::string const& uri, GCancellable* cancellable, PreviewCallback const& slot) |
124 | { |
125 | LOG_DEBUG(logger) << "Previewing '" << uri << "' on '" << id_ << "'"; |
126 | |
127 | if (!proxy_->IsConnected()) |
128 | - { |
129 | - LOG_DEBUG(logger) << "Skipping preview. Proxy not connected. ('" << id_ << "')"; |
130 | - return; |
131 | - } |
132 | - |
133 | - if (preview_cancellable_) |
134 | { |
135 | - g_cancellable_cancel(preview_cancellable_); |
136 | + LOG_DEBUG(logger) << "Skipping preview. Proxy not connected. ('" << id_ << "')"; |
137 | + return; |
138 | } |
139 | - preview_cancellable_ = g_cancellable_new (); |
140 | |
141 | proxy_->Call("Activate", |
142 | g_variant_new("(su)", uri.c_str(), |
143 | UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_RESULT), |
144 | - sigc::mem_fun(this, &Lens::Impl::ActivationReply), |
145 | - preview_cancellable_); |
146 | + sigc::bind(sigc::mem_fun(this, &Lens::Impl::ActivationReply), slot), |
147 | + cancellable); |
148 | } |
149 | |
150 | void Lens::Impl::ActivatePreviewAction(std::string const& action_id, |
151 | @@ -608,7 +608,7 @@ |
152 | proxy_->Call("Activate", |
153 | g_variant_new("(su)", activation_uri.c_str(), |
154 | UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_ACTION), |
155 | - sigc::mem_fun(this, &Lens::Impl::ActivationReply)); |
156 | + sigc::bind(sigc::mem_fun(this, &Lens::Impl::ActivationReply), std::nullptr_t())); |
157 | } |
158 | else |
159 | { |
160 | @@ -625,7 +625,7 @@ |
161 | g_variant_new("(sua{sv})", activation_uri.c_str(), |
162 | UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_ACTION, |
163 | &b), |
164 | - sigc::mem_fun(this, &Lens::Impl::ActivationReply)); |
165 | + sigc::bind(sigc::mem_fun(this, &Lens::Impl::ActivationReply), std::nullptr_t())); |
166 | |
167 | g_variant_builder_clear(&b); |
168 | } |
169 | @@ -876,9 +876,9 @@ |
170 | pimpl->Activate(uri); |
171 | } |
172 | |
173 | -void Lens::Preview(std::string const& uri) |
174 | +void Lens::Preview(std::string const& uri, GCancellable* cancellable, PreviewCallback const& slot) |
175 | { |
176 | - pimpl->Preview(uri); |
177 | + pimpl->Preview(uri, cancellable, slot); |
178 | } |
179 | |
180 | void Lens::ActivatePreviewAction(std::string const& action_id, |
181 | |
182 | === modified file 'UnityCore/Lens.h' |
183 | --- UnityCore/Lens.h 2012-11-14 08:57:56 +0000 |
184 | +++ UnityCore/Lens.h 2012-12-10 10:03:24 +0000 |
185 | @@ -52,6 +52,8 @@ |
186 | LENS_VIEW |
187 | }; |
188 | |
189 | +typedef std::function<void(std::string const&, Preview::Ptr const&)> PreviewCallback; |
190 | + |
191 | class Lens : public sigc::trackable, boost::noncopyable |
192 | { |
193 | public: |
194 | @@ -85,7 +87,7 @@ |
195 | virtual void GlobalSearch(std::string const& search_string, SearchFinishedCallback const& cb = nullptr); |
196 | virtual void Search(std::string const& search_string, SearchFinishedCallback const& cb = nullptr); |
197 | virtual void Activate(std::string const& uri); |
198 | - virtual void Preview(std::string const& uri); |
199 | + virtual void Preview(std::string const& uri, GCancellable* cancellable, PreviewCallback const& slot); |
200 | virtual void ActivatePreviewAction(std::string const& action_id, |
201 | std::string const& uri, |
202 | Hints const& hints); |
203 | |
204 | === added file 'UnityCore/PreviewPreCacher.cpp' |
205 | --- UnityCore/PreviewPreCacher.cpp 1970-01-01 00:00:00 +0000 |
206 | +++ UnityCore/PreviewPreCacher.cpp 2012-12-10 10:03:24 +0000 |
207 | @@ -0,0 +1,270 @@ |
208 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
209 | +/* |
210 | + * Copyright (C) 2012 Canonical Ltd |
211 | + * |
212 | + * This program is free software: you can redistribute it and/or modify |
213 | + * it under the terms of the GNU General Public License version 3 as |
214 | + * published by the Free Software Foundation. |
215 | + * |
216 | + * This program is distributed in the hope that it will be useful, |
217 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
218 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
219 | + * GNU General Public License for more details. |
220 | + * |
221 | + * You should have received a copy of the GNU General Public License |
222 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
223 | + * |
224 | + * Authored by: Nick Dedekind <nick.dedekind@canonical.com> |
225 | + */ |
226 | + |
227 | +#include "PreviewPreCacher.h" |
228 | +#include "Category.h" |
229 | + |
230 | +namespace unity |
231 | +{ |
232 | +namespace dash |
233 | +{ |
234 | +namespace previews |
235 | +{ |
236 | +DECLARE_LOGGER(logger, "unity.dash.preview.precacher"); |
237 | + |
238 | +const std::string PREVIEW_IDLE = "preview-idle"; |
239 | +const std::string CACHE_IDLE = "cache-idle"; |
240 | + |
241 | +const unsigned int CACHE_TIMEOUT = 100; |
242 | + |
243 | +PreviewPreCacher::PreviewPreCacher(Lens::Ptr const& lens, int cache_range) |
244 | +: lens_(lens) |
245 | +, cache_center_(0) |
246 | +, cache_delta_(0) |
247 | +, precaching_completeness(0) |
248 | +, cache_range_(cache_range) |
249 | +, category_index_(-1) |
250 | +, cache_cancel_(g_cancellable_new()) |
251 | +{ |
252 | + if (lens_) |
253 | + { |
254 | + lens_->preview_ready.connect(sigc::mem_fun(this, &PreviewPreCacher::CenterPreview)); |
255 | + |
256 | + Categories::Ptr categories = lens_->categories; |
257 | + categories->category_added.connect([&](Category const& category) {OnLensCategoryUpdated();}); |
258 | + categories->category_removed.connect([&](Category const& category) {OnLensCategoryUpdated();}); |
259 | + } |
260 | +} |
261 | + |
262 | +PreviewPreCacher::~PreviewPreCacher() |
263 | +{ |
264 | +} |
265 | + |
266 | +void PreviewPreCacher::OnLensCategoryUpdated() |
267 | +{ |
268 | + if (category_index_ == -1) |
269 | + return; |
270 | + if (lens_) |
271 | + result_model_ = lens_->GetFilterModelForCategory(category_index_); |
272 | +} |
273 | + |
274 | +void PreviewPreCacher::UpdateCategory(int category_index) |
275 | +{ |
276 | + if (category_index_ != category_index) |
277 | + { |
278 | + category_index_ = category_index; |
279 | + ClearCache(); |
280 | + OnLensCategoryUpdated(); |
281 | + } |
282 | +} |
283 | + |
284 | +void PreviewPreCacher::Preview(std::string const& uri, int category_index) |
285 | +{ |
286 | + UpdateCategory(category_index); |
287 | + |
288 | + if (preview_cancel_) |
289 | + g_cancellable_cancel (preview_cancel_); |
290 | + preview_cancel_ = g_cancellable_new (); |
291 | + |
292 | + auto iter = preview_uri_cache_.find(uri); |
293 | + if (iter != preview_uri_cache_.end()) |
294 | + { |
295 | + Preview::Ptr preview(iter->second); |
296 | + sources_.Remove(PREVIEW_IDLE); |
297 | + sources_.AddIdle([&, uri, preview]() |
298 | + { |
299 | + preview_ready.emit(uri, preview); |
300 | + |
301 | + // set the current center point. |
302 | + ResetPreCachePosition(GetResultIndexForUri(uri)); |
303 | + return FALSE; |
304 | + }, PREVIEW_IDLE); |
305 | + } |
306 | + else if (lens_) |
307 | + { |
308 | + lens_->Preview(uri, preview_cancel_, sigc::mem_fun(this, &PreviewPreCacher::CenterPreview)); |
309 | + } |
310 | +} |
311 | + |
312 | +void PreviewPreCacher::ClearCache() |
313 | +{ |
314 | + if (cache_cancel_) |
315 | + g_cancellable_cancel (cache_cancel_); |
316 | + cache_cancel_ = g_cancellable_new (); |
317 | + |
318 | + preview_index_cache_.clear(); |
319 | + preview_uri_cache_.clear(); |
320 | +} |
321 | + |
322 | +void PreviewPreCacher::CenterPreview(std::string const& uri, Preview::Ptr const& preview) |
323 | +{ |
324 | + // forward the signal. |
325 | + preview_ready.emit(uri, preview); |
326 | + |
327 | + if (category_index_ == -1) |
328 | + return; |
329 | + |
330 | + int index = GetResultIndexForUri(uri); |
331 | + preview_index_cache_[index] = preview; |
332 | + preview_uri_cache_[uri] = preview; |
333 | + ResetPreCachePosition(index); |
334 | +} |
335 | + |
336 | +void PreviewPreCacher::RecvPreviewPreCache(std::string const& uri, Preview::Ptr const& preview) |
337 | +{ |
338 | + int index = GetResultIndexForUri(uri); |
339 | + |
340 | + preview_index_cache_[index] = preview; |
341 | + preview_uri_cache_[uri] = preview; |
342 | + QueuePreCache(); |
343 | +} |
344 | + |
345 | +void PreviewPreCacher::ResetPreCachePosition(int index) |
346 | +{ |
347 | + if (index < 0 || index >=(int)GetResultCount()) |
348 | + return; |
349 | + |
350 | + cache_center_ = index; |
351 | + cache_delta_ = 0; |
352 | + precaching_completeness = 0; |
353 | + QueuePreCache(); |
354 | +} |
355 | + |
356 | +void PreviewPreCacher::QueuePreCache() |
357 | +{ |
358 | + sources_.AddTimeout(CACHE_TIMEOUT, [&]() |
359 | + { |
360 | + ContinuePreCaching(); |
361 | + return FALSE; |
362 | + }, CACHE_IDLE); |
363 | +} |
364 | + |
365 | +void PreviewPreCacher::ContinuePreCaching() |
366 | +{ |
367 | + if (precaching_completeness > 1) |
368 | + { |
369 | + OnPreCacheComplete(); |
370 | + return; |
371 | + } |
372 | + |
373 | + if (cache_delta_ > 0) |
374 | + cache_delta_ = -cache_delta_; |
375 | + else |
376 | + cache_delta_ = (-cache_delta_) +1; |
377 | + |
378 | + int next_position = cache_center_ + cache_delta_; |
379 | + |
380 | + // get min and max positions away from cache center position. |
381 | + int min_range = cache_range_ < 0 ? 0 : std::max<int>(0, cache_center_ - cache_range_); |
382 | + int max_range = cache_range_ < 0 ? GetResultCount() : std::min<int>(GetResultCount(), cache_center_ + cache_range_ + 1); |
383 | + |
384 | + if (next_position < min_range || next_position >= max_range) |
385 | + { |
386 | + precaching_completeness++; |
387 | + ContinuePreCaching(); |
388 | + return; |
389 | + } |
390 | + precaching_completeness=0; |
391 | + |
392 | + auto iter = preview_index_cache_.find(next_position); |
393 | + if (iter != preview_index_cache_.end()) |
394 | + { |
395 | + // position in result may have changed. |
396 | + std::string uri_at_next_position_current = GetUriForResultIndex(next_position); |
397 | + |
398 | + auto iter_preview_from_uri = preview_uri_cache_.find(uri_at_next_position_current); |
399 | + if (iter_preview_from_uri != preview_uri_cache_.end()) |
400 | + { |
401 | + preview_index_cache_[next_position] = iter_preview_from_uri->second; |
402 | + } |
403 | + QueuePreCache(); |
404 | + } |
405 | + else if (!ExecutePreCache(next_position, GetUriForResultIndex(next_position))) |
406 | + { |
407 | + QueuePreCache(); |
408 | + } |
409 | +} |
410 | + |
411 | +void PreviewPreCacher::OnPreCacheComplete() |
412 | +{ |
413 | +} |
414 | + |
415 | +bool PreviewPreCacher::ExecutePreCache(int index, std::string const& uri) |
416 | +{ |
417 | + auto iter = preview_uri_cache_.find(uri); |
418 | + if (iter != preview_uri_cache_.end()) |
419 | + { |
420 | + preview_index_cache_[index] = iter->second; |
421 | + return false; |
422 | + } |
423 | + |
424 | + LOG_DEBUG(logger) << "Preview pre-cache for '" << uri << "'"; |
425 | + lens_->Preview(uri, cache_cancel_, sigc::mem_fun(this, &PreviewPreCacher::RecvPreviewPreCache)); |
426 | + return true; |
427 | +} |
428 | + |
429 | +unsigned int PreviewPreCacher::GetResultIndexForUri(std::string const& uri) |
430 | +{ |
431 | + unsigned int index = 0; |
432 | + for (ResultIterator it(GetResultIteratorAtIndex(0)); !it.IsLast(); ++it) |
433 | + { |
434 | + if ((*it).uri == uri) |
435 | + break; |
436 | + |
437 | + index++; |
438 | + } |
439 | + |
440 | + return index; |
441 | +} |
442 | + |
443 | +std::string PreviewPreCacher::GetUriForResultIndex(unsigned int index) |
444 | +{ |
445 | + if (index >= GetResultCount()) |
446 | + return ""; |
447 | + |
448 | + return (*GetResultIteratorAtIndex(index)).uri(); |
449 | +} |
450 | + |
451 | +unsigned int PreviewPreCacher::GetResultCount() const |
452 | +{ |
453 | + if (result_model_) |
454 | + { |
455 | + return dee_model_get_n_rows(result_model_); |
456 | + } |
457 | + |
458 | + return 0; |
459 | +} |
460 | + |
461 | +ResultIterator PreviewPreCacher::GetResultIteratorAtIndex(unsigned index) |
462 | +{ |
463 | + if (!lens_) |
464 | + return ResultIterator(result_model_); |
465 | + |
466 | + DeeModelIter* iter = NULL; |
467 | + if (result_model_) |
468 | + { |
469 | + iter = index > 0 ? dee_model_get_iter_at_row(result_model_, index) : |
470 | + dee_model_get_first_iter(result_model_); |
471 | + } |
472 | + return ResultIterator(result_model_, iter, lens_->results()->GetTag()); |
473 | +} |
474 | + |
475 | +} // namespace previews |
476 | +} // namespace dash |
477 | +} // namespace unity |
478 | \ No newline at end of file |
479 | |
480 | === added file 'UnityCore/PreviewPreCacher.h' |
481 | --- UnityCore/PreviewPreCacher.h 1970-01-01 00:00:00 +0000 |
482 | +++ UnityCore/PreviewPreCacher.h 2012-12-10 10:03:24 +0000 |
483 | @@ -0,0 +1,94 @@ |
484 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
485 | +/* |
486 | + * Copyright 2012 Canonical Ltd. |
487 | + * |
488 | + * This program is free software: you can redistribute it and/or modify it |
489 | + * under the terms of the GNU Lesser General Public License version 3, as |
490 | + * published by the Free Software Foundation. |
491 | + * |
492 | + * This program is distributed in the hope that it will be useful, but |
493 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
494 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
495 | + * PURPOSE. See the applicable version of the GNU Lesser General Public |
496 | + * License for more details. |
497 | + * |
498 | + * You should have received a copy of both the GNU Lesser General Public |
499 | + * License version 3 along with this program. If not, see |
500 | + * <http://www.gnu.org/licenses/> |
501 | + * |
502 | + * Authored by: Nick Dedekind <nick.dedekind@canonical.com> |
503 | + * |
504 | + */ |
505 | + |
506 | +#ifndef PREVIEW_PRECACHER_H |
507 | +#define PREVIEW_PRECACHER_H |
508 | + |
509 | +#include <functional> |
510 | +#include <memory> |
511 | +#include "Preview.h" |
512 | +#include "ResultIterator.h" |
513 | +#include "GLibSource.h" |
514 | +#include "Lens.h" |
515 | + |
516 | +namespace unity |
517 | +{ |
518 | +namespace dash |
519 | +{ |
520 | + |
521 | +namespace previews |
522 | +{ |
523 | + |
524 | +class PreviewPreCacher |
525 | +{ |
526 | +public: |
527 | + typedef std::shared_ptr<PreviewPreCacher> Ptr; |
528 | + |
529 | + PreviewPreCacher(Lens::Ptr const& lens, int cache_range); |
530 | + virtual ~PreviewPreCacher(); |
531 | + |
532 | + void Preview(std::string const& uri, int category_index); |
533 | + void ClearCache(); |
534 | + |
535 | + sigc::signal<void, std::string const&, Preview::Ptr const&> preview_ready; |
536 | + |
537 | +protected: |
538 | + void CenterPreview(std::string const& uri, Preview::Ptr const& preview); |
539 | + void RecvPreviewPreCache(std::string const& uri, Preview::Ptr const& preview); |
540 | + |
541 | +protected: |
542 | + void ResetPreCachePosition(int index); |
543 | + void ContinuePreCaching(); |
544 | + |
545 | + void UpdateCategory(int category_index); |
546 | + void OnLensCategoryUpdated(); |
547 | + ResultIterator GetResultIteratorAtIndex(unsigned index); |
548 | + |
549 | + virtual void QueuePreCache(); |
550 | + virtual bool ExecutePreCache(int index, std::string const& uri); |
551 | + virtual void OnPreCacheComplete(); |
552 | + |
553 | + // result accessors |
554 | + virtual unsigned int GetResultCount() const; |
555 | + virtual unsigned int GetResultIndexForUri(std::string const& uri); |
556 | + virtual std::string GetUriForResultIndex(unsigned int index); |
557 | + |
558 | + Lens::Ptr lens_; |
559 | + std::map<int, Preview::Ptr> preview_index_cache_; |
560 | + std::map<std::string, Preview::Ptr> preview_uri_cache_; |
561 | + int cache_center_; |
562 | + int cache_delta_; |
563 | + int precaching_completeness; |
564 | + int cache_range_; |
565 | + |
566 | + int category_index_; |
567 | + glib::Object<DeeModel> result_model_; |
568 | + glib::Object<GCancellable> preview_cancel_; |
569 | + glib::Object<GCancellable> cache_cancel_; |
570 | + glib::SourceManager sources_; |
571 | +}; |
572 | + |
573 | +} // namespace previews |
574 | +} // namespace dash |
575 | +} // namespace unity |
576 | + |
577 | +#endif // PREVIEW_PRECACHER_H |
578 | |
579 | === modified file 'dash/DashView.cpp' |
580 | --- dash/DashView.cpp 2012-11-23 23:49:46 +0000 |
581 | +++ dash/DashView.cpp 2012-12-10 10:03:24 +0000 |
582 | @@ -407,8 +407,13 @@ |
583 | lenses_layout_ = new nux::VLayout(); |
584 | content_layout_->AddView(lenses_layout_, 1, nux::MINOR_POSITION_START); |
585 | |
586 | - home_view_ = new LensView(home_lens_, nullptr); |
587 | + home_view_ = new LensView(home_lens_, nullptr, NUX_TRACKER_LOCATION); |
588 | home_view_->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated)); |
589 | + home_view_->RegisterForPreviews([&] (std::string const& uri, Preview::Ptr const& model) |
590 | + { |
591 | + LOG_DEBUG(logger) << "Got home preview for: " << uri; |
592 | + preview_state_machine_.ActivatePreview(model); // this does not immediately display a preview - we now wait. |
593 | + }); |
594 | |
595 | AddChild(home_view_); |
596 | active_lens_view_ = home_view_; |
597 | @@ -935,7 +940,7 @@ |
598 | std::string id = lens->id; |
599 | lens_bar_->AddLens(lens); |
600 | |
601 | - LensView* view = new LensView(lens, search_bar_->show_filters()); |
602 | + LensView* view = new LensView(lens, search_bar_->show_filters(), NUX_TRACKER_LOCATION); |
603 | AddChild(view); |
604 | view->SetVisible(false); |
605 | view->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated)); |
606 | @@ -957,7 +962,7 @@ |
607 | }); |
608 | |
609 | // Hook up to the new preview infrastructure |
610 | - lens->preview_ready.connect([&] (std::string const& uri, Preview::Ptr model) |
611 | + view->RegisterForPreviews([&] (std::string const& uri, Preview::Ptr const& model) |
612 | { |
613 | LOG_DEBUG(logger) << "Got preview for: " << uri; |
614 | preview_state_machine_.ActivatePreview(model); // this does not immediately display a preview - we now wait. |
615 | |
616 | === modified file 'dash/LensView.cpp' |
617 | --- dash/LensView.cpp 2012-11-26 16:09:53 +0000 |
618 | +++ dash/LensView.cpp 2012-12-10 10:03:24 +0000 |
619 | @@ -137,15 +137,8 @@ |
620 | |
621 | NUX_IMPLEMENT_OBJECT_TYPE(LensView); |
622 | |
623 | -LensView::LensView() |
624 | - : nux::View(NUX_TRACKER_LOCATION) |
625 | - , filters_expanded(false) |
626 | - , can_refine_search(false) |
627 | - , no_results_active_(false) |
628 | -{} |
629 | - |
630 | -LensView::LensView(Lens::Ptr lens, nux::Area* show_filters) |
631 | - : nux::View(NUX_TRACKER_LOCATION) |
632 | +LensView::LensView(Lens::Ptr const& lens, nux::Area* show_filters, NUX_FILE_LINE_DECL) |
633 | + : nux::View(NUX_FILE_LINE_PARAM) |
634 | , filters_expanded(false) |
635 | , can_refine_search(false) |
636 | , lens_(lens) |
637 | @@ -153,6 +146,7 @@ |
638 | , no_results_active_(false) |
639 | , last_expanded_group_(nullptr) |
640 | , last_good_filter_model_(-1) |
641 | + , preview_precacher_(new previews::PreviewPreCacher(lens, -1)) |
642 | { |
643 | SetupViews(show_filters); |
644 | SetupCategories(); |
645 | @@ -207,6 +201,10 @@ |
646 | |
647 | } |
648 | |
649 | +LensView::~LensView() |
650 | +{ |
651 | +} |
652 | + |
653 | void LensView::SetupViews(nux::Area* show_filters) |
654 | { |
655 | dash::Style& style = dash::Style::Instance(); |
656 | @@ -366,7 +364,7 @@ |
657 | grid->expanded = false; |
658 | |
659 | group->SetRendererName(renderer_name.c_str()); |
660 | - grid->UriActivated.connect(sigc::bind([&] (std::string const& uri, ResultView::ActivateType type, GVariant* data, std::string const& view_id) |
661 | + grid->UriActivated.connect(sigc::bind([&] (std::string const& uri, ResultView::ActivateType type, GVariant* data, std::string const& view_id, int catgory_index) |
662 | { |
663 | uri_activated.emit(type, uri, data, view_id); |
664 | switch (type) |
665 | @@ -377,13 +375,12 @@ |
666 | } break; |
667 | case ResultView::ActivateType::PREVIEW: |
668 | { |
669 | - lens_->Preview(uri); |
670 | + preview_precacher_->Preview(uri, catgory_index); |
671 | } break; |
672 | default: break; |
673 | }; |
674 | |
675 | - }, unique_id)); |
676 | - |
677 | + }, unique_id, category.index.Get())); |
678 | |
679 | /* Set up filter model for this category */ |
680 | Results::Ptr results_model = lens_->results; |
681 | @@ -793,6 +790,11 @@ |
682 | } |
683 | } |
684 | |
685 | +sigc::connection LensView::RegisterForPreviews(PreviewCallback const& callback) |
686 | +{ |
687 | + return preview_precacher_->preview_ready.connect(callback); |
688 | +} |
689 | + |
690 | // Keyboard navigation |
691 | bool LensView::AcceptKeyNavFocus() |
692 | { |
693 | |
694 | === modified file 'dash/LensView.h' |
695 | --- dash/LensView.h 2012-11-14 08:57:56 +0000 |
696 | +++ dash/LensView.h 2012-12-10 10:03:24 +0000 |
697 | @@ -29,6 +29,7 @@ |
698 | #include <Nux/VLayout.h> |
699 | #include <UnityCore/Lens.h> |
700 | #include <UnityCore/GLibSource.h> |
701 | +#include "UnityCore/PreviewPreCacher.h" |
702 | |
703 | #include "FilterBar.h" |
704 | #include "unity-shared/Introspectable.h" |
705 | @@ -50,8 +51,8 @@ |
706 | typedef std::map<PlacesGroup*, unsigned int> ResultCounts; |
707 | |
708 | public: |
709 | - LensView(); |
710 | - LensView(Lens::Ptr lens, nux::Area* show_filters); |
711 | + LensView(Lens::Ptr const& lens, nux::Area* show_filters, NUX_FILE_LINE_DECL); |
712 | + ~LensView(); |
713 | |
714 | CategoryGroups& categories() { return categories_; } |
715 | FilterBar* filter_bar() const { return filter_bar_; } |
716 | @@ -75,6 +76,8 @@ |
717 | void CheckCategoryExpansion(); |
718 | void HideResultsMessage(); |
719 | |
720 | + sigc::connection RegisterForPreviews(PreviewCallback const& callback); |
721 | + |
722 | private: |
723 | void SetupViews(nux::Area* show_filters); |
724 | void SetupCategories(); |
725 | @@ -124,9 +127,10 @@ |
726 | nux::StaticCairoText* no_results_; |
727 | |
728 | UBusManager ubus_manager_; |
729 | - glib::Source::UniquePtr model_updated_timeout_; |
730 | + glib::Source::UniquePtr model_updated_timeout_; |
731 | int last_good_filter_model_; |
732 | glib::Source::UniquePtr fix_filter_models_idle_; |
733 | + previews::PreviewPreCacher::Ptr preview_precacher_; |
734 | }; |
735 | |
736 | |
737 | |
738 | === modified file 'dash/previews/ApplicationPreview.cpp' |
739 | --- dash/previews/ApplicationPreview.cpp 2012-11-26 16:09:53 +0000 |
740 | +++ dash/previews/ApplicationPreview.cpp 2012-12-10 10:03:24 +0000 |
741 | @@ -305,11 +305,11 @@ |
742 | nux::Geometry geo_art(geo.x, geo.y, style.GetAppImageAspectRatio() * geo.height, geo.height); |
743 | |
744 | if (geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() < style.GetDetailsPanelMinimumWidth()) |
745 | - geo_art.width = MAX(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
746 | + geo_art.width = std::max(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
747 | image_->SetMinMaxSize(geo_art.width, geo_art.height); |
748 | |
749 | - int details_width = MAX(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
750 | - int top_app_info_max_width = MAX(0, details_width - style.GetAppIconAreaWidth() - style.GetSpaceBetweenIconAndDetails()); |
751 | + int details_width = std::max(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
752 | + int top_app_info_max_width = std::max(0, details_width - style.GetAppIconAreaWidth() - style.GetSpaceBetweenIconAndDetails()); |
753 | |
754 | if (title_) { title_->SetMaximumWidth(top_app_info_max_width); } |
755 | if (subtitle_) { subtitle_->SetMaximumWidth(top_app_info_max_width); } |
756 | |
757 | === modified file 'dash/previews/GenericPreview.cpp' |
758 | --- dash/previews/GenericPreview.cpp 2012-11-13 21:42:58 +0000 |
759 | +++ dash/previews/GenericPreview.cpp 2012-12-10 10:03:24 +0000 |
760 | @@ -232,10 +232,10 @@ |
761 | nux::Geometry geo_art(geo.x, geo.y, style.GetAppImageAspectRatio() * geo.height, geo.height); |
762 | |
763 | if (geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() < style.GetDetailsPanelMinimumWidth()) |
764 | - geo_art.width = MAX(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
765 | + geo_art.width = std::max(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
766 | image_->SetMinMaxSize(geo_art.width, geo_art.height); |
767 | |
768 | - int details_width = MAX(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
769 | + int details_width = std::max(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
770 | |
771 | if (title_) { title_->SetMaximumWidth(details_width); } |
772 | if (subtitle_) { subtitle_->SetMaximumWidth(details_width); } |
773 | |
774 | === modified file 'dash/previews/MoviePreview.cpp' |
775 | --- dash/previews/MoviePreview.cpp 2012-11-13 21:42:58 +0000 |
776 | +++ dash/previews/MoviePreview.cpp 2012-12-10 10:03:24 +0000 |
777 | @@ -250,10 +250,10 @@ |
778 | nux::Geometry geo_art(geo.x, geo.y, style.GetVideoImageAspectRatio() * geo.height, geo.height); |
779 | |
780 | if (geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() < style.GetDetailsPanelMinimumWidth()) |
781 | - geo_art.width = MAX(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
782 | + geo_art.width = std::max(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
783 | image_->SetMinMaxSize(geo_art.width, geo_art.height); |
784 | |
785 | - int details_width = MAX(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
786 | + int details_width = std::max(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
787 | |
788 | if (title_) { title_->SetMaximumWidth(details_width); } |
789 | if (subtitle_) { subtitle_->SetMaximumWidth(details_width); } |
790 | |
791 | === modified file 'dash/previews/MusicPreview.cpp' |
792 | --- dash/previews/MusicPreview.cpp 2012-11-06 18:19:09 +0000 |
793 | +++ dash/previews/MusicPreview.cpp 2012-12-10 10:03:24 +0000 |
794 | @@ -264,10 +264,10 @@ |
795 | nux::Geometry geo_art(geo.x, geo.y, style.GetAppImageAspectRatio() * geo.height, geo.height); |
796 | |
797 | if (geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() < style.GetDetailsPanelMinimumWidth()) |
798 | - geo_art.width = MAX(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
799 | + geo_art.width = std::max(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
800 | image_->SetMinMaxSize(geo_art.width, geo_art.height); |
801 | |
802 | - int details_width = MAX(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
803 | + int details_width = std::max(0, geo.width - geo_art.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
804 | |
805 | if (title_) { title_->SetMaximumWidth(details_width); } |
806 | if (subtitle_) { subtitle_->SetMaximumWidth(details_width); } |
807 | |
808 | === modified file 'dash/previews/PreviewContainer.cpp' |
809 | --- dash/previews/PreviewContainer.cpp 2012-11-30 20:22:13 +0000 |
810 | +++ dash/previews/PreviewContainer.cpp 2012-12-10 10:03:24 +0000 |
811 | @@ -412,7 +412,7 @@ |
812 | |
813 | void PreviewContainer::Preview(dash::Preview::Ptr preview_model, Navigation direction) |
814 | { |
815 | - previews::Preview::Ptr preview_view = previews::Preview::PreviewForModel(preview_model); |
816 | + previews::Preview::Ptr preview_view = preview_model ? previews::Preview::PreviewForModel(preview_model) : previews::Preview::Ptr(); |
817 | |
818 | if (preview_view) |
819 | { |
820 | |
821 | === modified file 'dash/previews/PreviewInfoHintWidget.cpp' |
822 | --- dash/previews/PreviewInfoHintWidget.cpp 2012-11-06 18:19:09 +0000 |
823 | +++ dash/previews/PreviewInfoHintWidget.cpp 2012-12-10 10:03:24 +0000 |
824 | @@ -209,7 +209,7 @@ |
825 | int info_value_width = geo.width; |
826 | info_value_width -= layout_spacing; |
827 | info_value_width -= info_hint_width; |
828 | - info_value_width = MAX(0, info_value_width); |
829 | + info_value_width = std::max(0, info_value_width); |
830 | |
831 | for (InfoHint const& info_hint : info_hints_) |
832 | { |
833 | |
834 | === modified file 'dash/previews/SocialPreview.cpp' |
835 | --- dash/previews/SocialPreview.cpp 2012-11-26 16:09:53 +0000 |
836 | +++ dash/previews/SocialPreview.cpp 2012-12-10 10:03:24 +0000 |
837 | @@ -281,12 +281,12 @@ |
838 | nux::Geometry geo_content(geo.x, geo.y, style.GetAppImageAspectRatio() * geo.height, geo.height); |
839 | |
840 | if (geo.width - geo_content.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() < style.GetDetailsPanelMinimumWidth()) |
841 | - geo_content.width = MAX(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
842 | + geo_content.width = std::max(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); |
843 | if (content_) { content_->SetMinMaxSize(geo_content.width, geo_content.height); } |
844 | if (image_) { image_->SetMinMaxSize(geo_content.width, geo_content.height); } |
845 | |
846 | - int details_width = MAX(0, geo.width - geo_content.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
847 | - int top_social_info_max_width = details_width - style.GetAppIconAreaWidth() - style.GetSpaceBetweenIconAndDetails(); |
848 | + int details_width = std::max(0, geo.width - geo_content.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
849 | + int top_social_info_max_width = std::max(details_width - style.GetAppIconAreaWidth() - style.GetSpaceBetweenIconAndDetails(), 0); |
850 | |
851 | if (title_) { title_->SetMaximumWidth(top_social_info_max_width); } |
852 | if (subtitle_) { subtitle_->SetMaximumWidth(top_social_info_max_width); } |
853 | |
854 | === modified file 'dash/previews/SocialPreviewComments.cpp' |
855 | --- dash/previews/SocialPreviewComments.cpp 2012-11-08 09:12:24 +0000 |
856 | +++ dash/previews/SocialPreviewComments.cpp 2012-12-10 10:03:24 +0000 |
857 | @@ -102,7 +102,7 @@ |
858 | } |
859 | } |
860 | |
861 | - int comment_value_width = MAX(0, geo.width - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
862 | + int comment_value_width = std::max(0, geo.width - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); |
863 | |
864 | for (Comment const& comment : comments_) |
865 | { |
866 | |
867 | === modified file 'dash/previews/SocialPreviewContent.cpp' |
868 | --- dash/previews/SocialPreviewContent.cpp 2012-11-16 19:22:31 +0000 |
869 | +++ dash/previews/SocialPreviewContent.cpp 2012-12-10 10:03:24 +0000 |
870 | @@ -149,8 +149,8 @@ |
871 | |
872 | nux::Geometry geo_cr(GetBubbleGeometry(geo)); |
873 | |
874 | - int max_width = geo_cr.width - 2*(geo_cr.width*0.1); |
875 | - int max_height = (geo_cr.height - TAIL_HEIGHT) - 2*((geo_cr.height - TAIL_HEIGHT)*0.1); |
876 | + int max_width = std::max(0, (int)(geo_cr.width - 2*(geo_cr.width*0.1))); |
877 | + int max_height = std::max(0, (int)((geo_cr.height - TAIL_HEIGHT) - 2*((geo_cr.height - TAIL_HEIGHT)*0.1))); |
878 | |
879 | // this will update the texture with the actual size of the text. |
880 | text_->SetMaximumHeight(max_height); |
881 | @@ -169,8 +169,8 @@ |
882 | |
883 | void SocialPreviewContent::RedrawBubble(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state) |
884 | { |
885 | - double width = MAX(0, cairo_image_surface_get_width(cairo_get_target(cr))); |
886 | - double height = MAX(0, cairo_image_surface_get_height(cairo_get_target(cr)) - TAIL_HEIGHT); |
887 | + double width = std::max(0, cairo_image_surface_get_width(cairo_get_target(cr))); |
888 | + double height = std::max(0, cairo_image_surface_get_height(cairo_get_target(cr)) - TAIL_HEIGHT); |
889 | |
890 | double tailPosition = width - TAIL_POS_FROM_RIGHT - TAIL_HEIGHT; |
891 | if (width > 0 && height > 0) |
892 | |
893 | === modified file 'tests/CMakeLists.txt' |
894 | --- tests/CMakeLists.txt 2012-12-05 09:10:04 +0000 |
895 | +++ tests/CMakeLists.txt 2012-12-10 10:03:24 +0000 |
896 | @@ -130,6 +130,7 @@ |
897 | test_layout_system.cpp |
898 | test_model_iterator.cpp |
899 | test_previews.cpp |
900 | + test_previews_precacher.cpp |
901 | test_time_util.cpp |
902 | test_ubus.cpp |
903 | test_unityshell_private.cpp |
904 | |
905 | === modified file 'tests/test_lens.cpp' |
906 | --- tests/test_lens.cpp 2012-11-14 08:57:56 +0000 |
907 | +++ tests/test_lens.cpp 2012-12-10 10:03:24 +0000 |
908 | @@ -228,9 +228,7 @@ |
909 | previewed = true; |
910 | }; |
911 | |
912 | - lens_->preview_ready.connect(preview_cb); |
913 | - |
914 | - lens_->Preview(uri); |
915 | + lens_->Preview(uri, NULL, preview_cb); |
916 | Utils::WaitUntil(previewed); |
917 | } |
918 | |
919 | @@ -251,8 +249,7 @@ |
920 | previewed = true; |
921 | }; |
922 | |
923 | - lens_->preview_ready.connect(preview_cb); |
924 | - lens_->Preview(uri); |
925 | + lens_->Preview(uri, NULL, preview_cb); |
926 | |
927 | Utils::WaitUntil(previewed); |
928 | |
929 | @@ -290,8 +287,7 @@ |
930 | previewed = true; |
931 | }; |
932 | |
933 | - lens_->preview_ready.connect(preview_cb); |
934 | - lens_->Preview(uri); |
935 | + lens_->Preview(uri, NULL, preview_cb); |
936 | |
937 | Utils::WaitUntil(previewed); |
938 | |
939 | @@ -336,7 +332,7 @@ |
940 | }; |
941 | |
942 | lens_->preview_ready.connect(preview_cb); |
943 | - lens_->Preview(uri); |
944 | + lens_->Preview(uri, NULL, std::nullptr_t()); |
945 | |
946 | Utils::WaitUntil(previewed); |
947 | } |
948 | |
949 | === added file 'tests/test_previews_precacher.cpp' |
950 | --- tests/test_previews_precacher.cpp 1970-01-01 00:00:00 +0000 |
951 | +++ tests/test_previews_precacher.cpp 2012-12-10 10:03:24 +0000 |
952 | @@ -0,0 +1,224 @@ |
953 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
954 | +/* |
955 | + * Copyright (C) 2012 Canonical Ltd |
956 | + * |
957 | + * This program is free software: you can redistribute it and/or modify |
958 | + * it under the terms of the GNU General Public License version 3 as |
959 | + * published by the Free Software Foundation. |
960 | + * |
961 | + * This program is distributed in the hope that it will be useful, |
962 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
963 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
964 | + * GNU General Public License for more details. |
965 | + * |
966 | + * You should have received a copy of the GNU General Public License |
967 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
968 | + * |
969 | + * Authored by: Nick Dedekind <nick.dedekind@canonical.com> |
970 | + */ |
971 | + |
972 | +#include <list> |
973 | +#include <gmock/gmock.h> |
974 | +using namespace testing; |
975 | + |
976 | +#include <Nux/Nux.h> |
977 | + |
978 | +#include "UnityCore/PreviewPreCacher.h" |
979 | + |
980 | +using namespace unity; |
981 | +using namespace unity::dash; |
982 | + |
983 | +namespace |
984 | +{ |
985 | + |
986 | +class MockPreviewPreCacher : public previews::PreviewPreCacher |
987 | +{ |
988 | +public: |
989 | + MockPreviewPreCacher(int cache_range) |
990 | + : PreviewPreCacher(NULL, cache_range) |
991 | + , queue_(true) |
992 | + { |
993 | + ON_CALL (*this, GetResultCount()).WillByDefault(Return(10)); |
994 | + ON_CALL (*this, GetUriForResultIndex(_)).WillByDefault(Return("preview")); |
995 | + ON_CALL (*this, ExecutePreCache(_,_)).WillByDefault(Return(true)); |
996 | + } |
997 | + |
998 | + MOCK_CONST_METHOD0 (GetResultCount, unsigned int()); |
999 | + MOCK_METHOD1 (GetUriForResultIndex, std::string(int)); |
1000 | + MOCK_METHOD2 (ExecutePreCache, bool(int, std::string const&)); |
1001 | + MOCK_METHOD0 (OnPreCacheComplete, void()); |
1002 | + |
1003 | + void enable_queue() { queue_ = true; } |
1004 | + void disable_queue() { queue_ = false; } |
1005 | + |
1006 | + // mock this method so we dont have to wait on idle. |
1007 | + virtual void QueuePreCache() |
1008 | + { |
1009 | + if (queue_) |
1010 | + { |
1011 | + PreviewPreCacher::QueuePreCache(); |
1012 | + } |
1013 | + else |
1014 | + { |
1015 | + ContinuePreCaching(); |
1016 | + } |
1017 | + } |
1018 | + |
1019 | + using PreviewPreCacher::ResetPreCachePosition; |
1020 | + using PreviewPreCacher::ContinuePreCaching; |
1021 | + |
1022 | +private: |
1023 | + bool queue_; |
1024 | +}; |
1025 | + |
1026 | + |
1027 | +TEST(TestPreviewPreCacher, TestMathCenterInside) |
1028 | +{ |
1029 | + NiceMock<MockPreviewPreCacher> cacher(10); |
1030 | + cacher.disable_queue(); |
1031 | + |
1032 | + EXPECT_CALL(cacher, ExecutePreCache(4,_)).Times(1); |
1033 | + cacher.ResetPreCachePosition(3); |
1034 | + |
1035 | + EXPECT_CALL(cacher, ExecutePreCache(2,_)).Times(1); |
1036 | + cacher.ContinuePreCaching(); |
1037 | + |
1038 | + EXPECT_CALL(cacher, ExecutePreCache(5,_)).Times(1); |
1039 | + cacher.ContinuePreCaching(); |
1040 | + |
1041 | + EXPECT_CALL(cacher, ExecutePreCache(1,_)).Times(1); |
1042 | + cacher.ContinuePreCaching(); |
1043 | + |
1044 | + EXPECT_CALL(cacher, ExecutePreCache(6,_)).Times(1); |
1045 | + cacher.ContinuePreCaching(); |
1046 | + |
1047 | + EXPECT_CALL(cacher, ExecutePreCache(0,_)).Times(1); |
1048 | + cacher.ContinuePreCaching(); |
1049 | + |
1050 | + EXPECT_CALL(cacher, ExecutePreCache(7,_)).Times(1); |
1051 | + cacher.ContinuePreCaching(); |
1052 | + |
1053 | + EXPECT_CALL(cacher, ExecutePreCache(8,_)).Times(1); |
1054 | + cacher.ContinuePreCaching(); |
1055 | + |
1056 | + EXPECT_CALL(cacher, ExecutePreCache(9,_)).Times(1); |
1057 | + cacher.ContinuePreCaching(); |
1058 | + |
1059 | + EXPECT_CALL(cacher, OnPreCacheComplete()); |
1060 | + cacher.ContinuePreCaching(); |
1061 | +} |
1062 | + |
1063 | +TEST(TestPreviewPreCacher, TestMathCenterOutsidePositive) |
1064 | +{ |
1065 | + NiceMock<MockPreviewPreCacher> cacher(10); |
1066 | + cacher.disable_queue(); |
1067 | + |
1068 | + EXPECT_CALL(cacher, ExecutePreCache(_,_)).Times(0); |
1069 | + cacher.ResetPreCachePosition(11); |
1070 | +} |
1071 | + |
1072 | +TEST(TestPreviewPreCacher, TestMathCenterOutsideNegative) |
1073 | +{ |
1074 | + NiceMock<MockPreviewPreCacher> cacher(10); |
1075 | + cacher.disable_queue(); |
1076 | + |
1077 | + EXPECT_CALL(cacher, ExecutePreCache(_,_)).Times(0); |
1078 | + cacher.ResetPreCachePosition(-1); |
1079 | +} |
1080 | + |
1081 | +TEST(TestPreviewPreCacher, TestMathCenterBoundaryZero) |
1082 | +{ |
1083 | + NiceMock<MockPreviewPreCacher> cacher(10); |
1084 | + cacher.disable_queue(); |
1085 | + |
1086 | + EXPECT_CALL(cacher, ExecutePreCache(1,_)).Times(1); |
1087 | + cacher.ResetPreCachePosition(0); |
1088 | + |
1089 | + for (int i = 1; i < (int)cacher.GetResultCount()-1; i++) |
1090 | + { |
1091 | + EXPECT_CALL(cacher, ExecutePreCache(i+1,_)).Times(1); |
1092 | + cacher.ContinuePreCaching(); |
1093 | + } |
1094 | + |
1095 | + EXPECT_CALL(cacher, OnPreCacheComplete()); |
1096 | + cacher.ContinuePreCaching(); |
1097 | +} |
1098 | + |
1099 | +TEST(TestPreviewPreCacher, TestMathCenterBoundaryCount) |
1100 | +{ |
1101 | + NiceMock<MockPreviewPreCacher> cacher(10); |
1102 | + cacher.disable_queue(); |
1103 | + |
1104 | + EXPECT_CALL(cacher, ExecutePreCache(_,_)).Times(0); |
1105 | + cacher.ResetPreCachePosition(cacher.GetResultCount()); |
1106 | +} |
1107 | + |
1108 | +TEST(TestPreviewPreCacher, TestMathRangedCenterBottom) |
1109 | +{ |
1110 | + NiceMock<MockPreviewPreCacher> cacher(3); |
1111 | + cacher.disable_queue(); |
1112 | + |
1113 | + EXPECT_CALL(cacher, ExecutePreCache(2,_)).Times(1); |
1114 | + cacher.ResetPreCachePosition(1); |
1115 | + |
1116 | + EXPECT_CALL(cacher, ExecutePreCache(0,_)).Times(1); |
1117 | + cacher.ContinuePreCaching(); |
1118 | + |
1119 | + EXPECT_CALL(cacher, ExecutePreCache(3,_)).Times(1); |
1120 | + cacher.ContinuePreCaching(); |
1121 | + |
1122 | + EXPECT_CALL(cacher, ExecutePreCache(4,_)).Times(1); |
1123 | + cacher.ContinuePreCaching(); |
1124 | + |
1125 | + EXPECT_CALL(cacher, ExecutePreCache(5,_)).Times(0); |
1126 | + EXPECT_CALL(cacher, OnPreCacheComplete()); |
1127 | + cacher.ContinuePreCaching(); |
1128 | +} |
1129 | + |
1130 | +TEST(TestPreviewPreCacher, TestMathRangedCenterMiddle) |
1131 | +{ |
1132 | + NiceMock<MockPreviewPreCacher> cacher(2); |
1133 | + cacher.disable_queue(); |
1134 | + |
1135 | + EXPECT_CALL(cacher, ExecutePreCache(6,_)).Times(1); |
1136 | + cacher.ResetPreCachePosition(5); |
1137 | + |
1138 | + EXPECT_CALL(cacher, ExecutePreCache(4,_)).Times(1); |
1139 | + cacher.ContinuePreCaching(); |
1140 | + |
1141 | + EXPECT_CALL(cacher, ExecutePreCache(7,_)).Times(1); |
1142 | + cacher.ContinuePreCaching(); |
1143 | + |
1144 | + EXPECT_CALL(cacher, ExecutePreCache(3,_)).Times(1); |
1145 | + cacher.ContinuePreCaching(); |
1146 | + |
1147 | + EXPECT_CALL(cacher, ExecutePreCache(8,_)).Times(0); |
1148 | + EXPECT_CALL(cacher, OnPreCacheComplete()); |
1149 | + cacher.ContinuePreCaching(); |
1150 | +} |
1151 | + |
1152 | +TEST(TestPreviewPreCacher, TestMathRangedCenterTop) |
1153 | +{ |
1154 | + NiceMock<MockPreviewPreCacher> cacher(3); |
1155 | + cacher.disable_queue(); |
1156 | + |
1157 | + EXPECT_CALL(cacher, ExecutePreCache(9,_)).Times(1); |
1158 | + cacher.ResetPreCachePosition(8); |
1159 | + |
1160 | + EXPECT_CALL(cacher, ExecutePreCache(7,_)).Times(1); |
1161 | + cacher.ContinuePreCaching(); |
1162 | + |
1163 | + EXPECT_CALL(cacher, ExecutePreCache(6,_)).Times(1); |
1164 | + cacher.ContinuePreCaching(); |
1165 | + |
1166 | + EXPECT_CALL(cacher, ExecutePreCache(5,_)).Times(1); |
1167 | + cacher.ContinuePreCaching(); |
1168 | + |
1169 | + EXPECT_CALL(cacher, ExecutePreCache(4,_)).Times(0); |
1170 | + EXPECT_CALL(cacher, OnPreCacheComplete()); |
1171 | + cacher.ContinuePreCaching(); |
1172 | +} |
1173 | + |
1174 | + |
1175 | + |
1176 | +} |
530 + virtual ~PreviewPreCach er(); ete();
551 + virtual void OnPreCacheCompl
Could we make those pure virtual fucntions?
Or if not could we just do: ete() {}
530 + virtual ~PreviewPreCacher() {}
551 + virtual void OnPreCacheCompl
347 + if (index < 0 || index >=(int) GetResultCount( ))
Does this need to be casted to an int?
758 + int top_social_ info_max_ width = MAX(details_width - style.GetAppIco nAreaWidth( ) - style.GetSpaceB etweenIconAndDe tails() , 0); cr.width* 0.1)); >SetMaximumWidt h(MAX(0, GetGeometry().width - geo.height - style.GetMusicD urationWidth( ) - layout_spacing*2));
772 + int max_width = MAX(0, geo_cr.width - 2*(geo_
773 + int max_height = MAX(0, (geo_cr.height - TAIL_HEIGHT) - 2*((geo_cr.height - TAIL_HEIGHT)*0.1));
786 + title_-
Lets use std::max() here.