diff options
| author | Michal Hruby <michal.mhr@gmail.com> | 2012-08-11 23:29:24 +0200 |
|---|---|---|
| committer | Michal Hruby <michal.mhr@gmail.com> | 2012-08-11 23:29:24 +0200 |
| commit | 4b92db359532b713e1f605beecc21faed3b3a47a (patch) | |
| tree | 5042c81cfa1eaa49706788119d54755206d19211 | |
| parent | 0c9f0ef0dda3d34abf3de49d98a620614b37d8c1 (diff) | |
| parent | a9f5b8d6d2db9a6c30f4385696a62ae1b906a2a7 (diff) | |
Merge Gord's result-iterator branch
(bzr r2547.3.1)
| -rw-r--r-- | UnityCore/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | UnityCore/Model-inl.h | 6 | ||||
| -rw-r--r-- | UnityCore/Model.h | 1 | ||||
| -rw-r--r-- | UnityCore/ResultIterator.cpp | 150 | ||||
| -rw-r--r-- | UnityCore/ResultIterator.h | 103 | ||||
| -rw-r--r-- | UnityCore/Results.cpp | 10 | ||||
| -rw-r--r-- | UnityCore/Results.h | 4 | ||||
| -rw-r--r-- | tests/test_results.cpp | 90 | ||||
| -rw-r--r-- | tests/test_service_model.c | 2 |
9 files changed, 358 insertions, 10 deletions
diff --git a/UnityCore/CMakeLists.txt b/UnityCore/CMakeLists.txt index 0ae006c41..bfc526410 100644 --- a/UnityCore/CMakeLists.txt +++ b/UnityCore/CMakeLists.txt @@ -43,6 +43,7 @@ set (CORE_HEADERS RadioOptionFilter.h RatingsFilter.h Result.h + ResultIterator.h Results.h SeriesPreview.h Track.h @@ -80,6 +81,7 @@ set (CORE_SOURCES RatingsFilter.cpp RadioOptionFilter.cpp Result.cpp + ResultIterator.cpp Results.cpp SeriesPreview.cpp Track.cpp diff --git a/UnityCore/Model-inl.h b/UnityCore/Model-inl.h index ee5b93895..bb97b821f 100644 --- a/UnityCore/Model-inl.h +++ b/UnityCore/Model-inl.h @@ -163,6 +163,12 @@ const RowAdaptor Model<RowAdaptor>::RowAtIndex(std::size_t index) } template<class RowAdaptor> +DeeModelTag* Model<RowAdaptor>::GetTag() +{ + return renderer_tag_; +} + +template<class RowAdaptor> std::size_t Model<RowAdaptor>::get_count() { if (model_) diff --git a/UnityCore/Model.h b/UnityCore/Model.h index 8eb4d14b2..1c14067a7 100644 --- a/UnityCore/Model.h +++ b/UnityCore/Model.h @@ -57,6 +57,7 @@ public: virtual ~Model(); const RowAdaptor RowAtIndex(std::size_t index); + DeeModelTag* GetTag(); nux::Property<std::string> swarm_name; nux::ROProperty<std::size_t> count; diff --git a/UnityCore/ResultIterator.cpp b/UnityCore/ResultIterator.cpp new file mode 100644 index 000000000..9a7387f7a --- /dev/null +++ b/UnityCore/ResultIterator.cpp @@ -0,0 +1,150 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2012 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ + +#include "ResultIterator.h" +#include <NuxCore/Logger.h> +namespace unity +{ +namespace dash +{ + +namespace +{ + nux::logging::Logger logger("unity.dash.resultiterator"); +} + +ResultIterator::ResultIterator(glib::Object<DeeModel> model) + : model_(model, glib::AddRef()) + , iter_(dee_model_get_first_iter(model)) + , tag_(NULL) + , iter_result_(model_, iter_, tag_) + , cache_invalidated_(false) +{ +} + +ResultIterator::ResultIterator(glib::Object<DeeModel> model, DeeModelIter* iter, DeeModelTag* tag) + : model_(model, glib::AddRef()) + , iter_(iter) + , tag_(tag) + , iter_result_(model_, iter_, tag_) + , cache_invalidated_(false) +{ +} + +ResultIterator ResultIterator::operator[](int value) +{ + return ResultIterator(model_, dee_model_get_iter_at_row(model_, value), tag_); +} + +ResultIterator& ResultIterator::operator=(ResultIterator const& rhs) +{ + model_ = rhs.model_; + iter_ = rhs.iter_; + tag_ = rhs.tag_; + iter_result_ = Result(model_, iter_, tag_); + cache_invalidated_ = false; + + return *this; +} + +ResultIterator& ResultIterator::operator++() +{ + iter_ = dee_model_next(model_, iter_); + cache_invalidated_ = true; + return *this; +} + +ResultIterator& ResultIterator::operator+=(int count) +{ + if (dee_model_is_last(model_, iter_)) + return *this; + + for (int index = 0; index < count; index++) + iter_ = dee_model_next(model_, iter_); + + cache_invalidated_ = true; + return *this; +} + +ResultIterator ResultIterator::operator++(int) +{ + ResultIterator tmp(*this); + operator++(); + return tmp; +} + +ResultIterator ResultIterator::operator+(int count) const +{ + ResultIterator tmp(*this); + tmp += count; + return tmp; +} + +ResultIterator& ResultIterator::operator--() +{ + iter_ = dee_model_prev(model_, iter_); + cache_invalidated_ = true; + return *this; +} + +ResultIterator& ResultIterator::operator-=(int count) +{ + if (dee_model_is_first(model_, iter_)) + return *this; + + for (int index = 0; index < count; index++) + iter_ = dee_model_prev(model_, iter_); + + cache_invalidated_ = true; + return *this; +} + +ResultIterator ResultIterator::operator--(int) +{ + ResultIterator tmp(*this); + operator--(); + return tmp; +} + +ResultIterator ResultIterator::operator-(int count) const +{ + ResultIterator tmp(*this); + tmp -= count; + return tmp; +} + +Result const& ResultIterator::operator*() +{ + if (cache_invalidated_) + iter_result_ = Result(model_, iter_, tag_); + return iter_result_; +} + +bool const ResultIterator::IsLast() +{ + return (dee_model_is_last(model_, iter_)); +} + +bool const ResultIterator::IsFirst() +{ + return (dee_model_is_first(model_, iter_)); +} + +} +} diff --git a/UnityCore/ResultIterator.h b/UnityCore/ResultIterator.h new file mode 100644 index 000000000..a68aafb8f --- /dev/null +++ b/UnityCore/ResultIterator.h @@ -0,0 +1,103 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2012 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Gordon Allott <gord.allott@canonical.com> + */ +#ifndef UNITY_RESULT_ITERATOR_H +#define UNITY_RESULT_ITERATOR_H + +#include <dee.h> +#include <iterator> +#include "Result.h" +#include "GLibWrapper.h" + +namespace unity +{ +namespace dash +{ + +// Provides an iterator that will iterate a DeeModel from a Results object +// based on the category you give it + +class ResultIterator : public std::iterator<std::random_access_iterator_tag, Result> +{ +public: + ResultIterator(glib::Object<DeeModel> model); + ResultIterator(glib::Object<DeeModel> model, DeeModelIter* iter_, DeeModelTag* tag); + ResultIterator(ResultIterator const& copy) : model_(copy.model_), iter_(copy.iter_), tag_(copy.tag_), iter_result_(copy.iter_result_), cache_invalidated_(false){}; + + ResultIterator& operator=(ResultIterator const& rhs); + + //Iterator methods + ResultIterator& operator++(); + ResultIterator operator++(int); + ResultIterator& operator+=(int value); + ResultIterator operator+(int value) const; + + ResultIterator& operator--(); + ResultIterator operator--(int); + ResultIterator& operator-=(int value); + ResultIterator operator-(int value) const; + + ResultIterator operator[](int value); + friend inline bool const operator<(const ResultIterator& lhs, const ResultIterator& rhs) + { + return (dee_model_get_position(lhs.model_, lhs.iter_) < dee_model_get_position(rhs.model_, rhs.iter_)); + } + + friend inline bool const operator>(const ResultIterator& lhs, const ResultIterator& rhs) + { + return (dee_model_get_position(lhs.model_, lhs.iter_) > dee_model_get_position(rhs.model_, rhs.iter_)); + } + + friend inline bool const operator<=(const ResultIterator& lhs, const ResultIterator& rhs) + { + return (dee_model_get_position(lhs.model_, lhs.iter_) <= dee_model_get_position(rhs.model_, rhs.iter_)); + } + + friend inline bool const operator>=(const ResultIterator& lhs, const ResultIterator& rhs) + { + return (dee_model_get_position(lhs.model_, lhs.iter_) >= dee_model_get_position(rhs.model_, rhs.iter_)); + } + + friend inline bool const operator==(const ResultIterator& lhs, const ResultIterator& rhs) + { + return (lhs.iter_ == rhs.iter_); + } + + friend inline bool operator!=(const ResultIterator& lhs, const ResultIterator& rhs) + { + return !(lhs == rhs); + } + Result const& operator*(); + + /* convenience methods */ + bool const IsLast(); + bool const IsFirst(); + +private: + glib::Object<DeeModel> model_; + DeeModelIter* iter_; + DeeModelTag* tag_; + Result iter_result_; + bool cache_invalidated_; +}; + +} + +} + +#endif diff --git a/UnityCore/Results.cpp b/UnityCore/Results.cpp index b38c8e77e..8d3d9a654 100644 --- a/UnityCore/Results.cpp +++ b/UnityCore/Results.cpp @@ -39,6 +39,16 @@ Results::Results(ModelType model_type) row_removed.connect(sigc::mem_fun(this, &Results::OnRowRemoved)); } +ResultIterator Results::begin() +{ + return ResultIterator(model(), dee_model_get_first_iter(model()), GetTag()); +} + +ResultIterator Results::end() +{ + return ResultIterator(model(), dee_model_get_last_iter(model()), GetTag()); +} + void Results::OnRowAdded(Result& result) { result_added.emit(result); diff --git a/UnityCore/Results.h b/UnityCore/Results.h index ca98b9b95..d9d8c6108 100644 --- a/UnityCore/Results.h +++ b/UnityCore/Results.h @@ -24,6 +24,7 @@ #include "Model.h" #include "Result.h" +#include "ResultIterator.h" namespace unity { @@ -38,6 +39,9 @@ public: Results(); Results(ModelType model_type); + ResultIterator begin(); + ResultIterator end(); + sigc::signal<void, Result const&> result_added; sigc::signal<void, Result const&> result_changed; sigc::signal<void, Result const&> result_removed; diff --git a/tests/test_results.cpp b/tests/test_results.cpp index 730430333..e4b4d5165 100644 --- a/tests/test_results.cpp +++ b/tests/test_results.cpp @@ -3,11 +3,13 @@ #include <UnityCore/GLibWrapper.h> #include <UnityCore/Results.h> +#include <UnityCore/ResultIterator.h> #include "test_utils.h" using namespace std; using namespace unity::dash; +using namespace unity; namespace { @@ -35,27 +37,97 @@ TEST(TestResults, TestSynchronization) EXPECT_EQ(model.count, n_rows); } +TEST(TestResults, TestFilterValid) +{ + Results model; + DeeFilter filter; + + model.swarm_name = swarm_name; + WaitForSynchronize(model); + + dee_filter_new_for_any_column(2, g_variant_new_uint32(1), &filter); + glib::Object<DeeModel> filter_model(dee_filter_model_new(model.model(), &filter)); + + unsigned int i = 0; + for (ResultIterator iter(filter_model); !iter.IsLast(); ++iter) + { + EXPECT_EQ((*iter).category_index(), 1); + i++; + } + + EXPECT_EQ(i, 50); +} + TEST(TestResults, TestRowsValid) { Results model; model.swarm_name = swarm_name; WaitForSynchronize(model); + + ResultIterator iter(model.model); + unsigned int i = 0; + for (Result result : model) + { + //Result adaptor = *iter; + unity::glib::String tmp(g_strdup_printf("Result%d", i)); + string value = tmp.Str(); + EXPECT_EQ(result.uri(), value); + EXPECT_EQ(result.icon_hint(), value); + EXPECT_EQ(result.category_index(), (i / 50)); + EXPECT_EQ(result.mimetype(), value); + EXPECT_EQ(result.name(), value); + EXPECT_EQ(result.comment(), value); + EXPECT_EQ(result.dnd_uri(), value); + i++; + } - for (unsigned int i = 0; i < n_rows; i++) + //test reading a subset + i = 20; + for (auto iter = model.begin() + i; iter != model.end(); ++iter) { - Result adaptor = model.RowAtIndex(i); + Result result = (*iter); + unity::glib::String tmp(g_strdup_printf("Result%d", i)); + string value = tmp.Str(); + EXPECT_EQ(result.uri(), value); + i++; + } + // test post incrementor + i = 20; + for (auto iter = model.begin() + i; iter != model.end(); iter++) + { + Result result = (*iter); unity::glib::String tmp(g_strdup_printf("Result%d", i)); string value = tmp.Str(); - EXPECT_EQ(adaptor.uri, value); - EXPECT_EQ(adaptor.icon_hint, value); - EXPECT_EQ(adaptor.category_index, i); - EXPECT_EQ(adaptor.mimetype, value); - EXPECT_EQ(adaptor.name, value); - EXPECT_EQ(adaptor.comment, value); - EXPECT_EQ(adaptor.dnd_uri, value); + EXPECT_EQ(result.uri(), value); + i++; } + + // test equality + EXPECT_TRUE(model.begin() == model.begin()); + EXPECT_TRUE(model.begin() != model.end()); + + EXPECT_FALSE(model.begin().IsLast()); + EXPECT_FALSE(model.end().IsFirst()); + EXPECT_TRUE(model.begin().IsFirst()); + EXPECT_TRUE(model.end().IsLast()); + + EXPECT_TRUE(model.begin() < model.end()); + EXPECT_FALSE(model.end() < model.begin()); + EXPECT_TRUE(model.end() > model.begin()); + EXPECT_FALSE(model.begin() > model.end()); + EXPECT_TRUE(model.begin() <= model.end()); + EXPECT_FALSE(model.end() <= model.begin()); + EXPECT_TRUE(model.end() >= model.begin()); + EXPECT_FALSE(model.begin() >= model.end()); + + + EXPECT_TRUE(model.begin() + 20 > model.begin()); + EXPECT_TRUE(model.begin() + 20 > model.begin() + 19); + EXPECT_TRUE(model.end() - 20 < model.end()); + EXPECT_TRUE(model.end() - 20 < model.end() - 19); + } // We're testing the model's ability to store and retrieve random pointers diff --git a/tests/test_service_model.c b/tests/test_service_model.c index 8acdda48f..95f07f615 100644 --- a/tests/test_service_model.c +++ b/tests/test_service_model.c @@ -58,7 +58,7 @@ service_model_create_results(ServiceModel* self) dee_model_append(self->results_model_, name, name, - (guint)i, + (guint)(i/50), // new category every 50 results name, name, name, |
