Merge lp:unity-scopes-api/staging into lp:unity-scopes-api

Proposed by Michal Hruby
Status: Merged
Merged at revision: 205
Proposed branch: lp:unity-scopes-api/staging
Merge into: lp:unity-scopes-api
Diff against target: 3746 lines (+2416/-313)
73 files modified
CMakeLists.txt (+1/-1)
CONFIGFILES (+1/-1)
RELEASE_NOTES.md (+6/-0)
debian/changelog (+9/-0)
debian/libunity-scopes1.symbols (+38/-4)
demo/client.cpp (+5/-4)
demo/scopes/scope-A/scope-A.cpp (+1/-1)
doc/tutorial.dox (+44/-19)
include/unity/scopes/OptionSelectorFilter.h (+8/-1)
include/unity/scopes/RadioButtonsFilter.h (+124/-0)
include/unity/scopes/RangeInputFilter.h (+1/-1)
include/unity/scopes/RatingFilter.h (+180/-0)
include/unity/scopes/internal/FilterBaseImpl.h (+1/-0)
include/unity/scopes/internal/MWPublisher.h (+55/-0)
include/unity/scopes/internal/MWSubscriber.h (+57/-0)
include/unity/scopes/internal/MiddlewareBase.h (+5/-0)
include/unity/scopes/internal/OptionSelectorFilterImpl.h (+3/-1)
include/unity/scopes/internal/RadioButtonsFilterImpl.h (+50/-0)
include/unity/scopes/internal/RatingFilterImpl.h (+64/-0)
include/unity/scopes/internal/smartscopes/SmartScopesClient.h (+1/-0)
include/unity/scopes/internal/zmq_middleware/ObjectAdapter.h (+0/-2)
include/unity/scopes/internal/zmq_middleware/Util.h (+4/-0)
include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h (+4/-1)
include/unity/scopes/internal/zmq_middleware/ZmqPublisher.h (+83/-0)
include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h (+86/-0)
scoperegistry/CMakeLists.txt (+0/-1)
scoperegistry/FindFiles.cpp (+17/-6)
scoperegistry/FindFiles.h (+7/-3)
scoperegistry/ScopeSet.cpp (+0/-124)
scoperegistry/ScopeSet.h (+0/-56)
scoperegistry/scoperegistry.cpp (+3/-4)
scoperunner/scoperunner.cpp (+31/-1)
src/scopes/CMakeLists.txt (+2/-0)
src/scopes/OptionSelectorFilter.cpp (+7/-2)
src/scopes/RadioButtonsFilter.cpp (+80/-0)
src/scopes/RatingFilter.cpp (+105/-0)
src/scopes/internal/CMakeLists.txt (+4/-0)
src/scopes/internal/FilterBaseImpl.cpp (+60/-0)
src/scopes/internal/MWPublisher.cpp (+42/-0)
src/scopes/internal/MWSubscriber.cpp (+42/-0)
src/scopes/internal/OptionSelectorFilterImpl.cpp (+32/-0)
src/scopes/internal/RadioButtonsFilterImpl.cpp (+81/-0)
src/scopes/internal/RatingFilterImpl.cpp (+109/-0)
src/scopes/internal/SearchReplyImpl.cpp (+11/-1)
src/scopes/internal/smartscopes/SSRegistryObject.cpp (+5/-0)
src/scopes/internal/smartscopes/SmartScopesClient.cpp (+5/-0)
src/scopes/internal/zmq_middleware/CMakeLists.txt (+2/-0)
src/scopes/internal/zmq_middleware/ObjectAdapter.cpp (+0/-41)
src/scopes/internal/zmq_middleware/Util.cpp (+42/-0)
src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp (+17/-4)
src/scopes/internal/zmq_middleware/ZmqPublisher.cpp (+157/-0)
src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp (+185/-0)
test/gtest/scopes/CMakeLists.txt (+2/-0)
test/gtest/scopes/Filters/Filters_test.cpp (+72/-0)
test/gtest/scopes/Filters/TestScope.h (+1/-1)
test/gtest/scopes/IdleShutdown/IdleShutdown_test.cpp (+12/-6)
test/gtest/scopes/IdleShutdown/SlowSearchScope.cpp (+1/-1)
test/gtest/scopes/IdleShutdown/Zmq.ini.in (+5/-1)
test/gtest/scopes/OptionSelectorFilter/OptionSelectorFilter_test.cpp (+3/-0)
test/gtest/scopes/RadioButtonsFilter/CMakeLists.txt (+4/-0)
test/gtest/scopes/RadioButtonsFilter/RadioButtonsFilter_test.cpp (+71/-0)
test/gtest/scopes/RatingFilter/CMakeLists.txt (+4/-0)
test/gtest/scopes/RatingFilter/RatingFilter_test.cpp (+111/-0)
test/gtest/scopes/Registry/Registry_test.cpp (+0/-19)
test/gtest/scopes/Registry/Zmq.ini.in (+1/-0)
test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py (+1/-1)
test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp (+2/-0)
test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt (+1/-0)
test/gtest/scopes/internal/zmq_middleware/ObjectAdapter/ObjectAdapter_test.cpp (+2/-4)
test/gtest/scopes/internal/zmq_middleware/PubSub/CMakeLists.txt (+6/-0)
test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp (+237/-0)
test/gtest/scopes/internal/zmq_middleware/PubSub/Zmq.ini.in (+2/-0)
test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp (+1/-1)
To merge this branch: bzr merge lp:unity-scopes-api/staging
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Unity Team Pending
Review via email: mp+220461@code.launchpad.net

Commit message

Sync with devel.

Description of the change

Sync with devel.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:unity-scopes-api/staging updated
205. By Tarmac

Sync with devel.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-05-15 08:17:57 +0000
+++ CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -179,7 +179,7 @@
179# API version179# API version
180set(UNITY_SCOPES_MAJOR 0)180set(UNITY_SCOPES_MAJOR 0)
181set(UNITY_SCOPES_MINOR 4)181set(UNITY_SCOPES_MINOR 4)
182set(UNITY_SCOPES_MICRO 6)182set(UNITY_SCOPES_MICRO 7)
183183
184# Version for testing, with all symbols visible184# Version for testing, with all symbols visible
185set(UNITY_SCOPES_TEST_LIB ${UNITY_SCOPES_LIB}-test)185set(UNITY_SCOPES_TEST_LIB ${UNITY_SCOPES_LIB}-test)
186186
=== modified file 'CONFIGFILES'
--- CONFIGFILES 2014-05-15 07:33:37 +0000
+++ CONFIGFILES 2014-05-21 14:02:43 +0000
@@ -279,7 +279,7 @@
279279
280 If set, the results for this scope will be set to expire, and be refreshed. Valid values are:280 If set, the results for this scope will be set to expire, and be refreshed. Valid values are:
281281
282 - none282 - None
283283
284 - Small - in the order of a minute284 - Small - in the order of a minute
285285
286286
=== modified file 'RELEASE_NOTES.md'
--- RELEASE_NOTES.md 2014-05-15 10:34:30 +0000
+++ RELEASE_NOTES.md 2014-05-21 14:02:43 +0000
@@ -1,6 +1,12 @@
1Release notes1Release notes
2=============2=============
33
4Changes in version 0.4.7
5========================
6 - Implemented RatingFilter and RadioButtonsFilter.
7 - changed create() methods of OptionSelectorFilter and RangeInputFilter to return unique_ptr (UPtr)
8 instead of shared pointers.
9
4Changes in version 0.4.610Changes in version 0.4.6
5========================11========================
6 - Added method to get and set display hints for filters (at this moment the only display hint12 - Added method to get and set display hints for filters (at this moment the only display hint
713
=== modified file 'debian/changelog'
--- debian/changelog 2014-05-19 10:10:28 +0000
+++ debian/changelog 2014-05-21 14:02:43 +0000
@@ -1,3 +1,12 @@
1unity-scopes-api (0.4.7-0ubuntu1) UNRELEASED; urgency=medium
2
3 [ Pawel Stolowski ]
4 * Implemented RatingFilter and RadioButtonFilter.
5 * Fixed lp:1319712: Appearance attributes not supported for remote scopes.
6 * Changed create() methods of OptionSelectorFilter and RangeInputFilter to return unique ptr.
7
8 -- Pawel Stolowski <pawel.stolowski@ubuntu.com> Fri, 16 May 2014 17:48:23 +0200
9
1unity-scopes-api (0.4.6+14.10.20140519-0ubuntu1) utopic; urgency=medium10unity-scopes-api (0.4.6+14.10.20140519-0ubuntu1) utopic; urgency=medium
211
3 [ Pete Woods ]12 [ Pete Woods ]
413
=== modified file 'debian/libunity-scopes1.symbols'
--- debian/libunity-scopes1.symbols 2014-05-19 10:10:27 +0000
+++ debian/libunity-scopes1.symbols 2014-05-21 14:02:43 +0000
@@ -82,6 +82,14 @@
82 (c++)"unity::scopes::ListenerBase::~ListenerBase()@Base" 0.4.0+14.04.20140312.182 (c++)"unity::scopes::ListenerBase::~ListenerBase()@Base" 0.4.0+14.04.20140312.1
83 (c++)"unity::scopes::PreviewReply::PreviewReply()@Base" 0.4.0+14.04.20140312.183 (c++)"unity::scopes::PreviewReply::PreviewReply()@Base" 0.4.0+14.04.20140312.1
84 (c++)"unity::scopes::PreviewReply::~PreviewReply()@Base" 0.4.0+14.04.20140312.184 (c++)"unity::scopes::PreviewReply::~PreviewReply()@Base" 0.4.0+14.04.20140312.1
85 (c++)"unity::scopes::RatingFilter::add_option(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
86 (c++)"unity::scopes::RatingFilter::set_on_icon(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
87 (c++)"unity::scopes::RatingFilter::set_off_icon(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
88 (c++)"unity::scopes::RatingFilter::update_state(unity::scopes::FilterState&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)@Base" 0replaceme
89 (c++)"unity::scopes::RatingFilter::create(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
90 (c++)"unity::scopes::RatingFilter::create(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@Base" 0replaceme
91 (c++)"unity::scopes::RatingFilter::RatingFilter(unity::scopes::internal::RatingFilterImpl*)@Base" 0replaceme
92 (c++)"unity::scopes::RatingFilter::~RatingFilter()@Base" 0replaceme
85 (c++)"unity::scopes::PreviewWidget::add_attribute_value(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unity::scopes::Variant const&)@Base" 0.4.0+14.04.20140312.193 (c++)"unity::scopes::PreviewWidget::add_attribute_value(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unity::scopes::Variant const&)@Base" 0.4.0+14.04.20140312.1
86 (c++)"unity::scopes::PreviewWidget::add_attribute_mapping(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.194 (c++)"unity::scopes::PreviewWidget::add_attribute_mapping(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
87 (c++)"unity::scopes::PreviewWidget::PreviewWidget(unity::scopes::PreviewWidget&&)@Base" 0.4.0+14.04.20140312.195 (c++)"unity::scopes::PreviewWidget::PreviewWidget(unity::scopes::PreviewWidget&&)@Base" 0.4.0+14.04.20140312.1
@@ -216,6 +224,11 @@
216 (c++)"unity::scopes::ActivationResponse::~ActivationResponse()@Base" 0.4.0+14.04.20140312.1224 (c++)"unity::scopes::ActivationResponse::~ActivationResponse()@Base" 0.4.0+14.04.20140312.1
217 (c++)"unity::scopes::ActivationResponse::operator=(unity::scopes::ActivationResponse&&)@Base" 0.4.0+14.04.20140312.1225 (c++)"unity::scopes::ActivationResponse::operator=(unity::scopes::ActivationResponse&&)@Base" 0.4.0+14.04.20140312.1
218 (c++)"unity::scopes::ActivationResponse::operator=(unity::scopes::ActivationResponse const&)@Base" 0.4.0+14.04.20140312.1226 (c++)"unity::scopes::ActivationResponse::operator=(unity::scopes::ActivationResponse const&)@Base" 0.4.0+14.04.20140312.1
227 (c++)"unity::scopes::RadioButtonsFilter::add_option(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
228 (c++)"unity::scopes::RadioButtonsFilter::update_state(unity::scopes::FilterState&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)@Base" 0replaceme
229 (c++)"unity::scopes::RadioButtonsFilter::create(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
230 (c++)"unity::scopes::RadioButtonsFilter::RadioButtonsFilter(unity::scopes::internal::RadioButtonsFilterImpl*)@Base" 0replaceme
231 (c++)"unity::scopes::RadioButtonsFilter::~RadioButtonsFilter()@Base" 0replaceme
219 (c++)"unity::scopes::SearchListenerBase::push(unity::scopes::Annotation)@Base" 0.4.0+14.04.20140312.1232 (c++)"unity::scopes::SearchListenerBase::push(unity::scopes::Annotation)@Base" 0.4.0+14.04.20140312.1
220 (c++)"unity::scopes::SearchListenerBase::push(std::list<unity::scopes::Department, std::allocator<unity::scopes::Department> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1233 (c++)"unity::scopes::SearchListenerBase::push(std::list<unity::scopes::Department, std::allocator<unity::scopes::Department> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
221 (c++)"unity::scopes::SearchListenerBase::push(std::list<std::shared_ptr<unity::scopes::FilterBase const>, std::allocator<std::shared_ptr<unity::scopes::FilterBase const> > > const&, unity::scopes::FilterState const&)@Base" 0.4.0+14.04.20140312.1234 (c++)"unity::scopes::SearchListenerBase::push(std::list<std::shared_ptr<unity::scopes::FilterBase const>, std::allocator<std::shared_ptr<unity::scopes::FilterBase const> > > const&, unity::scopes::FilterState const&)@Base" 0.4.0+14.04.20140312.1
@@ -447,13 +460,12 @@
447 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_search_hint(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1460 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_search_hint(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
448 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_display_name(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1461 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_display_name(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
449 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_scope_directory(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.2+14.04.20140404.2462 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_scope_directory(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.2+14.04.20140404.2
463 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_results_ttl_type(unity::scopes::ScopeMetadata::ResultsTtlType)@Base" 0.4.6+14.10.20140519
450 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_appearance_attributes(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unity::scopes::Variant, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unity::scopes::Variant> > > const&)@Base" 0.4.2+14.04.20140404.2464 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_appearance_attributes(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unity::scopes::Variant, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unity::scopes::Variant> > > const&)@Base" 0.4.2+14.04.20140404.2
451 (c++)"unity::scopes::internal::ScopeMetadataImpl::create(std::unique_ptr<unity::scopes::internal::ScopeMetadataImpl, std::default_delete<unity::scopes::internal::ScopeMetadataImpl> >)@Base" 0.4.0+14.04.20140312.1465 (c++)"unity::scopes::internal::ScopeMetadataImpl::create(std::unique_ptr<unity::scopes::internal::ScopeMetadataImpl, std::default_delete<unity::scopes::internal::ScopeMetadataImpl> >)@Base" 0.4.0+14.04.20140312.1
452 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_art(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1466 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_art(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
453 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_icon(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1467 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_icon(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
454 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_proxy(std::shared_ptr<unity::scopes::Scope> const&)@Base" 0.4.0+14.04.20140312.1468 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_proxy(std::shared_ptr<unity::scopes::Scope> const&)@Base" 0.4.0+14.04.20140312.1
455 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_results_ttl_type(unity::scopes::ScopeMetadata::ResultsTtlType)@Base" 0.4.6+14.10.20140519
456 (c++)"unity::scopes::internal::ScopeMetadataImpl::results_ttl_type() const@Base" 0.4.6+14.10.20140519
457 (c++)"unity::scopes::internal::ScopeMetadataImpl::ScopeMetadataImpl(unity::scopes::internal::MiddlewareBase*)@Base" 0.4.0+14.04.20140312.1469 (c++)"unity::scopes::internal::ScopeMetadataImpl::ScopeMetadataImpl(unity::scopes::internal::MiddlewareBase*)@Base" 0.4.0+14.04.20140312.1
458 (c++)"unity::scopes::internal::ScopeMetadataImpl::ScopeMetadataImpl(unity::scopes::internal::ScopeMetadataImpl const&)@Base" 0.4.0+14.04.20140312.1470 (c++)"unity::scopes::internal::ScopeMetadataImpl::ScopeMetadataImpl(unity::scopes::internal::ScopeMetadataImpl const&)@Base" 0.4.0+14.04.20140312.1
459 (c++)"unity::scopes::internal::ScopeMetadataImpl::ScopeMetadataImpl(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unity::scopes::Variant, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unity::scopes::Variant> > > const&, unity::scopes::internal::MiddlewareBase*)@Base" 0.4.0+14.04.20140312.1471 (c++)"unity::scopes::internal::ScopeMetadataImpl::ScopeMetadataImpl(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unity::scopes::Variant, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unity::scopes::Variant> > > const&, unity::scopes::internal::MiddlewareBase*)@Base" 0.4.0+14.04.20140312.1
@@ -522,6 +534,14 @@
522 (c++)"unity::scopes::ColumnLayout::serialize() const@Base" 0.4.0+14.04.20140312.1534 (c++)"unity::scopes::ColumnLayout::serialize() const@Base" 0.4.0+14.04.20140312.1
523 (c++)"unity::scopes::FilterOption::id() const@Base" 0.4.0+14.04.20140312.1535 (c++)"unity::scopes::FilterOption::id() const@Base" 0.4.0+14.04.20140312.1
524 (c++)"unity::scopes::FilterOption::label() const@Base" 0.4.0+14.04.20140312.1536 (c++)"unity::scopes::FilterOption::label() const@Base" 0.4.0+14.04.20140312.1
537 (c++)"unity::scopes::RatingFilter::update_state(unity::scopes::FilterState&, std::shared_ptr<unity::scopes::FilterOption const>, bool) const@Base" 0replaceme
538 (c++)"unity::scopes::RatingFilter::active_rating(unity::scopes::FilterState const&) const@Base" 0replaceme
539 (c++)"unity::scopes::RatingFilter::has_active_rating(unity::scopes::FilterState const&) const@Base" 0replaceme
540 (c++)"unity::scopes::RatingFilter::fwd() const@Base" 0replaceme
541 (c++)"unity::scopes::RatingFilter::label() const@Base" 0replaceme
542 (c++)"unity::scopes::RatingFilter::on_icon() const@Base" 0replaceme
543 (c++)"unity::scopes::RatingFilter::options() const@Base" 0replaceme
544 (c++)"unity::scopes::RatingFilter::off_icon() const@Base" 0replaceme
525 (c++)"unity::scopes::PreviewWidget::widget_type() const@Base" 0.4.0+14.04.20140312.1545 (c++)"unity::scopes::PreviewWidget::widget_type() const@Base" 0.4.0+14.04.20140312.1
526 (c++)"unity::scopes::PreviewWidget::attribute_values() const@Base" 0.4.0+14.04.20140312.1546 (c++)"unity::scopes::PreviewWidget::attribute_values() const@Base" 0.4.0+14.04.20140312.1
527 (c++)"unity::scopes::PreviewWidget::attribute_mappings() const@Base" 0.4.0+14.04.20140312.1547 (c++)"unity::scopes::PreviewWidget::attribute_mappings() const@Base" 0.4.0+14.04.20140312.1
@@ -532,6 +552,7 @@
532 (c++)"unity::scopes::ScopeMetadata::search_hint() const@Base" 0.4.0+14.04.20140312.1552 (c++)"unity::scopes::ScopeMetadata::search_hint() const@Base" 0.4.0+14.04.20140312.1
533 (c++)"unity::scopes::ScopeMetadata::display_name() const@Base" 0.4.0+14.04.20140312.1553 (c++)"unity::scopes::ScopeMetadata::display_name() const@Base" 0.4.0+14.04.20140312.1
534 (c++)"unity::scopes::ScopeMetadata::scope_directory() const@Base" 0.4.2+14.04.20140404.2554 (c++)"unity::scopes::ScopeMetadata::scope_directory() const@Base" 0.4.2+14.04.20140404.2
555 (c++)"unity::scopes::ScopeMetadata::results_ttl_type() const@Base" 0.4.6+14.10.20140519
535 (c++)"unity::scopes::ScopeMetadata::appearance_attributes() const@Base" 0.4.2+14.04.20140404.2556 (c++)"unity::scopes::ScopeMetadata::appearance_attributes() const@Base" 0.4.2+14.04.20140404.2
536 (c++)"unity::scopes::ScopeMetadata::art() const@Base" 0.4.0+14.04.20140312.1557 (c++)"unity::scopes::ScopeMetadata::art() const@Base" 0.4.0+14.04.20140312.1
537 (c++)"unity::scopes::ScopeMetadata::icon() const@Base" 0.4.0+14.04.20140312.1558 (c++)"unity::scopes::ScopeMetadata::icon() const@Base" 0.4.0+14.04.20140312.1
@@ -541,7 +562,6 @@
541 (c++)"unity::scopes::ScopeMetadata::scope_id() const@Base" 0.4.0+14.04.20140312.1562 (c++)"unity::scopes::ScopeMetadata::scope_id() const@Base" 0.4.0+14.04.20140312.1
542 (c++)"unity::scopes::ScopeMetadata::invisible() const@Base" 0.4.0+14.04.20140312.1563 (c++)"unity::scopes::ScopeMetadata::invisible() const@Base" 0.4.0+14.04.20140312.1
543 (c++)"unity::scopes::ScopeMetadata::serialize() const@Base" 0.4.0+14.04.20140312.1564 (c++)"unity::scopes::ScopeMetadata::serialize() const@Base" 0.4.0+14.04.20140312.1
544 (c++)"unity::scopes::ScopeMetadata::results_ttl_type() const@Base" 0.4.6+14.10.20140519
545 (c++)"unity::scopes::ActionMetadata::scope_data() const@Base" 0.4.0+14.04.20140312.1565 (c++)"unity::scopes::ActionMetadata::scope_data() const@Base" 0.4.0+14.04.20140312.1
546 (c++)"unity::scopes::ActionMetadata::form_factor() const@Base" 0.4.0+14.04.20140312.1566 (c++)"unity::scopes::ActionMetadata::form_factor() const@Base" 0.4.0+14.04.20140312.1
547 (c++)"unity::scopes::ActionMetadata::locale() const@Base" 0.4.0+14.04.20140312.1567 (c++)"unity::scopes::ActionMetadata::locale() const@Base" 0.4.0+14.04.20140312.1
@@ -573,10 +593,17 @@
573 (c++)"unity::scopes::ActivationResponse::query() const@Base" 0.4.0+14.04.20140312.1593 (c++)"unity::scopes::ActivationResponse::query() const@Base" 0.4.0+14.04.20140312.1
574 (c++)"unity::scopes::ActivationResponse::status() const@Base" 0.4.0+14.04.20140312.1594 (c++)"unity::scopes::ActivationResponse::status() const@Base" 0.4.0+14.04.20140312.1
575 (c++)"unity::scopes::ActivationResponse::serialize() const@Base" 0.4.0+14.04.20140312.1595 (c++)"unity::scopes::ActivationResponse::serialize() const@Base" 0.4.0+14.04.20140312.1
596 (c++)"unity::scopes::RadioButtonsFilter::update_state(unity::scopes::FilterState&, std::shared_ptr<unity::scopes::FilterOption const>, bool) const@Base" 0replaceme
597 (c++)"unity::scopes::RadioButtonsFilter::active_option(unity::scopes::FilterState const&) const@Base" 0replaceme
598 (c++)"unity::scopes::RadioButtonsFilter::has_active_option(unity::scopes::FilterState const&) const@Base" 0replaceme
599 (c++)"unity::scopes::RadioButtonsFilter::fwd() const@Base" 0replaceme
600 (c++)"unity::scopes::RadioButtonsFilter::label() const@Base" 0replaceme
601 (c++)"unity::scopes::RadioButtonsFilter::options() const@Base" 0replaceme
576 (c++)"unity::scopes::MiddlewareException::self() const@Base" 0.4.0+14.04.20140312.1602 (c++)"unity::scopes::MiddlewareException::self() const@Base" 0.4.0+14.04.20140312.1
577 (c++)"unity::scopes::OptionSelectorFilter::multi_select() const@Base" 0.4.0+14.04.20140312.1603 (c++)"unity::scopes::OptionSelectorFilter::multi_select() const@Base" 0.4.0+14.04.20140312.1
578 (c++)"unity::scopes::OptionSelectorFilter::update_state(unity::scopes::FilterState&, std::shared_ptr<unity::scopes::FilterOption const>, bool) const@Base" 0.4.0+14.04.20140312.1604 (c++)"unity::scopes::OptionSelectorFilter::update_state(unity::scopes::FilterState&, std::shared_ptr<unity::scopes::FilterOption const>, bool) const@Base" 0.4.0+14.04.20140312.1
579 (c++)"unity::scopes::OptionSelectorFilter::active_options(unity::scopes::FilterState const&) const@Base" 0.4.0+14.04.20140312.1605 (c++)"unity::scopes::OptionSelectorFilter::active_options(unity::scopes::FilterState const&) const@Base" 0.4.0+14.04.20140312.1
606 (c++)"unity::scopes::OptionSelectorFilter::has_active_option(unity::scopes::FilterState const&) const@Base" 0replaceme
580 (c++)"unity::scopes::OptionSelectorFilter::fwd() const@Base" 0.4.0+14.04.20140312.1607 (c++)"unity::scopes::OptionSelectorFilter::fwd() const@Base" 0.4.0+14.04.20140312.1
581 (c++)"unity::scopes::OptionSelectorFilter::label() const@Base" 0.4.0+14.04.20140312.1608 (c++)"unity::scopes::OptionSelectorFilter::label() const@Base" 0.4.0+14.04.20140312.1
582 (c++)"unity::scopes::OptionSelectorFilter::options() const@Base" 0.4.0+14.04.20140312.1609 (c++)"unity::scopes::OptionSelectorFilter::options() const@Base" 0.4.0+14.04.20140312.1
@@ -644,13 +671,13 @@
644 (c++)"unity::scopes::internal::ScopeConfig::idle_timeout() const@Base" 0.4.5+14.10.20140513671 (c++)"unity::scopes::internal::ScopeConfig::idle_timeout() const@Base" 0.4.5+14.10.20140513
645 (c++)"unity::scopes::internal::ScopeConfig::overrideable() const@Base" 0.4.0+14.04.20140312.1672 (c++)"unity::scopes::internal::ScopeConfig::overrideable() const@Base" 0.4.0+14.04.20140312.1
646 (c++)"unity::scopes::internal::ScopeConfig::scope_runner() const@Base" 0.4.2+14.04.20140404.2673 (c++)"unity::scopes::internal::ScopeConfig::scope_runner() const@Base" 0.4.2+14.04.20140404.2
674 (c++)"unity::scopes::internal::ScopeConfig::results_ttl_type() const@Base" 0.4.6+14.10.20140519
647 (c++)"unity::scopes::internal::ScopeConfig::appearance_attributes() const@Base" 0.4.2+14.04.20140404.2675 (c++)"unity::scopes::internal::ScopeConfig::appearance_attributes() const@Base" 0.4.2+14.04.20140404.2
648 (c++)"unity::scopes::internal::ScopeConfig::art() const@Base" 0.4.0+14.04.20140312.1676 (c++)"unity::scopes::internal::ScopeConfig::art() const@Base" 0.4.0+14.04.20140312.1
649 (c++)"unity::scopes::internal::ScopeConfig::icon() const@Base" 0.4.0+14.04.20140312.1677 (c++)"unity::scopes::internal::ScopeConfig::icon() const@Base" 0.4.0+14.04.20140312.1
650 (c++)"unity::scopes::internal::ScopeConfig::author() const@Base" 0.4.0+14.04.20140312.1678 (c++)"unity::scopes::internal::ScopeConfig::author() const@Base" 0.4.0+14.04.20140312.1
651 (c++)"unity::scopes::internal::ScopeConfig::hot_key() const@Base" 0.4.0+14.04.20140312.1679 (c++)"unity::scopes::internal::ScopeConfig::hot_key() const@Base" 0.4.0+14.04.20140312.1
652 (c++)"unity::scopes::internal::ScopeConfig::invisible() const@Base" 0.4.0+14.04.20140312.1680 (c++)"unity::scopes::internal::ScopeConfig::invisible() const@Base" 0.4.0+14.04.20140312.1
653 (c++)"unity::scopes::internal::ScopeConfig::results_ttl_type() const@Base" 0.4.6+14.10.20140519
654 (c++)"unity::scopes::internal::ScopeLoader::scope_base() const@Base" 0.4.0+14.04.20140312.1681 (c++)"unity::scopes::internal::ScopeLoader::scope_base() const@Base" 0.4.0+14.04.20140312.1
655 (c++)"unity::scopes::internal::ScopeLoader::libpath() const@Base" 0.4.0+14.04.20140312.1682 (c++)"unity::scopes::internal::ScopeLoader::libpath() const@Base" 0.4.0+14.04.20140312.1
656 (c++)"unity::scopes::internal::ScopeLoader::scope_id() const@Base" 0.4.2+14.04.20140404.2683 (c++)"unity::scopes::internal::ScopeLoader::scope_id() const@Base" 0.4.2+14.04.20140404.2
@@ -693,6 +720,7 @@
693 (c++)"unity::scopes::internal::ScopeMetadataImpl::search_hint() const@Base" 0.4.0+14.04.20140312.1720 (c++)"unity::scopes::internal::ScopeMetadataImpl::search_hint() const@Base" 0.4.0+14.04.20140312.1
694 (c++)"unity::scopes::internal::ScopeMetadataImpl::display_name() const@Base" 0.4.0+14.04.20140312.1721 (c++)"unity::scopes::internal::ScopeMetadataImpl::display_name() const@Base" 0.4.0+14.04.20140312.1
695 (c++)"unity::scopes::internal::ScopeMetadataImpl::scope_directory() const@Base" 0.4.2+14.04.20140404.2722 (c++)"unity::scopes::internal::ScopeMetadataImpl::scope_directory() const@Base" 0.4.2+14.04.20140404.2
723 (c++)"unity::scopes::internal::ScopeMetadataImpl::results_ttl_type() const@Base" 0.4.6+14.10.20140519
696 (c++)"unity::scopes::internal::ScopeMetadataImpl::appearance_attributes() const@Base" 0.4.2+14.04.20140404.2724 (c++)"unity::scopes::internal::ScopeMetadataImpl::appearance_attributes() const@Base" 0.4.2+14.04.20140404.2
697 (c++)"unity::scopes::internal::ScopeMetadataImpl::art() const@Base" 0.4.0+14.04.20140312.1725 (c++)"unity::scopes::internal::ScopeMetadataImpl::art() const@Base" 0.4.0+14.04.20140312.1
698 (c++)"unity::scopes::internal::ScopeMetadataImpl::icon() const@Base" 0.4.0+14.04.20140312.1726 (c++)"unity::scopes::internal::ScopeMetadataImpl::icon() const@Base" 0.4.0+14.04.20140312.1
@@ -710,6 +738,7 @@
710 (c++)"typeinfo for unity::scopes::SearchReply@Base" 0.4.0+14.04.20140312.1738 (c++)"typeinfo for unity::scopes::SearchReply@Base" 0.4.0+14.04.20140312.1
711 (c++)"typeinfo for unity::scopes::ListenerBase@Base" 0.4.0+14.04.20140312.1739 (c++)"typeinfo for unity::scopes::ListenerBase@Base" 0.4.0+14.04.20140312.1
712 (c++)"typeinfo for unity::scopes::PreviewReply@Base" 0.4.0+14.04.20140312.1740 (c++)"typeinfo for unity::scopes::PreviewReply@Base" 0.4.0+14.04.20140312.1
741 (c++)"typeinfo for unity::scopes::RatingFilter@Base" 0replaceme
713 (c++)"typeinfo for unity::scopes::PreviewWidget@Base" 0.4.0+14.04.20140312.1742 (c++)"typeinfo for unity::scopes::PreviewWidget@Base" 0.4.0+14.04.20140312.1
714 (c++)"typeinfo for unity::scopes::VariantBuilder@Base" 0.4.0+14.04.20140312.1743 (c++)"typeinfo for unity::scopes::VariantBuilder@Base" 0.4.0+14.04.20140312.1
715 (c++)"typeinfo for unity::scopes::ConfigException@Base" 0.4.0+14.04.20140312.1744 (c++)"typeinfo for unity::scopes::ConfigException@Base" 0.4.0+14.04.20140312.1
@@ -720,6 +749,7 @@
720 (c++)"typeinfo for unity::scopes::TimeoutException@Base" 0.4.0+14.04.20140312.1749 (c++)"typeinfo for unity::scopes::TimeoutException@Base" 0.4.0+14.04.20140312.1
721 (c++)"typeinfo for unity::scopes::CategorisedResult@Base" 0.4.0+14.04.20140312.1750 (c++)"typeinfo for unity::scopes::CategorisedResult@Base" 0.4.0+14.04.20140312.1
722 (c++)"typeinfo for unity::scopes::NotFoundException@Base" 0.4.0+14.04.20140312.1751 (c++)"typeinfo for unity::scopes::NotFoundException@Base" 0.4.0+14.04.20140312.1
752 (c++)"typeinfo for unity::scopes::RadioButtonsFilter@Base" 0replaceme
723 (c++)"typeinfo for unity::scopes::SearchListenerBase@Base" 0.4.0+14.04.20140312.1753 (c++)"typeinfo for unity::scopes::SearchListenerBase@Base" 0.4.0+14.04.20140312.1
724 (c++)"typeinfo for unity::scopes::ActivationQueryBase@Base" 0.4.0+14.04.20140312.1754 (c++)"typeinfo for unity::scopes::ActivationQueryBase@Base" 0.4.0+14.04.20140312.1
725 (c++)"typeinfo for unity::scopes::MiddlewareException@Base" 0.4.0+14.04.20140312.1755 (c++)"typeinfo for unity::scopes::MiddlewareException@Base" 0.4.0+14.04.20140312.1
@@ -748,6 +778,7 @@
748 (c++)"typeinfo name for unity::scopes::SearchReply@Base" 0.4.0+14.04.20140312.1778 (c++)"typeinfo name for unity::scopes::SearchReply@Base" 0.4.0+14.04.20140312.1
749 (c++)"typeinfo name for unity::scopes::ListenerBase@Base" 0.4.0+14.04.20140312.1779 (c++)"typeinfo name for unity::scopes::ListenerBase@Base" 0.4.0+14.04.20140312.1
750 (c++)"typeinfo name for unity::scopes::PreviewReply@Base" 0.4.0+14.04.20140312.1780 (c++)"typeinfo name for unity::scopes::PreviewReply@Base" 0.4.0+14.04.20140312.1
781 (c++)"typeinfo name for unity::scopes::RatingFilter@Base" 0replaceme
751 (c++)"typeinfo name for unity::scopes::PreviewWidget@Base" 0.4.0+14.04.20140312.1782 (c++)"typeinfo name for unity::scopes::PreviewWidget@Base" 0.4.0+14.04.20140312.1
752 (c++)"typeinfo name for unity::scopes::VariantBuilder@Base" 0.4.0+14.04.20140312.1783 (c++)"typeinfo name for unity::scopes::VariantBuilder@Base" 0.4.0+14.04.20140312.1
753 (c++)"typeinfo name for unity::scopes::ConfigException@Base" 0.4.0+14.04.20140312.1784 (c++)"typeinfo name for unity::scopes::ConfigException@Base" 0.4.0+14.04.20140312.1
@@ -758,6 +789,7 @@
758 (c++)"typeinfo name for unity::scopes::TimeoutException@Base" 0.4.0+14.04.20140312.1789 (c++)"typeinfo name for unity::scopes::TimeoutException@Base" 0.4.0+14.04.20140312.1
759 (c++)"typeinfo name for unity::scopes::CategorisedResult@Base" 0.4.0+14.04.20140312.1790 (c++)"typeinfo name for unity::scopes::CategorisedResult@Base" 0.4.0+14.04.20140312.1
760 (c++)"typeinfo name for unity::scopes::NotFoundException@Base" 0.4.0+14.04.20140312.1791 (c++)"typeinfo name for unity::scopes::NotFoundException@Base" 0.4.0+14.04.20140312.1
792 (c++)"typeinfo name for unity::scopes::RadioButtonsFilter@Base" 0replaceme
761 (c++)"typeinfo name for unity::scopes::SearchListenerBase@Base" 0.4.0+14.04.20140312.1793 (c++)"typeinfo name for unity::scopes::SearchListenerBase@Base" 0.4.0+14.04.20140312.1
762 (c++)"typeinfo name for unity::scopes::ActivationQueryBase@Base" 0.4.0+14.04.20140312.1794 (c++)"typeinfo name for unity::scopes::ActivationQueryBase@Base" 0.4.0+14.04.20140312.1
763 (c++)"typeinfo name for unity::scopes::MiddlewareException@Base" 0.4.0+14.04.20140312.1795 (c++)"typeinfo name for unity::scopes::MiddlewareException@Base" 0.4.0+14.04.20140312.1
@@ -797,6 +829,7 @@
797 (c++)"vtable for unity::scopes::SearchReply@Base" 0.4.0+14.04.20140312.1829 (c++)"vtable for unity::scopes::SearchReply@Base" 0.4.0+14.04.20140312.1
798 (c++)"vtable for unity::scopes::ListenerBase@Base" 0.4.0+14.04.20140312.1830 (c++)"vtable for unity::scopes::ListenerBase@Base" 0.4.0+14.04.20140312.1
799 (c++)"vtable for unity::scopes::PreviewReply@Base" 0.4.0+14.04.20140312.1831 (c++)"vtable for unity::scopes::PreviewReply@Base" 0.4.0+14.04.20140312.1
832 (c++)"vtable for unity::scopes::RatingFilter@Base" 0replaceme
800 (c++)"vtable for unity::scopes::PreviewWidget@Base" 0.4.0+14.04.20140312.1833 (c++)"vtable for unity::scopes::PreviewWidget@Base" 0.4.0+14.04.20140312.1
801 (c++)"vtable for unity::scopes::VariantBuilder@Base" 0.4.0+14.04.20140312.1834 (c++)"vtable for unity::scopes::VariantBuilder@Base" 0.4.0+14.04.20140312.1
802 (c++)"vtable for unity::scopes::ConfigException@Base" 0.4.0+14.04.20140312.1835 (c++)"vtable for unity::scopes::ConfigException@Base" 0.4.0+14.04.20140312.1
@@ -807,6 +840,7 @@
807 (c++)"vtable for unity::scopes::TimeoutException@Base" 0.4.0+14.04.20140312.1840 (c++)"vtable for unity::scopes::TimeoutException@Base" 0.4.0+14.04.20140312.1
808 (c++)"vtable for unity::scopes::CategorisedResult@Base" 0.4.0+14.04.20140312.1841 (c++)"vtable for unity::scopes::CategorisedResult@Base" 0.4.0+14.04.20140312.1
809 (c++)"vtable for unity::scopes::NotFoundException@Base" 0.4.0+14.04.20140312.1842 (c++)"vtable for unity::scopes::NotFoundException@Base" 0.4.0+14.04.20140312.1
843 (c++)"vtable for unity::scopes::RadioButtonsFilter@Base" 0replaceme
810 (c++)"vtable for unity::scopes::SearchListenerBase@Base" 0.4.0+14.04.20140312.1844 (c++)"vtable for unity::scopes::SearchListenerBase@Base" 0.4.0+14.04.20140312.1
811 (c++)"vtable for unity::scopes::ActivationQueryBase@Base" 0.4.0+14.04.20140312.1845 (c++)"vtable for unity::scopes::ActivationQueryBase@Base" 0.4.0+14.04.20140312.1
812 (c++)"vtable for unity::scopes::MiddlewareException@Base" 0.4.0+14.04.20140312.1846 (c++)"vtable for unity::scopes::MiddlewareException@Base" 0.4.0+14.04.20140312.1
813847
=== modified file 'demo/client.cpp'
--- demo/client.cpp 2014-04-29 13:51:44 +0000
+++ demo/client.cpp 2014-05-21 14:02:43 +0000
@@ -422,10 +422,11 @@
422 }422 }
423423
424 auto meta = r->get_metadata(scope_id);424 auto meta = r->get_metadata(scope_id);
425 cout << "Scope metadata: " << endl;425 cout << "Scope metadata: " << endl;
426 cout << "\tscope_id: " << meta.scope_id() << endl;426 cout << "\tscope_id: " << meta.scope_id() << endl;
427 cout << "\tdisplay_name: " << meta.display_name() << endl;427 cout << "\tdisplay_name: " << meta.display_name() << endl;
428 cout << "\tdescription: " << meta.description() << endl;428 cout << "\tdescription: " << meta.description() << endl;
429 cout << "\tappearance attr: " << to_string(Variant(meta.appearance_attributes())) << endl;
429 string tmp;430 string tmp;
430 try431 try
431 {432 {
432433
=== modified file 'demo/scopes/scope-A/scope-A.cpp'
--- demo/scopes/scope-A/scope-A.cpp 2014-04-29 11:20:57 +0000
+++ demo/scopes/scope-A/scope-A.cpp 2014-05-21 14:02:43 +0000
@@ -59,7 +59,7 @@
59 reply->register_departments(departments);59 reply->register_departments(departments);
6060
61 Filters filters;61 Filters filters;
62 auto filter = OptionSelectorFilter::create("f1", "Options");62 OptionSelectorFilter::SPtr filter = OptionSelectorFilter::create("f1", "Options");
63 filter->add_option("1", "Option 1");63 filter->add_option("1", "Option 1");
64 filter->add_option("2", "Option 2");64 filter->add_option("2", "Option 2");
65 filters.push_back(filter);65 filters.push_back(filter);
6666
=== modified file 'doc/tutorial.dox'
--- doc/tutorial.dox 2014-05-08 10:47:45 +0000
+++ doc/tutorial.dox 2014-05-21 14:02:43 +0000
@@ -188,7 +188,7 @@
188and \link unity::scopes::SearchReply::push push\endlink.188and \link unity::scopes::SearchReply::push push\endlink.
189189
190The \link unity::scopes::SearchReply::register_category register_category\endlink method is a factory method for creating new categories (see190The \link unity::scopes::SearchReply::register_category register_category\endlink method is a factory method for creating new categories (see
191\link unity::scopes::Category\endlink). Categories can be created at any point during query processing inside run method, but it's recommended to create191\link unity::scopes::Category\endlink). Categories can be created at any point during query processing inside run method, but we recommend to create
192them as soon as possible (ideally as soon as they are known to the scope).192them as soon as possible (ideally as soon as they are known to the scope).
193193
194When creating a category, one of its parameters is a \link unity::scopes::CategoryRenderer \endlink instance,194When creating a category, one of its parameters is a \link unity::scopes::CategoryRenderer \endlink instance,
@@ -552,29 +552,39 @@
552restart scope-registry552restart scope-registry
553\endverbatim553\endverbatim
554554
555The scope will be installed under one of the "scopes directories"555Scopes are installed under one of the "scopes directories"
556scanned by the scope registry. Currently these default to:556scanned by the scope registry. Currently these default to:
557557
558<ul>558<ul>
559<li>/usr/lib/${arch}/unity-scopes</li>559<li>/usr/lib/${arch}/unity-scopes</li>
560<li>/custom/lib/${arch}/unity-scopes</li>560<li>/custom/lib/${arch}/unity-scopes</li>
561<!-- <li>??? Click packages?</li> -->561<li>$HOME/.local/share/unity-scopes</li>
562</ul>562</ul>
563563
564Individual scopes are installed into a subdirectory matching the564The `/usr/lib` directory is for scopes that are pre-installed by Canonical.
565scope's name. At a minimum, the directory structure should contain565The `/custom/lib` directory is for scopes that pre-installed by OEMs.
566the following:566The `$HOME/.local` directory is for scopes that are installed from click packages.
567
568Individual scopes are installed into subdirectories of these
569installation directories. The name of the subdirectory containing
570a scope's `.ini` and `.so` files can be anything but, to avoid name clashes,
571we strongly suggest something that is unique, such as `com.canonical.scopes.scopename`.
572At a minimum, the directory structure must contain the following:
567573
568 -+- ${scopesdir}574 -+- ${scopesdir}
569 `-+- scopename575 `-+- subdirectory
570 |--- scopename.ini576 |--- scopename.ini
571 `--- libscopename.so577 `--- <library>.so
572578
573That is, a scope metadata file and a shared library containing the579That is, each subdirectory must contain a scope `.ini` file and a shared library containing the
574scope code. The scope author is free to ship additional data in this580scope code. The scope author is free to ship additional data in this
575directory (e.g. icons and screenshots).581directory (e.g. icons and screenshots).
576582
577The scope metadata file uses the standard ini file format, with the583The name of the scope's `.ini` file _must_ be a unique ID for the scope. We _strongly_
584suggest to use a unique identifier, such as `com.canonical.scopes.scopename`, to avoid
585clashes with scopes created by other developers.
586
587The scope `.ini` file uses the standard `.ini` file format, with the
578following keys:588following keys:
579589
580 [ScopeConfig]590 [ScopeConfig]
@@ -585,8 +595,22 @@
585 Art = path to screenshot of the scope595 Art = path to screenshot of the scope
586 SearchHint = hint text displayed to user when viewing scope596 SearchHint = hint text displayed to user when viewing scope
587 HotKey =597 HotKey =
588598 ResultsTtlType = None, Small, Medium, or Large
589In addition to allowing the registry to make the scope available, this information controls how the scope appears in the "Scopes" scope.599
600 [Appearance]
601 TODO: document valid attributes
602
603The `ScopeConfig` group is mandatory and must contain settings for at least `DisplayName`, `Description`, and Author.
604`DisplayName` and `Description` can (and should) be localized. For example:
605
606`Description[de] = Fu&szlig;ballergebnisse`
607
608In addition to allowing the registry to make the scope available, this information controls how the scope appears
609in the "Scopes" scope.
610
611The name of of the scope's `.so` file can be `libscopename.so`, `scopename.so`, or simply `scope.so`. For example,
612for a scope named `Fred`, the names `libFred.so`, `Fred.so`, and `scope.so` are acceptable. (No other library
613names are valid.)
590614
591\subsection scopetool Previewing scope615\subsection scopetool Previewing scope
592616
@@ -599,16 +623,17 @@
599sudo apt-get install unity-scope-tool623sudo apt-get install unity-scope-tool
600\endverbatim624\endverbatim
601625
602After installation, you can run the scope-tool with a parameter specifying626After installation, you can run the scope-tool with a parameter specifying the
603path to your scope configuration file (for example `unity-scope-tool ~/dev/myscope/build/myscope.ini`). If a binary for your scope can be found in the same627path to your scope configuration file (for example `unity-scope-tool ~/dev/myscope/build/myscope.ini`).
604directory (ie there's `~/dev/myscope/build/libmyscope.so`), the scope-tool will628If a binary for your scope can be found in the same
629directory, the scope-tool will
605display surfacing and search results provided by your scope, and allow you to630display surfacing and search results provided by your scope, and allow you to
606perform searches, invoke previews and actions within previews.631perform searches, invoke previews and actions within previews.
607632
608Note that the scope-tool is using the same rendering mechanism as Unity633Note that the scope-tool uses the same rendering mechanism as Unity
609itself, and therefore what you see in the scope-tool is what you get in Unity.634itself and, therefore, what you see in the scope-tool is what you get in Unity.
610It can also be used to fine-tune the category definitions, as it allows you635It can also be used to fine-tune the category definitions, as it allows you
611to manipulate the definitions on the fly, and once you're happy with the result636to manipulate the definitions on the fly. Once you are happy with the result
612you can just copy the JSON definition back into your scope637you can just copy the JSON definition back into your scope
613(see unity::scopes::CategoryRenderer::CategoryRenderer()).638(see unity::scopes::CategoryRenderer::CategoryRenderer()).
614639
615640
=== modified file 'include/unity/scopes/OptionSelectorFilter.h'
--- include/unity/scopes/OptionSelectorFilter.h 2014-05-08 16:10:18 +0000
+++ include/unity/scopes/OptionSelectorFilter.h 2014-05-21 14:02:43 +0000
@@ -57,7 +57,7 @@
57 \param multi_select If true, the filter permits more than option to be selected; otherwise, only a single57 \param multi_select If true, the filter permits more than option to be selected; otherwise, only a single
58 option can be selected.58 option can be selected.
59 */59 */
60 static OptionSelectorFilter::SPtr create(std::string const& id, std::string const& label, bool multi_select = false);60 static OptionSelectorFilter::UPtr create(std::string const& id, std::string const& label, bool multi_select = false);
6161
62 /**62 /**
63 \brief Get the label of this filter.63 \brief Get the label of this filter.
@@ -84,6 +84,13 @@
84 std::list<FilterOption::SCPtr> options() const;84 std::list<FilterOption::SCPtr> options() const;
8585
86 /**86 /**
87 \brief Check if an option is active for this filter.
88 \param filter_state The state of filters
89 \return true if an option is active
90 */
91 bool has_active_option(FilterState const& filter_state) const;
92
93 /**
87 \brief Get active options from an instance of FilterState for this filter.94 \brief Get active options from an instance of FilterState for this filter.
88 \return The set of selected filter options.95 \return The set of selected filter options.
89 */96 */
9097
=== added file 'include/unity/scopes/RadioButtonsFilter.h'
--- include/unity/scopes/RadioButtonsFilter.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/RadioButtonsFilter.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,124 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17 */
18
19#ifndef UNITY_SCOPES_RADIOBUTTONSFILTER_H
20#define UNITY_SCOPES_RADIOBUTTONSFILTER_H
21
22#include <unity/scopes/FilterBase.h>
23#include <unity/scopes/FilterOption.h>
24
25namespace unity
26{
27
28namespace scopes
29{
30
31class FilterState;
32
33namespace internal
34{
35
36class RadioButtonsFilterImpl;
37
38}
39
40/**
41\brief A filter that displays mutually exclusive list of options.
42
43Displays filter with a set of options and allows only one option to be selected at a time.
44*/
45class UNITY_API RadioButtonsFilter : public FilterBase
46{
47public:
48/// @cond
49 UNITY_DEFINES_PTRS(RadioButtonsFilter);
50/// @endcond
51
52 /**
53 \brief Creates RadioButtonsFilter filter.
54
55 Creates an empty RadioButtonsFilter filter. Use unity::scopes::RadioButtonsFilter::add_option() to add options to it.
56 \param id A unique identifier for the filter that can be used to identify it later among several filters.
57 \param label A display label for this filter
58 \return Instance of RadioButtonsFilter
59 */
60 static RadioButtonsFilter::UPtr create(std::string const& id, std::string const& label);
61
62 /**
63 \brief Adds a new option to the filter.
64
65 \param id A unique identifier of the option.
66 \param label A display label for the option
67 \return Instance of FilterOption
68 */
69 FilterOption::SCPtr add_option(std::string const& id, std::string const& label);
70
71 /**
72 \brief Get the label of this filter.
73 \return The filter label.
74 */
75 std::string label() const;
76
77 /**
78 \brief Get active option from an instance of FilterState for this filter.
79 \return The active option or nullptr if no option is active.
80 */
81 FilterOption::SCPtr active_option(FilterState const& filter_state) const;
82
83 /**
84 \brief Check if active options.
85 \param filter_state The state of filters
86 \return true if there is at least one option active
87 */
88 bool has_active_option(FilterState const& filter_state) const;
89
90
91 /**
92 \brief Get all options of this filter, in the order they were added.
93 \return The list of options.
94 */
95 std::list<FilterOption::SCPtr> options() const;
96
97 /**
98 \brief Marks given FilterOption of this filter instance as active (or not active) in a FilterState object.
99
100 Records the given FilterOption as "selected" in the FilterState. This is meant to be used to modify a
101 FilterState received with a search request before sending it back to the client (UI shell).
102 Only one option can be active at a time - marking an option active automatically deactivates any other option.
103 */
104 void update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const;
105
106 /**
107 \brief Marks an option of a filter active/inactive in a FilterState object, without having an instance of OptionSelectorFilter.
108
109 Updates an instance of FilterState, without the need for an OptionSelectorFilter instance. This is meant
110 to be used when creating a canned Query that references another scope.
111 */
112 static void update_state(FilterState& filter_state, std::string const& filter_id, std::string const& option_id, bool value);
113
114private:
115 RadioButtonsFilter(internal::RadioButtonsFilterImpl*);
116 internal::RadioButtonsFilterImpl* fwd() const;
117 friend class internal::RadioButtonsFilterImpl;
118};
119
120} // namespace scopes
121
122} // namespace unity
123
124#endif
0125
=== modified file 'include/unity/scopes/RangeInputFilter.h'
--- include/unity/scopes/RangeInputFilter.h 2014-05-09 11:26:27 +0000
+++ include/unity/scopes/RangeInputFilter.h 2014-05-21 14:02:43 +0000
@@ -124,10 +124,10 @@
124 \brief Store start and end value in the filter state, without having an instance of RangeInputFilter.124 \brief Store start and end value in the filter state, without having an instance of RangeInputFilter.
125125
126 Updates filter_state with start and end values without an instance of RangeInputFilter. This is meant126 Updates filter_state with start and end values without an instance of RangeInputFilter. This is meant
127 for the explanation of this method.
127 to be used when creating a CannedQuery that points to a foreign scope.128 to be used when creating a CannedQuery that points to a foreign scope.
128129
129 See the documentation of unity::scopes::update_state(FilterState const& filter_state, Variant const& start_value, Variant const& end_value)130 See the documentation of unity::scopes::update_state(FilterState const& filter_state, Variant const& start_value, Variant const& end_value)
130 for the explanation of this method.
131131
132 \param filter_state FilterState instance to update132 \param filter_state FilterState instance to update
133 \param filter_id Unique identifier of filter133 \param filter_id Unique identifier of filter
134134
=== added file 'include/unity/scopes/RatingFilter.h'
--- include/unity/scopes/RatingFilter.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/RatingFilter.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,180 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17 */
18
19#ifndef UNITY_SCOPES_RATINGFILTER_H
20#define UNITY_SCOPES_RATINGFILTER_H
21
22#include <unity/scopes/FilterBase.h>
23#include <unity/scopes/FilterOption.h>
24
25namespace unity
26{
27
28namespace scopes
29{
30
31class FilterState;
32
33namespace internal
34{
35
36class RatingFilterImpl;
37
38}
39
40/**
41\brief A filter that allows for rating-based selection.
42
43Displays filter with a set of options, where every option has a label and icon.
44Only one option can be active at a time. The active option uses the icon in "on" state
45(see unity::scopes::RatingFilter::set_on_icon() ). All other icons are "off" (see unity::scopes::RatingFilter::set_off_icon() ).
46By default, "on" and "off" icons are bright and dim star respectively.
47
48This filter is best suited for rating-based filtering.
49*/
50class UNITY_API RatingFilter : public FilterBase
51{
52public:
53/// @cond
54 UNITY_DEFINES_PTRS(RatingFilter);
55/// @endcond
56
57 /**
58 \brief Creates RatingFilter widget.
59
60 Creates an empty RatingFilter widget. Use unity::scopes::RatingFilter::add_option() to add rating options to it.
61 \param id A unique identifier for the filter that can be used to identify it later among several filters.
62 \param label A display label for this filter
63 \return Instance of RatingFilter
64 */
65 static RatingFilter::UPtr create(std::string const& id, std::string const& label);
66
67 /**
68 \brief Creates RatingFilter widget.
69
70 Creates a RatingFilter widget and populates it with some standard rating options.
71 This is a convienience factory method, that fills RatingFilter in with options for ratings
72 from 1 up to top_rating. Options are created with identifiers "1", "2" and so on, and labels
73 "1+", "2+" etc., except for that last label, which is just the number (no plus sign). The maximum top_rating
74 allowed is 10.
75
76 \param id A unique identifier for the filter that can be used to identify it later among several filters.
77 \param label A display label for this filter
78 \param top_rating The maximum rating allowed.
79 \return Instance of RatingFilter
80 */
81 static RatingFilter::UPtr create(std::string const& id, std::string const& label, int top_rating);
82
83 /**
84 \brief Adds a new option to the filter.
85
86 \param id A unique identifier of the option.
87 \param label A display label for the option
88 \return Instance of FilterOption
89 */
90 FilterOption::SCPtr add_option(std::string const& id, std::string const& label);
91
92 /**
93 \brief Set a custom icon for the "on" state.
94
95 If not set, a star icon will be used by default.
96
97 \param on_icon icon uri
98 */
99 void set_on_icon(std::string const& on_icon);
100
101 /**
102 \brief Set a custom icon for the "off" state.
103
104 If not set, a dim star icon will be used by default.
105
106 \param off_icon icon uri
107 */
108 void set_off_icon(std::string const& off_icon);
109
110 /**
111 \brief Get the label of this filter.
112 \return The filter label.
113 */
114 std::string label() const;
115
116 /**
117 \brief Get custom icon for the "on" state.
118
119 If empty, then the default icon will be used.
120
121 \return icon uri or empty string
122 */
123 std::string on_icon() const;
124
125 /**
126 \brief Get custom icon for the "off" state.
127
128 If empty, then the default icon will be used.
129
130 \return icon uri or empty string
131 */
132 std::string off_icon() const;
133
134 /**
135 \brief Get all options of this filter, in the order they were added.
136 \return The list of options.
137 */
138 std::list<FilterOption::SCPtr> options() const;
139
140 /**
141 \brief Check if a rating option is active.
142 \param filter_state The state of filters
143 \return true if a rating option is active.
144 */
145 bool has_active_rating(FilterState const& filter_state) const;
146
147 /**
148 \brief Get active option from an instance of FilterState for this filter.
149 \return The active option or nullptr if no option is active.
150 */
151 FilterOption::SCPtr active_rating(FilterState const& filter_state) const;
152
153 /**
154 \brief Marks given FilterOption of this filter instance as active (or not active) in a FilterState object.
155
156 Records the given FilterOption as "selected" in the FilterState. This is meant to be used to modify a
157 FilterState received with a search request before sending it back to the client (UI shell).
158 Only one option can be active at a time - marking an option active automatically deactivates any other option.
159 */
160 void update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const;
161
162 /**
163 \brief Marks an option of a filter active/inactive in a FilterState object, without having an instance of OptionSelectorFilter.
164
165 Updates an instance of FilterState, without the need for an OptionSelectorFilter instance. This is meant
166 to be used when creating a canned Query that references another scope.
167 */
168 static void update_state(FilterState& filter_state, std::string const& filter_id, std::string const& option_id, bool value);
169
170private:
171 RatingFilter(internal::RatingFilterImpl*);
172 internal::RatingFilterImpl* fwd() const;
173 friend class internal::RatingFilterImpl;
174};
175
176} // namespace scopes
177
178} // namespace unity
179
180#endif
0181
=== modified file 'include/unity/scopes/internal/FilterBaseImpl.h'
--- include/unity/scopes/internal/FilterBaseImpl.h 2014-05-02 10:19:46 +0000
+++ include/unity/scopes/internal/FilterBaseImpl.h 2014-05-21 14:02:43 +0000
@@ -47,6 +47,7 @@
47 static FilterBase::SCPtr deserialize(VariantMap const& var);47 static FilterBase::SCPtr deserialize(VariantMap const& var);
48 static VariantArray serialize_filters(Filters const& filters);48 static VariantArray serialize_filters(Filters const& filters);
49 static Filters deserialize_filters(VariantArray const& var);49 static Filters deserialize_filters(VariantArray const& var);
50 static void validate_filters(Filters const& filters);
5051
51protected:52protected:
52 virtual void serialize(VariantMap& var) const = 0;53 virtual void serialize(VariantMap& var) const = 0;
5354
=== added file 'include/unity/scopes/internal/MWPublisher.h'
--- include/unity/scopes/internal/MWPublisher.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/internal/MWPublisher.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#ifndef UNITY_SCOPES_INTERNAL_MWPUBLISHER_H
20#define UNITY_SCOPES_INTERNAL_MWPUBLISHER_H
21
22#include <unity/util/DefinesPtrs.h>
23#include <unity/util/NonCopyable.h>
24
25namespace unity
26{
27
28namespace scopes
29{
30
31namespace internal
32{
33
34class MWPublisher
35{
36public:
37 NONCOPYABLE(MWPublisher);
38 UNITY_DEFINES_PTRS(MWPublisher);
39
40 virtual ~MWPublisher();
41
42 virtual std::string endpoint() const = 0;
43 virtual void send_message(std::string const& message, std::string const& topic = "") = 0;
44
45protected:
46 MWPublisher();
47};
48
49} // namespace internal
50
51} // namespace scopes
52
53} // namespace unity
54
55#endif // UNITY_SCOPES_INTERNAL_MWPUBLISHER_H
056
=== added file 'include/unity/scopes/internal/MWSubscriber.h'
--- include/unity/scopes/internal/MWSubscriber.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/internal/MWSubscriber.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#ifndef UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H
20#define UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H
21
22#include <unity/util/DefinesPtrs.h>
23#include <unity/util/NonCopyable.h>
24
25namespace unity
26{
27
28namespace scopes
29{
30
31namespace internal
32{
33
34typedef std::function<void(std::string const& message)> SubscriberCallback;
35
36class MWSubscriber
37{
38public:
39 NONCOPYABLE(MWSubscriber);
40 UNITY_DEFINES_PTRS(MWSubscriber);
41
42 virtual ~MWSubscriber();
43
44 virtual std::string endpoint() const = 0;
45 virtual void set_message_callback(SubscriberCallback callback) = 0;
46
47protected:
48 MWSubscriber();
49};
50
51} // namespace internal
52
53} // namespace scopes
54
55} // namespace unity
56
57#endif // UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H
058
=== modified file 'include/unity/scopes/internal/MiddlewareBase.h'
--- include/unity/scopes/internal/MiddlewareBase.h 2014-05-08 12:55:26 +0000
+++ include/unity/scopes/internal/MiddlewareBase.h 2014-05-21 14:02:43 +0000
@@ -20,11 +20,13 @@
20#define UNITY_SCOPES_INTERNAL_MIDDLEWAREBASE_H20#define UNITY_SCOPES_INTERNAL_MIDDLEWAREBASE_H
2121
22#include <unity/scopes/internal/MWObjectProxyFwd.h>22#include <unity/scopes/internal/MWObjectProxyFwd.h>
23#include <unity/scopes/internal/MWPublisher.h>
23#include <unity/scopes/internal/MWQueryCtrlProxyFwd.h>24#include <unity/scopes/internal/MWQueryCtrlProxyFwd.h>
24#include <unity/scopes/internal/MWQueryProxyFwd.h>25#include <unity/scopes/internal/MWQueryProxyFwd.h>
25#include <unity/scopes/internal/MWRegistryProxyFwd.h>26#include <unity/scopes/internal/MWRegistryProxyFwd.h>
26#include <unity/scopes/internal/MWScopeProxyFwd.h>27#include <unity/scopes/internal/MWScopeProxyFwd.h>
27#include <unity/scopes/internal/MWStateReceiverProxyFwd.h>28#include <unity/scopes/internal/MWStateReceiverProxyFwd.h>
29#include <unity/scopes/internal/MWSubscriber.h>
28#include <unity/scopes/internal/QueryObjectBase.h>30#include <unity/scopes/internal/QueryObjectBase.h>
29#include <unity/scopes/internal/QueryCtrlObjectBase.h>31#include <unity/scopes/internal/QueryCtrlObjectBase.h>
30#include <unity/scopes/internal/RegistryObjectBase.h>32#include <unity/scopes/internal/RegistryObjectBase.h>
@@ -84,6 +86,9 @@
84 virtual void add_dflt_scope_object(ScopeObjectBase::SPtr const& scope) = 0;86 virtual void add_dflt_scope_object(ScopeObjectBase::SPtr const& scope) = 0;
85 virtual MWStateReceiverProxy add_state_receiver_object(std::string const& identity, StateReceiverObject::SPtr const& state_receiver) = 0;87 virtual MWStateReceiverProxy add_state_receiver_object(std::string const& identity, StateReceiverObject::SPtr const& state_receiver) = 0;
8688
89 virtual MWPublisher::UPtr create_publisher(std::string const& publisher_id) = 0;
90 virtual MWSubscriber::UPtr create_subscriber(std::string const& publisher_id, std::string const& topic = "") = 0;
91
87 virtual std::string get_scope_endpoint() = 0;92 virtual std::string get_scope_endpoint() = 0;
88 virtual std::string get_query_endpoint() = 0;93 virtual std::string get_query_endpoint() = 0;
89 virtual std::string get_query_ctrl_endpoint() = 0;94 virtual std::string get_query_ctrl_endpoint() = 0;
9095
=== modified file 'include/unity/scopes/internal/OptionSelectorFilterImpl.h'
--- include/unity/scopes/internal/OptionSelectorFilterImpl.h 2014-05-08 16:10:18 +0000
+++ include/unity/scopes/internal/OptionSelectorFilterImpl.h 2014-05-21 14:02:43 +0000
@@ -43,9 +43,11 @@
43 OptionSelectorFilterImpl(VariantMap const& var);43 OptionSelectorFilterImpl(VariantMap const& var);
44 std::string label() const;44 std::string label() const;
45 bool multi_select() const;45 bool multi_select() const;
46 FilterOption::SCPtr add_option(std::string const& id, std::string const& label);46 virtual FilterOption::SCPtr add_option(std::string const& id, std::string const& label);
47 std::list<FilterOption::SCPtr> options() const;47 std::list<FilterOption::SCPtr> options() const;
48 int num_of_options() const;
48 std::set<FilterOption::SCPtr> active_options(FilterState const& filter_state) const;49 std::set<FilterOption::SCPtr> active_options(FilterState const& filter_state) const;
50 bool has_active_option(FilterState const& filter_state) const;
49 void update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const;51 void update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const;
50 static void update_state(FilterState& filter_state, std::string const& filter_id, std::string const& option_id, bool value);52 static void update_state(FilterState& filter_state, std::string const& filter_id, std::string const& option_id, bool value);
51 static OptionSelectorFilter::SPtr create(VariantMap const& var);53 static OptionSelectorFilter::SPtr create(VariantMap const& var);
5254
=== added file 'include/unity/scopes/internal/RadioButtonsFilterImpl.h'
--- include/unity/scopes/internal/RadioButtonsFilterImpl.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/internal/RadioButtonsFilterImpl.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17 */
18
19#ifndef UNITY_INTERNAL_RADIOBUTTONSFILTERIMPL_H
20#define UNITY_INTERNAL_RADIOBUTTONSFILTERIMPL_H
21
22#include <unity/scopes/internal/OptionSelectorFilterImpl.h>
23#include <unity/scopes/RadioButtonsFilter.h>
24
25namespace unity
26{
27
28namespace scopes
29{
30
31namespace internal
32{
33
34class RadioButtonsFilterImpl : public OptionSelectorFilterImpl
35{
36public:
37 RadioButtonsFilterImpl(std::string const& id, std::string const& label);
38 RadioButtonsFilterImpl(VariantMap const& var);
39 FilterOption::SCPtr active_option(FilterState const& filter_state) const;
40 std::string filter_type() const override;
41 static RadioButtonsFilter::SPtr create(VariantMap const& var);
42};
43
44} // namespace internal
45
46} // namespace scopes
47
48} // namespace unity
49
50#endif
051
=== added file 'include/unity/scopes/internal/RatingFilterImpl.h'
--- include/unity/scopes/internal/RatingFilterImpl.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/internal/RatingFilterImpl.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17 */
18
19#ifndef UNITY_INTERNAL_RATINGFILTERIMPL_H
20#define UNITY_INTERNAL_RATINGFILTERIMPL_H
21
22#include <unity/scopes/internal/RadioButtonsFilterImpl.h>
23#include <unity/scopes/RatingFilter.h>
24
25namespace unity
26{
27
28namespace scopes
29{
30
31namespace internal
32{
33
34class RatingFilterImpl : public RadioButtonsFilterImpl
35{
36public:
37 RatingFilterImpl(std::string const& id, std::string const& label);
38 RatingFilterImpl(std::string const& id, std::string const& label, int top_rating);
39 RatingFilterImpl(VariantMap const& var);
40 FilterOption::SCPtr add_option(std::string const& id, std::string const& label) override;
41 void set_on_icon(std::string const& on_icon);
42 void set_off_icon(std::string const& off_icon);
43 std::string on_icon() const;
44 std::string off_icon() const;
45 FilterOption::SCPtr active_rating(FilterState const& filter_state) const;
46
47 static RatingFilter::SPtr create(VariantMap const& var);
48
49 std::string filter_type() const override;
50
51 static const int max_rating = 10;
52
53private:
54 std::string on_icon_;
55 std::string off_icon_;
56};
57
58} // namespace internal
59
60} // namespace scopes
61
62} // namespace unity
63
64#endif
065
=== modified file 'include/unity/scopes/internal/smartscopes/SmartScopesClient.h'
--- include/unity/scopes/internal/smartscopes/SmartScopesClient.h 2014-03-24 10:15:20 +0000
+++ include/unity/scopes/internal/smartscopes/SmartScopesClient.h 2014-05-21 14:02:43 +0000
@@ -54,6 +54,7 @@
54 std::string base_url;54 std::string base_url;
55 std::shared_ptr<std::string> icon; // optional55 std::shared_ptr<std::string> icon; // optional
56 std::shared_ptr<std::string> art; // optional56 std::shared_ptr<std::string> art; // optional
57 std::shared_ptr<VariantMap> appearance; // optional
57 bool invisible = false;58 bool invisible = false;
58};59};
5960
6061
=== modified file 'include/unity/scopes/internal/zmq_middleware/ObjectAdapter.h'
--- include/unity/scopes/internal/zmq_middleware/ObjectAdapter.h 2014-05-08 13:27:38 +0000
+++ include/unity/scopes/internal/zmq_middleware/ObjectAdapter.h 2014-05-21 14:02:43 +0000
@@ -98,8 +98,6 @@
98 // zmqpp::socket subscribe_to_ctrl_socket();98 // zmqpp::socket subscribe_to_ctrl_socket();
99 // void stop_workers() noexcept;99 // void stop_workers() noexcept;
100100
101 void safe_bind(zmqpp::socket& s, std::string const& endpoint);
102
103 std::shared_ptr<ServantBase> find_servant(std::string const& id, std::string const& category);101 std::shared_ptr<ServantBase> find_servant(std::string const& id, std::string const& category);
104102
105 // Thread start functions103 // Thread start functions
106104
=== modified file 'include/unity/scopes/internal/zmq_middleware/Util.h'
--- include/unity/scopes/internal/zmq_middleware/Util.h 2014-01-28 06:34:03 +0000
+++ include/unity/scopes/internal/zmq_middleware/Util.h 2014-05-21 14:02:43 +0000
@@ -19,6 +19,8 @@
19#ifndef UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_UTIL_H19#ifndef UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_UTIL_H
20#define UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_UTIL_H20#define UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_UTIL_H
2121
22#include <zmqpp/socket.hpp>
23
22#include <string>24#include <string>
2325
24namespace unity26namespace unity
@@ -35,6 +37,8 @@
3537
36void throw_if_bad_endpoint(std::string const& endpoint);38void throw_if_bad_endpoint(std::string const& endpoint);
3739
40void safe_bind(zmqpp::socket& s, std::string const& endpoint);
41
38} // namespace zmq_middleware42} // namespace zmq_middleware
3943
40} // namespace internal44} // namespace internal
4145
=== modified file 'include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h'
--- include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h 2014-05-15 00:34:39 +0000
+++ include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h 2014-05-21 14:02:43 +0000
@@ -78,10 +78,13 @@
78 virtual void add_dflt_query_object(QueryObjectBase::SPtr const& query) override;78 virtual void add_dflt_query_object(QueryObjectBase::SPtr const& query) override;
79 virtual MWRegistryProxy add_registry_object(std::string const& identity, RegistryObjectBase::SPtr const& registry) override;79 virtual MWRegistryProxy add_registry_object(std::string const& identity, RegistryObjectBase::SPtr const& registry) override;
80 virtual MWReplyProxy add_reply_object(ReplyObjectBase::SPtr const& reply) override;80 virtual MWReplyProxy add_reply_object(ReplyObjectBase::SPtr const& reply) override;
81 virtual MWScopeProxy add_scope_object(std::string const& identity, ScopeObjectBase::SPtr const& scope, int64_t idle_timeout = 0) override;81 virtual MWScopeProxy add_scope_object(std::string const& identity, ScopeObjectBase::SPtr const& scope, int64_t idle_timeout) override;
82 virtual void add_dflt_scope_object(ScopeObjectBase::SPtr const& scope) override;82 virtual void add_dflt_scope_object(ScopeObjectBase::SPtr const& scope) override;
83 virtual MWStateReceiverProxy add_state_receiver_object(std::string const& identity, StateReceiverObject::SPtr const& state_receiver) override;83 virtual MWStateReceiverProxy add_state_receiver_object(std::string const& identity, StateReceiverObject::SPtr const& state_receiver) override;
8484
85 virtual MWPublisher::UPtr create_publisher(std::string const& publisher_id) override;
86 virtual MWSubscriber::UPtr create_subscriber(std::string const& publisher_id, std::string const& topic) override;
87
85 virtual std::string get_scope_endpoint() override;88 virtual std::string get_scope_endpoint() override;
86 virtual std::string get_query_endpoint() override;89 virtual std::string get_query_endpoint() override;
87 virtual std::string get_query_ctrl_endpoint() override;90 virtual std::string get_query_ctrl_endpoint() override;
8891
=== added file 'include/unity/scopes/internal/zmq_middleware/ZmqPublisher.h'
--- include/unity/scopes/internal/zmq_middleware/ZmqPublisher.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/internal/zmq_middleware/ZmqPublisher.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,83 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#ifndef UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQPUBLISHER_H
20#define UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQPUBLISHER_H
21
22#include <unity/scopes/internal/MWPublisher.h>
23
24#include <zmqpp/context.hpp>
25#include <zmqpp/socket.hpp>
26
27#include <condition_variable>
28#include <queue>
29#include <thread>
30
31namespace unity
32{
33
34namespace scopes
35{
36
37namespace internal
38{
39
40namespace zmq_middleware
41{
42
43class ZmqPublisher : public virtual MWPublisher
44{
45public:
46 ZmqPublisher(zmqpp::context* context, std::string const& publisher_id,
47 std::string const& endpoint_dir);
48 virtual ~ZmqPublisher();
49
50 std::string endpoint() const override;
51 void send_message(std::string const& message, std::string const& topic) override;
52
53private:
54 enum ThreadState
55 {
56 NotRunning,
57 Running,
58 Stopping,
59 Failed
60 };
61
62 zmqpp::context* const context_;
63 std::string const endpoint_;
64 std::queue<std::string> message_queue_;
65
66 std::thread thread_;
67 std::mutex mutex_;
68 std::condition_variable cond_;
69 ThreadState thread_state_;
70 std::exception_ptr thread_exception_;
71
72 void publisher_thread();
73};
74
75} // namespace zmq_middleware
76
77} // namespace internal
78
79} // namespace scopes
80
81} // namespace unity
82
83#endif // UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQPUBLISHER_H
084
=== added file 'include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h'
--- include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h 2014-05-21 14:02:43 +0000
@@ -0,0 +1,86 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#ifndef UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H
20#define UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H
21
22#include <unity/scopes/internal/MWSubscriber.h>
23
24#include <zmqpp/context.hpp>
25
26#include <condition_variable>
27#include <thread>
28
29namespace unity
30{
31
32namespace scopes
33{
34
35namespace internal
36{
37
38namespace zmq_middleware
39{
40
41class StopPublisher;
42
43class ZmqSubscriber : public virtual MWSubscriber
44{
45public:
46 ZmqSubscriber(zmqpp::context* context, std::string const& publisher_id,
47 std::string const& endpoint_dir, std::string const& topic);
48 virtual ~ZmqSubscriber();
49
50 std::string endpoint() const override;
51 void set_message_callback(SubscriberCallback callback) override;
52
53private:
54 enum ThreadState
55 {
56 NotRunning,
57 Running,
58 Stopping,
59 Failed
60 };
61
62 zmqpp::context* const context_;
63 std::string const endpoint_;
64 std::string const topic_;
65
66 std::thread thread_;
67 std::unique_ptr<StopPublisher> thread_stopper_;
68 std::mutex mutex_;
69 std::condition_variable cond_;
70 ThreadState thread_state_;
71 std::exception_ptr thread_exception_;
72
73 SubscriberCallback callback_;
74
75 void subscriber_thread();
76};
77
78} // namespace zmq_middleware
79
80} // namespace internal
81
82} // namespace scopes
83
84} // namespace unity
85
86#endif // UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H
087
=== modified file 'scoperegistry/CMakeLists.txt'
--- scoperegistry/CMakeLists.txt 2014-05-06 09:00:45 +0000
+++ scoperegistry/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -1,7 +1,6 @@
1set(SRC1set(SRC
2 FindFiles.cpp2 FindFiles.cpp
3 scoperegistry.cpp3 scoperegistry.cpp
4 ScopeSet.cpp
5)4)
65
7include_directories(${CMAKE_CURRENT_SOURCE_DIR})6include_directories(${CMAKE_CURRENT_SOURCE_DIR})
87
=== modified file 'scoperegistry/FindFiles.cpp'
--- scoperegistry/FindFiles.cpp 2014-04-04 13:22:38 +0000
+++ scoperegistry/FindFiles.cpp 2014-05-21 14:02:43 +0000
@@ -21,12 +21,14 @@
21#include <unity/UnityExceptions.h>21#include <unity/UnityExceptions.h>
22#include <unity/util/ResourcePtr.h>22#include <unity/util/ResourcePtr.h>
2323
24#include <boost/filesystem/path.hpp>
25
26#include <map>
27
24#include <dirent.h>28#include <dirent.h>
25#include <string.h>29#include <string.h>
26#include <sys/stat.h>30#include <sys/stat.h>
2731
28#include <boost/filesystem/path.hpp>
29
30using namespace std;32using namespace std;
31using namespace unity;33using namespace unity;
32using namespace boost;34using namespace boost;
@@ -86,10 +88,14 @@
86// Return all files of the form dir/*/<scomescope>.ini that are regular files or88// Return all files of the form dir/*/<scomescope>.ini that are regular files or
87// symbolic links and have the specified suffix.89// symbolic links and have the specified suffix.
88// The empty suffix is legal and causes all regular files and symlinks to be returned.90// The empty suffix is legal and causes all regular files and symlinks to be returned.
91// Print error message for any scopes with an id that was seen previously.
8992
90vector<string> find_scope_config_files(string const& install_dir, string const& suffix)93vector<string> find_scope_config_files(string const& install_dir,
94 string const& suffix,
95 function<void(string const&)> error)
91{96{
92 vector<string> files;97 vector<string> files;
98 map<string, string> scopes_seen;
9399
94 auto subdirs = find_entries(install_dir, Directory);100 auto subdirs = find_entries(install_dir, Directory);
95 for (auto subdir : subdirs)101 for (auto subdir : subdirs)
@@ -97,13 +103,18 @@
97 auto candidates = find_entries(subdir, File);103 auto candidates = find_entries(subdir, File);
98 for (auto c : candidates)104 for (auto c : candidates)
99 {105 {
100 // TODO Check for multiple ini files
101
102 filesystem::path path(c);106 filesystem::path path(c);
103 if (path.extension() != suffix) {107 if (path.extension() != suffix) {
104 continue;108 continue;
105 }109 }
106110 auto stem = path.stem().native();
111 auto const it = scopes_seen.find(stem);
112 if (it != scopes_seen.end())
113 {
114 error("ignoring second instance of non-unique scope: " + path.native() + "\n"
115 "previous instance: " + it->second);
116 }
117 scopes_seen[stem] = path.native();
107 files.emplace_back(c);118 files.emplace_back(c);
108 }119 }
109 }120 }
110121
=== modified file 'scoperegistry/FindFiles.h'
--- scoperegistry/FindFiles.h 2013-11-21 21:44:00 +0000
+++ scoperegistry/FindFiles.h 2014-05-21 14:02:43 +0000
@@ -19,8 +19,9 @@
19#ifndef SCOPEREGISTRY_FINDFILES_H19#ifndef SCOPEREGISTRY_FINDFILES_H
20#define SCOPEREGISTRY_FINDFILES_H20#define SCOPEREGISTRY_FINDFILES_H
2121
22#include <functional>
23#include <string>
22#include <vector>24#include <vector>
23#include <string>
2425
25namespace scoperegistry26namespace scoperegistry
26{27{
@@ -34,11 +35,14 @@
34// we get those two .ini files, but no .ini files in canonical or underneath35// we get those two .ini files, but no .ini files in canonical or underneath
35// further-nested directories.36// further-nested directories.
3637
37std::vector<std::string> find_scope_config_files(std::string const& install_dir, std::string const& suffix);38std::vector<std::string> find_scope_config_files(std::string const& install_dir,
39 std::string const& suffix,
40 std::function<void(std::string const&)> error);
3841
39// Return a vector of file names in dir with the given suffix.42// Return a vector of file names in dir with the given suffix.
4043
41std::vector<std::string> find_files(std::string const& dir, std::string const& suffix);44std::vector<std::string> find_files(std::string const& dir,
45 std::string const& suffix);
4246
43} // namespace scoperegistry47} // namespace scoperegistry
4448
4549
=== removed file 'scoperegistry/ScopeSet.cpp'
--- scoperegistry/ScopeSet.cpp 2014-04-03 12:57:25 +0000
+++ scoperegistry/ScopeSet.cpp 1970-01-01 00:00:00 +0000
@@ -1,124 +0,0 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the Lesser GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Jussi Pakkanen <jussi.pakkanen@canonical.com>
17 */
18
19#include"FindFiles.h"
20#include"ScopeSet.h"
21#include <unity/scopes/ScopeMetadata.h>
22#include <unity/scopes/internal/RegistryConfig.h>
23#include <unity/scopes/internal/ScopeConfig.h>
24#include <unity/scopes/ScopeExceptions.h>
25#include<memory>
26#include<map>
27#include<set>
28#include<cstring>
29
30using namespace std;
31using namespace unity::scopes;
32using namespace unity::scopes::internal;
33
34namespace scoperegistry
35{
36
37static string strip_suffix(string const& s, string const& suffix)
38{
39 auto s_len = s.length();
40 auto suffix_len = suffix.length();
41 if (s_len >= suffix_len)
42 {
43 if (s.compare(s_len - suffix_len, suffix_len, suffix) == 0)
44 {
45 return string(s, 0, s_len - suffix_len);
46 }
47 }
48 return s;
49}
50
51struct ScopeSetPrivate
52{
53 std::set<string> overridable_scopes;
54 std::map<string, unique_ptr<ScopeConfig>> scopes;
55};
56
57ScopeSet::ScopeSet(const RegistryConfig& c) : p(new ScopeSetPrivate())
58{
59 string canonical_dir = c.scope_installdir();
60 string oem_dir = c.oem_installdir();
61 auto canonical_files = find_scope_config_files(canonical_dir, ".ini");
62 auto oem_files = find_scope_config_files(oem_dir, ".ini");
63 for (const auto &path : canonical_files)
64 {
65 unique_ptr<ScopeConfig> sc(new ScopeConfig(path));
66 // basename() modifies its argument
67 string file_name = basename(const_cast<char*>(string(path).c_str()));
68 string scope_id = strip_suffix(file_name, ".ini");
69 if (sc->overrideable())
70 {
71 p->overridable_scopes.insert(path);
72 }
73 p->scopes[scope_id] = move(sc);
74 }
75 for (const auto &path : oem_files)
76 {
77 unique_ptr<ScopeConfig> sc(new ScopeConfig(path));
78 string file_name = basename(const_cast<char*>(string(path).c_str()));
79 string scope_id = strip_suffix(file_name, ".ini");
80 if (p->scopes.find(scope_id) != p->scopes.end())
81 {
82 if (p->overridable_scopes.find(scope_id) != p->overridable_scopes.end())
83 {
84 p->scopes[scope_id] = move(sc);
85 }
86 else
87 {
88 // print error about trying to override a non-overridable scope.
89 }
90 }
91 else
92 {
93 p->scopes[scope_id] = move(sc);
94 }
95 }
96 // Add click scope parsing here.
97}
98
99ScopeSet::~ScopeSet()
100{
101 delete p;
102}
103
104std::vector<std::string> ScopeSet::list() const
105{
106 vector<string> list;
107 for (auto &i : p->scopes)
108 {
109 list.push_back(i.first);
110 }
111 return list;
112}
113
114const unity::scopes::internal::ScopeConfig&
115ScopeSet::get(const std::string& name)
116{
117 if (p->scopes.find(name) == p->scopes.end())
118 {
119 throw NotFoundException("Scope does not exist", name);
120 }
121 return *p->scopes[name].get();
122}
123
124}
1250
=== removed file 'scoperegistry/ScopeSet.h'
--- scoperegistry/ScopeSet.h 2014-01-14 13:36:43 +0000
+++ scoperegistry/ScopeSet.h 1970-01-01 00:00:00 +0000
@@ -1,56 +0,0 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the Lesser GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Jussi Pakkanen <jussi.pakkanen@canonical.com>
17 */
18
19#ifndef SCOPEREGISTRY_SCOPESET_H_
20#define SCOPEREGISTRY_SCOPESET_H_
21
22#include<vector>
23#include<string>
24#include<unity/scopes/internal/RegistryConfig.h>
25#include<unity/scopes/internal/ScopeConfig.h>
26
27
28namespace scoperegistry
29{
30
31struct ScopeSetPrivate;
32
33
34class ScopeSet final
35{
36
37public:
38
39 ScopeSet(const ::unity::scopes::internal::RegistryConfig& c);
40 ~ScopeSet();
41
42 ScopeSet(const ScopeSet&) = delete;
43 ScopeSet& operator=(const ScopeSet&) = delete;
44
45 std::vector<std::string> list() const;
46 const unity::scopes::internal::ScopeConfig& get(const std::string& name);
47
48private:
49 ScopeSetPrivate* p;
50
51};
52
53
54}
55
56#endif
570
=== modified file 'scoperegistry/scoperegistry.cpp'
--- scoperegistry/scoperegistry.cpp 2014-05-14 17:26:34 +0000
+++ scoperegistry/scoperegistry.cpp 2014-05-21 14:02:43 +0000
@@ -136,7 +136,7 @@
136 map<string, string> fixed_scopes; // Scopes that the OEM cannot override136 map<string, string> fixed_scopes; // Scopes that the OEM cannot override
137 map<string, string> overrideable_scopes; // Scopes that the OEM can override137 map<string, string> overrideable_scopes; // Scopes that the OEM can override
138138
139 auto config_files = find_scope_config_files(scope_installdir, ".ini");139 auto config_files = find_scope_config_files(scope_installdir, ".ini", error);
140 for (auto&& path : config_files)140 for (auto&& path : config_files)
141 {141 {
142 filesystem::path p(path);142 filesystem::path p(path);
@@ -163,7 +163,7 @@
163 {163 {
164 try164 try
165 {165 {
166 auto oem_paths = find_scope_config_files(oem_installdir, ".ini");166 auto oem_paths = find_scope_config_files(oem_installdir, ".ini", error);
167 for (auto&& path : oem_paths)167 for (auto&& path : oem_paths)
168 {168 {
169 filesystem::path p(path);169 filesystem::path p(path);
@@ -199,7 +199,7 @@
199 {199 {
200 try200 try
201 {201 {
202 auto click_paths = find_scope_config_files(click_installdir, ".ini");202 auto click_paths = find_scope_config_files(click_installdir, ".ini", error);
203 for (auto&& path : click_paths)203 for (auto&& path : click_paths)
204 {204 {
205 filesystem::path p(path);205 filesystem::path p(path);
@@ -424,7 +424,6 @@
424424
425 add_local_scopes(registry, local_scopes, middleware, scoperunner_path, config_file, false, process_timeout);425 add_local_scopes(registry, local_scopes, middleware, scoperunner_path, config_file, false, process_timeout);
426 add_local_scopes(registry, click_scopes, middleware, scoperunner_path, config_file, true, process_timeout);426 add_local_scopes(registry, click_scopes, middleware, scoperunner_path, config_file, true, process_timeout);
427 local_scopes.insert(click_scopes.begin(), click_scopes.end());
428 if (ss_reg_id.empty())427 if (ss_reg_id.empty())
429 {428 {
430 error("no remote registry configured, only local scopes will be available");429 error("no remote registry configured, only local scopes will be available");
431430
=== modified file 'scoperunner/scoperunner.cpp'
--- scoperunner/scoperunner.cpp 2014-05-09 04:04:06 +0000
+++ scoperunner/scoperunner.cpp 2014-05-21 14:02:43 +0000
@@ -93,7 +93,37 @@
93 auto rt = RuntimeImpl::create(scope_id, runtime_config);93 auto rt = RuntimeImpl::create(scope_id, runtime_config);
94 auto mw = rt->factory()->create(scope_id, reg_conf.mw_kind(), reg_conf.mw_configfile());94 auto mw = rt->factory()->create(scope_id, reg_conf.mw_kind(), reg_conf.mw_configfile());
9595
96 ScopeLoader::SPtr loader = ScopeLoader::load(scope_id, lib_dir + "lib" + scope_id + ".so", rt->registry());96 // For a scope_id "Fred", we look for the library as "libFred.so", "Fred.so", and "scope.so".
97 vector<string> libs;
98 libs.push_back(lib_dir + "lib" + scope_id + ".so");
99 libs.push_back(lib_dir + scope_id + ".so");
100 libs.push_back(lib_dir + "scope.so");
101 string failed_libs;
102 ScopeLoader::SPtr loader;
103 exception_ptr ep;
104 for (auto const& lib : libs)
105 {
106 try
107 {
108 loader = ScopeLoader::load(scope_id, lib, rt->registry());
109 }
110 catch (unity::ResourceException& e)
111 {
112 failed_libs += "\n " + lib;
113 ep = e.remember(ep);
114 }
115 if (loader)
116 {
117 break;
118 }
119 }
120 if (!loader)
121 {
122 unity::ResourceException e("Cannot load scope " + scope_id + "; tried in the following locations:"
123 + failed_libs);
124 e.remember(ep);
125 throw e;
126 }
97 loader->start();127 loader->start();
98128
99 // Give a thread to the scope to do with as it likes. If the scope doesn't want to use it and129 // Give a thread to the scope to do with as it likes. If the scope doesn't want to use it and
100130
=== modified file 'src/scopes/CMakeLists.txt'
--- src/scopes/CMakeLists.txt 2014-05-08 14:49:31 +0000
+++ src/scopes/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -29,6 +29,8 @@
29 ${CMAKE_CURRENT_SOURCE_DIR}/PreviewWidget.cpp29 ${CMAKE_CURRENT_SOURCE_DIR}/PreviewWidget.cpp
30 ${CMAKE_CURRENT_SOURCE_DIR}/QueryBase.cpp30 ${CMAKE_CURRENT_SOURCE_DIR}/QueryBase.cpp
31 ${CMAKE_CURRENT_SOURCE_DIR}/QueryCtrl.cpp31 ${CMAKE_CURRENT_SOURCE_DIR}/QueryCtrl.cpp
32 ${CMAKE_CURRENT_SOURCE_DIR}/RadioButtonsFilter.cpp
33 ${CMAKE_CURRENT_SOURCE_DIR}/RatingFilter.cpp
32 ${CMAKE_CURRENT_SOURCE_DIR}/Registry.cpp34 ${CMAKE_CURRENT_SOURCE_DIR}/Registry.cpp
33 ${CMAKE_CURRENT_SOURCE_DIR}/Reply.cpp35 ${CMAKE_CURRENT_SOURCE_DIR}/Reply.cpp
34 ${CMAKE_CURRENT_SOURCE_DIR}/Result.cpp36 ${CMAKE_CURRENT_SOURCE_DIR}/Result.cpp
3537
=== modified file 'src/scopes/OptionSelectorFilter.cpp'
--- src/scopes/OptionSelectorFilter.cpp 2014-05-08 16:10:18 +0000
+++ src/scopes/OptionSelectorFilter.cpp 2014-05-21 14:02:43 +0000
@@ -30,9 +30,9 @@
30{30{
31}31}
3232
33OptionSelectorFilter::SPtr OptionSelectorFilter::create(std::string const& id, std::string const& label, bool multi_select)33OptionSelectorFilter::UPtr OptionSelectorFilter::create(std::string const& id, std::string const& label, bool multi_select)
34{34{
35 return std::shared_ptr<OptionSelectorFilter>(new OptionSelectorFilter(new internal::OptionSelectorFilterImpl(id, label, multi_select)));35 return std::unique_ptr<OptionSelectorFilter>(new OptionSelectorFilter(new internal::OptionSelectorFilterImpl(id, label, multi_select)));
36}36}
3737
38std::string OptionSelectorFilter::label() const38std::string OptionSelectorFilter::label() const
@@ -55,6 +55,11 @@
55 return fwd()->options();55 return fwd()->options();
56}56}
5757
58bool OptionSelectorFilter::has_active_option(FilterState const& filter_state) const
59{
60 return fwd()->has_active_option(filter_state);
61}
62
58std::set<FilterOption::SCPtr> OptionSelectorFilter::active_options(FilterState const& filter_state) const63std::set<FilterOption::SCPtr> OptionSelectorFilter::active_options(FilterState const& filter_state) const
59{64{
60 return fwd()->active_options(filter_state);65 return fwd()->active_options(filter_state);
6166
=== added file 'src/scopes/RadioButtonsFilter.cpp'
--- src/scopes/RadioButtonsFilter.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/RadioButtonsFilter.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17*/
18
19#include <unity/scopes/RadioButtonsFilter.h>
20#include <unity/scopes/internal/RadioButtonsFilterImpl.h>
21
22namespace unity
23{
24
25namespace scopes
26{
27
28RadioButtonsFilter::RadioButtonsFilter(internal::RadioButtonsFilterImpl *impl)
29 : FilterBase(impl)
30{
31}
32
33FilterOption::SCPtr RadioButtonsFilter::add_option(std::string const& id, std::string const& label)
34{
35 return fwd()->add_option(id, label);
36}
37
38std::string RadioButtonsFilter::label() const
39{
40 return fwd()->label();
41}
42
43FilterOption::SCPtr RadioButtonsFilter::active_option(FilterState const& filter_state) const
44{
45 return fwd()->active_option(filter_state);
46}
47
48bool RadioButtonsFilter::has_active_option(FilterState const& filter_state) const
49{
50 return fwd()->has_active_option(filter_state);
51}
52
53std::list<FilterOption::SCPtr> RadioButtonsFilter::options() const
54{
55 return fwd()->options();
56}
57
58void RadioButtonsFilter::update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const
59{
60 fwd()->update_state(filter_state, option, active);
61}
62
63void RadioButtonsFilter::update_state(FilterState& filter_state, std::string const& filter_id, std::string const& option_id, bool value)
64{
65 internal::RadioButtonsFilterImpl::update_state(filter_state, filter_id, option_id, value);
66}
67
68RadioButtonsFilter::UPtr RadioButtonsFilter::create(std::string const& id, std::string const& label)
69{
70 return std::unique_ptr<RadioButtonsFilter>(new RadioButtonsFilter(new internal::RadioButtonsFilterImpl(id, label)));
71}
72
73internal::RadioButtonsFilterImpl* RadioButtonsFilter::fwd() const
74{
75 return dynamic_cast<internal::RadioButtonsFilterImpl*>(p.get());
76}
77
78} // namespace scopes
79
80} // namespace unity
081
=== added file 'src/scopes/RatingFilter.cpp'
--- src/scopes/RatingFilter.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/RatingFilter.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17*/
18
19#include <unity/scopes/RatingFilter.h>
20#include <unity/scopes/internal/RatingFilterImpl.h>
21
22namespace unity
23{
24
25namespace scopes
26{
27
28RatingFilter::RatingFilter(internal::RatingFilterImpl *impl)
29 : FilterBase(impl)
30{
31}
32
33RatingFilter::UPtr RatingFilter::create(std::string const& id, std::string const& label, int top_rating)
34{
35 return std::unique_ptr<RatingFilter>(new RatingFilter(new internal::RatingFilterImpl(id, label, top_rating)));
36}
37
38RatingFilter::UPtr RatingFilter::create(std::string const& id, std::string const& label)
39{
40 return std::unique_ptr<RatingFilter>(new RatingFilter(new internal::RatingFilterImpl(id, label)));
41}
42
43FilterOption::SCPtr RatingFilter::add_option(std::string const& id, std::string const& label)
44{
45 return fwd()->add_option(id, label);
46}
47
48void RatingFilter::set_on_icon(std::string const& on_icon)
49{
50 fwd()->set_on_icon(on_icon);
51}
52
53void RatingFilter::set_off_icon(std::string const& off_icon)
54{
55 fwd()->set_off_icon(off_icon);
56}
57
58std::string RatingFilter::label() const
59{
60 return fwd()->label();
61}
62
63std::list<FilterOption::SCPtr> RatingFilter::options() const
64{
65 return fwd()->options();
66}
67
68std::string RatingFilter::on_icon() const
69{
70 return fwd()->on_icon();
71}
72
73std::string RatingFilter::off_icon() const
74{
75 return fwd()->off_icon();
76}
77
78FilterOption::SCPtr RatingFilter::active_rating(FilterState const& filter_state) const
79{
80 return fwd()->active_option(filter_state);
81}
82
83bool RatingFilter::has_active_rating(FilterState const& filter_state) const
84{
85 return fwd()->has_active_option(filter_state);
86}
87
88void RatingFilter::update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const
89{
90 fwd()->update_state(filter_state, option, active);
91}
92
93void RatingFilter::update_state(FilterState& filter_state, std::string const& filter_id, std::string const& option_id, bool value)
94{
95 internal::RatingFilterImpl::update_state(filter_state, filter_id, option_id, value);
96}
97
98internal::RatingFilterImpl* RatingFilter::fwd() const
99{
100 return dynamic_cast<internal::RatingFilterImpl*>(p.get());
101}
102
103} // namespace scopes
104
105} // namespace unity
0106
=== modified file 'src/scopes/internal/CMakeLists.txt'
--- src/scopes/internal/CMakeLists.txt 2014-05-08 14:49:31 +0000
+++ src/scopes/internal/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -29,12 +29,14 @@
29 ${CMAKE_CURRENT_SOURCE_DIR}/MiddlewareBase.cpp29 ${CMAKE_CURRENT_SOURCE_DIR}/MiddlewareBase.cpp
30 ${CMAKE_CURRENT_SOURCE_DIR}/MiddlewareFactory.cpp30 ${CMAKE_CURRENT_SOURCE_DIR}/MiddlewareFactory.cpp
31 ${CMAKE_CURRENT_SOURCE_DIR}/MWObject.cpp31 ${CMAKE_CURRENT_SOURCE_DIR}/MWObject.cpp
32 ${CMAKE_CURRENT_SOURCE_DIR}/MWPublisher.cpp
32 ${CMAKE_CURRENT_SOURCE_DIR}/MWQuery.cpp33 ${CMAKE_CURRENT_SOURCE_DIR}/MWQuery.cpp
33 ${CMAKE_CURRENT_SOURCE_DIR}/MWQueryCtrl.cpp34 ${CMAKE_CURRENT_SOURCE_DIR}/MWQueryCtrl.cpp
34 ${CMAKE_CURRENT_SOURCE_DIR}/MWRegistry.cpp35 ${CMAKE_CURRENT_SOURCE_DIR}/MWRegistry.cpp
35 ${CMAKE_CURRENT_SOURCE_DIR}/MWReply.cpp36 ${CMAKE_CURRENT_SOURCE_DIR}/MWReply.cpp
36 ${CMAKE_CURRENT_SOURCE_DIR}/MWScope.cpp37 ${CMAKE_CURRENT_SOURCE_DIR}/MWScope.cpp
37 ${CMAKE_CURRENT_SOURCE_DIR}/MWStateReceiver.cpp38 ${CMAKE_CURRENT_SOURCE_DIR}/MWStateReceiver.cpp
39 ${CMAKE_CURRENT_SOURCE_DIR}/MWSubscriber.cpp
38 ${CMAKE_CURRENT_SOURCE_DIR}/ObjectImpl.cpp40 ${CMAKE_CURRENT_SOURCE_DIR}/ObjectImpl.cpp
39 ${CMAKE_CURRENT_SOURCE_DIR}/OptionSelectorFilterImpl.cpp41 ${CMAKE_CURRENT_SOURCE_DIR}/OptionSelectorFilterImpl.cpp
40 ${CMAKE_CURRENT_SOURCE_DIR}/PreviewQueryObject.cpp42 ${CMAKE_CURRENT_SOURCE_DIR}/PreviewQueryObject.cpp
@@ -46,6 +48,8 @@
46 ${CMAKE_CURRENT_SOURCE_DIR}/QueryCtrlObject.cpp48 ${CMAKE_CURRENT_SOURCE_DIR}/QueryCtrlObject.cpp
47 ${CMAKE_CURRENT_SOURCE_DIR}/QueryMetadataImpl.cpp49 ${CMAKE_CURRENT_SOURCE_DIR}/QueryMetadataImpl.cpp
48 ${CMAKE_CURRENT_SOURCE_DIR}/QueryObject.cpp50 ${CMAKE_CURRENT_SOURCE_DIR}/QueryObject.cpp
51 ${CMAKE_CURRENT_SOURCE_DIR}/RadioButtonsFilterImpl.cpp
52 ${CMAKE_CURRENT_SOURCE_DIR}/RatingFilterImpl.cpp
49 ${CMAKE_CURRENT_SOURCE_DIR}/RangeInputFilterImpl.cpp53 ${CMAKE_CURRENT_SOURCE_DIR}/RangeInputFilterImpl.cpp
50 ${CMAKE_CURRENT_SOURCE_DIR}/Reaper.cpp54 ${CMAKE_CURRENT_SOURCE_DIR}/Reaper.cpp
51 ${CMAKE_CURRENT_SOURCE_DIR}/RegistryConfig.cpp55 ${CMAKE_CURRENT_SOURCE_DIR}/RegistryConfig.cpp
5256
=== modified file 'src/scopes/internal/FilterBaseImpl.cpp'
--- src/scopes/internal/FilterBaseImpl.cpp 2014-05-15 22:32:00 +0000
+++ src/scopes/internal/FilterBaseImpl.cpp 2014-05-21 14:02:43 +0000
@@ -22,6 +22,8 @@
22#include <unity/scopes/internal/Utils.h>22#include <unity/scopes/internal/Utils.h>
23#include <unity/scopes/internal/OptionSelectorFilterImpl.h>23#include <unity/scopes/internal/OptionSelectorFilterImpl.h>
24#include <unity/scopes/internal/RangeInputFilterImpl.h>24#include <unity/scopes/internal/RangeInputFilterImpl.h>
25#include <unity/scopes/internal/RadioButtonsFilterImpl.h>
26#include <unity/scopes/internal/RatingFilterImpl.h>
25#include <unity/UnityExceptions.h>27#include <unity/UnityExceptions.h>
26#include <sstream>28#include <sstream>
2729
@@ -117,6 +119,14 @@
117 {119 {
118 return RangeInputFilterImpl::create(var);120 return RangeInputFilterImpl::create(var);
119 }121 }
122 if (ftype == "radio_buttons")
123 {
124 return RadioButtonsFilterImpl::create(var);
125 }
126 if (ftype == "rating")
127 {
128 return RatingFilterImpl::create(var);
129 }
120 throw unity::LogicException("Unknown filter type: " + ftype);130 throw unity::LogicException("Unknown filter type: " + ftype);
121 }131 }
122 throw unity::LogicException("FilterBase: Missing 'filter_type'");132 throw unity::LogicException("FilterBase: Missing 'filter_type'");
@@ -142,6 +152,56 @@
142 return filters;152 return filters;
143}153}
144154
155void FilterBaseImpl::validate_filters(Filters const& filters)
156{
157 for (auto const& f: filters)
158 {
159 if (f == nullptr)
160 {
161 throw unity::LogicException("FilterBaseImpl::validate_filters(): invalid null filter pointer");
162 }
163 {
164 OptionSelectorFilter::SCPtr optsel = std::dynamic_pointer_cast<OptionSelectorFilter const>(f);
165 if (optsel)
166 {
167 if (optsel->options().size() == 0)
168 {
169 std::stringstream err;
170 err << "FilterBaseImpl::validate_filters(): invalid empty OptionSelectorFilter '" << f->id() << "'";
171 throw unity::LogicException(err.str());
172 }
173 continue;
174 }
175 }
176 {
177 RatingFilter::SCPtr rating = std::dynamic_pointer_cast<RatingFilter const>(f);
178 if (rating)
179 {
180 if (rating->options().size() == 0)
181 {
182 std::stringstream err;
183 err << "FilterBaseImpl::validate_filters(): invalid empty RatingFilter '" << f->id() << "'";
184 throw unity::LogicException(err.str());
185 }
186 continue;
187 }
188 }
189 {
190 RadioButtonsFilter::SCPtr radiobtn = std::dynamic_pointer_cast<RadioButtonsFilter const>(f);
191 if (radiobtn)
192 {
193 if (radiobtn->options().size() == 0)
194 {
195 std::stringstream err;
196 err << "FilterBaseImpl::validate_filters(): invalid empty RadioButtonsFilter '" << f->id() << "'";
197 throw unity::LogicException(err.str());
198 }
199 continue;
200 }
201 }
202 }
203}
204
145} // namespace internal205} // namespace internal
146206
147} // namespace scopes207} // namespace scopes
148208
=== added file 'src/scopes/internal/MWPublisher.cpp'
--- src/scopes/internal/MWPublisher.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/internal/MWPublisher.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#include <unity/scopes/internal/MWPublisher.h>
20
21namespace unity
22{
23
24namespace scopes
25{
26
27namespace internal
28{
29
30MWPublisher::MWPublisher()
31{
32}
33
34MWPublisher::~MWPublisher()
35{
36}
37
38} // namespace internal
39
40} // namespace scopes
41
42} // namespace unity
043
=== added file 'src/scopes/internal/MWSubscriber.cpp'
--- src/scopes/internal/MWSubscriber.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/internal/MWSubscriber.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#include <unity/scopes/internal/MWSubscriber.h>
20
21namespace unity
22{
23
24namespace scopes
25{
26
27namespace internal
28{
29
30MWSubscriber::MWSubscriber()
31{
32}
33
34MWSubscriber::~MWSubscriber()
35{
36}
37
38} // namespace internal
39
40} // namespace scopes
41
42} // namespace unity
043
=== modified file 'src/scopes/internal/OptionSelectorFilterImpl.cpp'
--- src/scopes/internal/OptionSelectorFilterImpl.cpp 2014-05-15 03:23:43 +0000
+++ src/scopes/internal/OptionSelectorFilterImpl.cpp 2014-05-21 14:02:43 +0000
@@ -131,6 +131,11 @@
131 }131 }
132}132}
133133
134int OptionSelectorFilterImpl::num_of_options() const
135{
136 return options_.size();
137}
138
134std::list<FilterOption::SCPtr> OptionSelectorFilterImpl::options() const139std::list<FilterOption::SCPtr> OptionSelectorFilterImpl::options() const
135{140{
136 return options_;141 return options_;
@@ -170,6 +175,33 @@
170 return opts;175 return opts;
171}176}
172177
178bool OptionSelectorFilterImpl::has_active_option(FilterState const& filter_state) const
179{
180 if (filter_state.has_filter(id()))
181 {
182 try
183 {
184 auto const var = FilterBaseImpl::get(filter_state, id()).get_array(); // this can throw if of different type
185
186 for (auto const& idvar: var)
187 {
188 auto const opt_id = idvar.get_string();
189 for (auto const& opt: options_)
190 {
191 if (opt_id == opt->id())
192 {
193 return true;
194 }
195 }
196 }
197 }
198 catch (...)
199 {
200 }
201 }
202 return false;
203}
204
173void OptionSelectorFilterImpl::update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const205void OptionSelectorFilterImpl::update_state(FilterState& filter_state, FilterOption::SCPtr option, bool active) const
174{206{
175 auto const oid(option->id());207 auto const oid(option->id());
176208
=== added file 'src/scopes/internal/RadioButtonsFilterImpl.cpp'
--- src/scopes/internal/RadioButtonsFilterImpl.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/internal/RadioButtonsFilterImpl.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,81 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17*/
18
19#include <unity/scopes/internal/RadioButtonsFilterImpl.h>
20#include <unity/scopes/FilterState.h>
21#include <sstream>
22#include <unity/UnityExceptions.h>
23
24namespace unity
25{
26
27namespace scopes
28{
29
30namespace internal
31{
32
33RadioButtonsFilterImpl::RadioButtonsFilterImpl(std::string const& id, std::string const& label)
34 : OptionSelectorFilterImpl(id, label, false)
35{
36}
37
38RadioButtonsFilterImpl::RadioButtonsFilterImpl(VariantMap const& var)
39 : OptionSelectorFilterImpl(var)
40{
41 if (multi_select()) // this should never happen unless a client bypasses the api
42 {
43 std::stringstream err;
44 err << "RadioButtonsFilterImpl(): invalid filter data, multi selection is not available with RadioButtonsFilter, filter id '" << id() << "'";
45 throw unity::LogicException(err.str());
46 }
47}
48
49FilterOption::SCPtr RadioButtonsFilterImpl::active_option(FilterState const& filter_state) const
50{
51 auto const active = active_options(filter_state);
52 if (active.size() > 1) // this should never happen unless a client bypasses the api
53 {
54 std::stringstream err;
55 err << "RadioButtonsFilterImpl::active_option(): internal error, more than one button active, filter id '" << id() << "'";
56 throw unity::LogicException(err.str());
57 }
58
59 if (active.size() == 1)
60 {
61 return *active.begin();
62 }
63
64 return nullptr;
65}
66
67std::string RadioButtonsFilterImpl::filter_type() const
68{
69 return "radio_buttons";
70}
71
72RadioButtonsFilter::SPtr RadioButtonsFilterImpl::create(VariantMap const& var)
73{
74 return std::shared_ptr<RadioButtonsFilter>(new RadioButtonsFilter(new RadioButtonsFilterImpl(var)));
75}
76
77} // namespace internal
78
79} // namespace scopes
80
81} // namespace unity
082
=== added file 'src/scopes/internal/RatingFilterImpl.cpp'
--- src/scopes/internal/RatingFilterImpl.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/internal/RatingFilterImpl.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,109 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17*/
18
19#include <unity/scopes/RatingFilter.h>
20#include <unity/scopes/internal/RatingFilterImpl.h>
21#include <unity/UnityExceptions.h>
22#include <sstream>
23
24namespace unity
25{
26
27namespace scopes
28{
29
30namespace internal
31{
32
33RatingFilterImpl::RatingFilterImpl(std::string const& id, std::string const& label)
34 : RadioButtonsFilterImpl(id, label)
35{
36}
37
38RatingFilterImpl::RatingFilterImpl(std::string const& id, std::string const& label, int top_rating)
39 : RadioButtonsFilterImpl(id, label)
40{
41 if (top_rating < 2 || top_rating > max_rating)
42 {
43 std::stringstream err;
44 err << "RatingFilterImpl(): top_rating " << top_rating << " outside of allowed range for filter '" << id << "'";
45 throw unity::LogicException(err.str());
46 }
47
48 // create rating options from 1..top_rating range, e.g. "1+", "2+", ..., "5".
49 for (int i = 1; i <= top_rating; i++)
50 {
51 auto const num = std::to_string(i);
52 RadioButtonsFilterImpl::add_option(num, i < top_rating ? num + "+" : num);
53 }
54}
55
56RatingFilterImpl::RatingFilterImpl(VariantMap const& var)
57 : RadioButtonsFilterImpl(var)
58{
59}
60
61FilterOption::SCPtr RatingFilterImpl::add_option(std::string const& id, std::string const& label)
62{
63 if (num_of_options() < max_rating)
64 {
65 return RadioButtonsFilterImpl::add_option(id, label);
66 }
67 else
68 {
69 std::stringstream err;
70 err << "RatingFilterImpl::add_option(): maximum number of rating options reached for filter '" << id << "'";
71 throw unity::LogicException(err.str());
72 }
73}
74
75void RatingFilterImpl::set_on_icon(std::string const& on_icon)
76{
77 on_icon_ = on_icon;
78}
79
80void RatingFilterImpl::set_off_icon(std::string const& off_icon)
81{
82 off_icon_ = off_icon;
83}
84
85std::string RatingFilterImpl::on_icon() const
86{
87 return on_icon_;
88}
89
90std::string RatingFilterImpl::off_icon() const
91{
92 return off_icon_;
93}
94
95RatingFilter::SPtr RatingFilterImpl::create(VariantMap const& var)
96{
97 return std::shared_ptr<RatingFilter>(new RatingFilter(new RatingFilterImpl(var)));
98}
99
100std::string RatingFilterImpl::filter_type() const
101{
102 return "rating";
103}
104
105} // namespace internal
106
107} // namespace scopes
108
109} // namespace unity
0110
=== modified file 'src/scopes/internal/SearchReplyImpl.cpp'
--- src/scopes/internal/SearchReplyImpl.cpp 2014-04-29 11:20:57 +0000
+++ src/scopes/internal/SearchReplyImpl.cpp 2014-05-21 14:02:43 +0000
@@ -62,7 +62,7 @@
62 }62 }
63 catch (unity::LogicException const &e)63 catch (unity::LogicException const &e)
64 {64 {
65 throw unity::LogicException("Reply::register_departments(): Failed to validate departments");65 throw unity::LogicException("SearchReplyImpl::register_departments(): Failed to validate departments");
66 }66 }
6767
68 ReplyImpl::push(internal::DepartmentImpl::serialize_departments(departments, current_department_id)); // ignore return value?68 ReplyImpl::push(internal::DepartmentImpl::serialize_departments(departments, current_department_id)); // ignore return value?
@@ -129,6 +129,16 @@
129129
130bool SearchReplyImpl::push(unity::scopes::Filters const& filters, unity::scopes::FilterState const& filter_state)130bool SearchReplyImpl::push(unity::scopes::Filters const& filters, unity::scopes::FilterState const& filter_state)
131{131{
132 // basic consistency check
133 try
134 {
135 internal::FilterBaseImpl::validate_filters(filters);
136 }
137 catch (unity::LogicException const &e)
138 {
139 throw unity::LogicException("SearchReplyImpl::push(): Failed to validate filters");
140 }
141
132 VariantMap var;142 VariantMap var;
133 var["filters"] = internal::FilterBaseImpl::serialize_filters(filters);143 var["filters"] = internal::FilterBaseImpl::serialize_filters(filters);
134 var["filter_state"] = filter_state.serialize();144 var["filter_state"] = filter_state.serialize();
135145
=== modified file 'src/scopes/internal/smartscopes/SSRegistryObject.cpp'
--- src/scopes/internal/smartscopes/SSRegistryObject.cpp 2014-05-09 08:20:57 +0000
+++ src/scopes/internal/smartscopes/SSRegistryObject.cpp 2014-05-21 14:02:43 +0000
@@ -232,6 +232,11 @@
232 metadata->set_art(*scope.art);232 metadata->set_art(*scope.art);
233 }233 }
234234
235 if (scope.appearance)
236 {
237 metadata->set_appearance_attributes(*scope.appearance);
238 }
239
235 metadata->set_invisible(scope.invisible);240 metadata->set_invisible(scope.invisible);
236241
237 ScopeProxy proxy = ScopeImpl::create(middleware_->create_scope_proxy(scope.id, ss_scope_endpoint_),242 ScopeProxy proxy = ScopeImpl::create(middleware_->create_scope_proxy(scope.id, ss_scope_endpoint_),
238243
=== modified file 'src/scopes/internal/smartscopes/SmartScopesClient.cpp'
--- src/scopes/internal/smartscopes/SmartScopesClient.cpp 2014-05-09 09:56:09 +0000
+++ src/scopes/internal/smartscopes/SmartScopesClient.cpp 2014-05-21 14:02:43 +0000
@@ -259,6 +259,11 @@
259 scope.art.reset(new std::string(child_node->get_node("art")->as_string()));259 scope.art.reset(new std::string(child_node->get_node("art")->as_string()));
260 }260 }
261261
262 if (child_node->has_node("appearance"))
263 {
264 scope.appearance.reset(new VariantMap(child_node->get_node("appearance")->to_variant().get_dict()));
265 }
266
262 scope.invisible = child_node->has_node("invisible") ? child_node->get_node("invisible")->as_bool() : false;267 scope.invisible = child_node->has_node("invisible") ? child_node->get_node("invisible")->as_bool() : false;
263268
264 remote_scopes.push_back(scope);269 remote_scopes.push_back(scope);
265270
=== modified file 'src/scopes/internal/zmq_middleware/CMakeLists.txt'
--- src/scopes/internal/zmq_middleware/CMakeLists.txt 2014-04-15 00:30:07 +0000
+++ src/scopes/internal/zmq_middleware/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -21,6 +21,7 @@
21 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqMiddleware.cpp21 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqMiddleware.cpp
22 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqException.cpp22 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqException.cpp
23 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqObject.cpp23 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqObject.cpp
24 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqPublisher.cpp
24 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqQuery.cpp25 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqQuery.cpp
25 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqQueryCtrl.cpp26 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqQueryCtrl.cpp
26 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqReceiver.cpp27 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqReceiver.cpp
@@ -29,5 +30,6 @@
29 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqScope.cpp30 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqScope.cpp
30 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqSender.cpp31 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqSender.cpp
31 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqStateReceiver.cpp32 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqStateReceiver.cpp
33 ${CMAKE_CURRENT_SOURCE_DIR}/ZmqSubscriber.cpp
32)34)
33set(UNITY_SCOPES_LIB_SRC ${UNITY_SCOPES_LIB_SRC} ${SRC} PARENT_SCOPE)35set(UNITY_SCOPES_LIB_SRC ${UNITY_SCOPES_LIB_SRC} ${SRC} PARENT_SCOPE)
3436
=== modified file 'src/scopes/internal/zmq_middleware/ObjectAdapter.cpp'
--- src/scopes/internal/zmq_middleware/ObjectAdapter.cpp 2014-05-14 04:50:14 +0000
+++ src/scopes/internal/zmq_middleware/ObjectAdapter.cpp 2014-05-21 14:02:43 +0000
@@ -494,47 +494,6 @@
494 }494 }
495}495}
496496
497// For the ipc transport, zmq permits more than one server to bind to the same endpoint.
498// If a server binds to an endpoint while another server is using that endpoint, the
499// second server silently "steals" the endpoint from the previous server, so all
500// connects after that point go to the new server, while connects that happened earlier
501// go to the old server. This is meant as a fail-over feature, and cannot be disabled.
502//
503// We don't want this and need an error if two servers try to use the same endpoint.
504// Hacky solution: we check whether it's possible to successfully connect to the
505// endpoint. If so, a server is still running there, and we throw. This has a
506// small race because a second server may connect after the check, but before
507// the bind. But, in practice, that's good enough for our purposes.
508
509void ObjectAdapter::safe_bind(zmqpp::socket& s, string const& endpoint)
510{
511 const std::string transport_prefix = "ipc://";
512 if (endpoint.substr(0, transport_prefix.size()) == transport_prefix)
513 {
514 string path = endpoint.substr(transport_prefix.size());
515 struct sockaddr_un addr;
516 memset(&addr, 0, sizeof(addr));
517 addr.sun_family = AF_UNIX;
518 strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path) - 1);
519 int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
520 if (fd == -1)
521 {
522 // LCOV_EXCL_START
523 throw MiddlewareException("ObjectAdapter: broker thread failure (adapter: " + name_ + "): " +
524 "cannot create socket: " + strerror(errno));
525 // LCOV_EXCL_STOP
526 }
527 util::ResourcePtr<int, decltype(&::close)> close_guard(fd, ::close);
528 if (::connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0)
529 {
530 // Connect succeeded, so another server is using the socket already.
531 throw MiddlewareException("ObjectAdapter: broker thread failure (adapter: " + name_ + "): " +
532 "address in use: " + endpoint);
533 }
534 }
535 s.bind(endpoint);
536}
537
538shared_ptr<ServantBase> ObjectAdapter::find_servant(string const& id, string const& category)497shared_ptr<ServantBase> ObjectAdapter::find_servant(string const& id, string const& category)
539{498{
540 shared_ptr<ServantBase> servant = find(id);499 shared_ptr<ServantBase> servant = find(id);
541500
=== modified file 'src/scopes/internal/zmq_middleware/Util.cpp'
--- src/scopes/internal/zmq_middleware/Util.cpp 2014-01-28 06:34:03 +0000
+++ src/scopes/internal/zmq_middleware/Util.cpp 2014-05-21 14:02:43 +0000
@@ -19,7 +19,10 @@
19#include <unity/scopes/internal/zmq_middleware/Util.h>19#include <unity/scopes/internal/zmq_middleware/Util.h>
2020
21#include <unity/scopes/ScopeExceptions.h>21#include <unity/scopes/ScopeExceptions.h>
22#include <unity/util/ResourcePtr.h>
2223
24#include <unistd.h>
25#include <sys/socket.h>
23#include <sys/un.h>26#include <sys/un.h>
2427
25using namespace std;28using namespace std;
@@ -55,6 +58,45 @@
55 }58 }
56}59}
5760
61// For the ipc transport, zmq permits more than one server to bind to the same endpoint.
62// If a server binds to an endpoint while another server is using that endpoint, the
63// second server silently "steals" the endpoint from the previous server, so all
64// connects after that point go to the new server, while connects that happened earlier
65// go to the old server. This is meant as a fail-over feature, and cannot be disabled.
66//
67// We don't want this and need an error if two servers try to use the same endpoint.
68// Hacky solution: we check whether it's possible to successfully connect to the
69// endpoint. If so, a server is still running there, and we throw. This has a
70// small race because a second server may connect after the check, but before
71// the bind. But, in practice, that's good enough for our purposes.
72
73void safe_bind(zmqpp::socket& s, string const& endpoint)
74{
75 const std::string transport_prefix = "ipc://";
76 if (endpoint.substr(0, transport_prefix.size()) == transport_prefix)
77 {
78 string path = endpoint.substr(transport_prefix.size());
79 struct sockaddr_un addr;
80 memset(&addr, 0, sizeof(addr));
81 addr.sun_family = AF_UNIX;
82 strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path) - 1);
83 int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
84 if (fd == -1)
85 {
86 // LCOV_EXCL_START
87 throw MiddlewareException("safe_bind(): cannot create socket: " + std::string(strerror(errno)));
88 // LCOV_EXCL_STOP
89 }
90 util::ResourcePtr<int, decltype(&::close)> close_guard(fd, ::close);
91 if (::connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0)
92 {
93 // Connect succeeded, so another server is using the socket already.
94 throw MiddlewareException("safe_bind(): address in use: " + endpoint);
95 }
96 }
97 s.bind(endpoint);
98}
99
58} // namespace zmq_middleware100} // namespace zmq_middleware
59101
60} // namespace internal102} // namespace internal
61103
=== modified file 'src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp'
--- src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp 2014-05-15 08:12:19 +0000
+++ src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp 2014-05-21 14:02:43 +0000
@@ -29,12 +29,14 @@
29#include <unity/scopes/internal/zmq_middleware/ReplyI.h>29#include <unity/scopes/internal/zmq_middleware/ReplyI.h>
30#include <unity/scopes/internal/zmq_middleware/ScopeI.h>30#include <unity/scopes/internal/zmq_middleware/ScopeI.h>
31#include <unity/scopes/internal/zmq_middleware/StateReceiverI.h>31#include <unity/scopes/internal/zmq_middleware/StateReceiverI.h>
32#include <unity/scopes/internal/zmq_middleware/ZmqPublisher.h>
32#include <unity/scopes/internal/zmq_middleware/ZmqQuery.h>33#include <unity/scopes/internal/zmq_middleware/ZmqQuery.h>
33#include <unity/scopes/internal/zmq_middleware/ZmqQueryCtrl.h>34#include <unity/scopes/internal/zmq_middleware/ZmqQueryCtrl.h>
34#include <unity/scopes/internal/zmq_middleware/ZmqRegistry.h>35#include <unity/scopes/internal/zmq_middleware/ZmqRegistry.h>
35#include <unity/scopes/internal/zmq_middleware/ZmqReply.h>36#include <unity/scopes/internal/zmq_middleware/ZmqReply.h>
36#include <unity/scopes/internal/zmq_middleware/ZmqScope.h>37#include <unity/scopes/internal/zmq_middleware/ZmqScope.h>
37#include <unity/scopes/internal/zmq_middleware/ZmqStateReceiver.h>38#include <unity/scopes/internal/zmq_middleware/ZmqStateReceiver.h>
39#include <unity/scopes/internal/zmq_middleware/ZmqSubscriber.h>
38#include <unity/scopes/internal/zmq_middleware/RethrowException.h>40#include <unity/scopes/internal/zmq_middleware/RethrowException.h>
39#include <unity/scopes/ScopeExceptions.h>41#include <unity/scopes/ScopeExceptions.h>
40#include <unity/UnityExceptions.h>42#include <unity/UnityExceptions.h>
@@ -59,10 +61,11 @@
59namespace61namespace
60{62{
6163
62char const* query_suffix = "-q"; // Appended to server_name_ to create query adapter name64char const* query_suffix = "-q"; // Appended to server_name_ to create query adapter name
63char const* ctrl_suffix = "-c"; // Appended to server_name_ to create control adapter name65char const* ctrl_suffix = "-c"; // Appended to server_name_ to create control adapter name
64char const* reply_suffix = "-r"; // Appended to server_name_ to create reply adapter name66char const* reply_suffix = "-r"; // Appended to server_name_ to create reply adapter name
65char const* state_suffix = "-s"; // Appended to server_name_ to create state adapter name67char const* state_suffix = "-s"; // Appended to server_name_ to create state adapter name
68char const* publisher_suffix = "-p"; // Appended to publisher_id to create a publisher endpoint
6669
67char const* query_category = "Query"; // query adapter category name70char const* query_category = "Query"; // query adapter category name
68char const* ctrl_category = "QueryCtrl"; // control adapter category name71char const* ctrl_category = "QueryCtrl"; // control adapter category name
@@ -657,6 +660,16 @@
657 return proxy;660 return proxy;
658}661}
659662
663MWPublisher::UPtr ZmqMiddleware::create_publisher(std::string const& publisher_id)
664{
665 return MWPublisher::UPtr(new ZmqPublisher(&context_, publisher_id + publisher_suffix, config_.public_dir()));
666}
667
668MWSubscriber::UPtr ZmqMiddleware::create_subscriber(std::string const& publisher_id, std::string const& topic)
669{
670 return MWSubscriber::UPtr(new ZmqSubscriber(&context_, publisher_id + publisher_suffix, config_.public_dir(), topic));
671}
672
660std::string ZmqMiddleware::get_scope_endpoint()673std::string ZmqMiddleware::get_scope_endpoint()
661{674{
662 return "ipc://" + config_.private_dir() + "/" + server_name_;675 return "ipc://" + config_.private_dir() + "/" + server_name_;
663676
=== added file 'src/scopes/internal/zmq_middleware/ZmqPublisher.cpp'
--- src/scopes/internal/zmq_middleware/ZmqPublisher.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/internal/zmq_middleware/ZmqPublisher.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,157 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#include <unity/scopes/internal/zmq_middleware/ZmqPublisher.h>
20
21#include <unity/scopes/internal/zmq_middleware/Util.h>
22#include <unity/scopes/ScopeExceptions.h>
23#include <unity/util/ResourcePtr.h>
24
25#include <unistd.h>
26#include <sys/socket.h>
27#include <sys/un.h>
28
29namespace unity
30{
31
32namespace scopes
33{
34
35namespace internal
36{
37
38namespace zmq_middleware
39{
40
41ZmqPublisher::ZmqPublisher(zmqpp::context* context, std::string const& publisher_id,
42 std::string const& endpoint_dir)
43 : context_(context)
44 , endpoint_("ipc://" + endpoint_dir + "/" + publisher_id)
45 , thread_state_(NotRunning)
46 , thread_exception_(nullptr)
47{
48 // Validate publisher_id
49 if (publisher_id.find('/') != std::string::npos)
50 {
51 throw MiddlewareException("ZmqPublisher(): A publisher cannot contain a '/' in its id");
52 }
53
54 // Start the publisher thread
55 thread_ = std::thread(&ZmqPublisher::publisher_thread, this);
56
57 std::unique_lock<std::mutex> lock(mutex_);
58 cond_.wait(lock, [this] { return thread_state_ == Running || thread_state_ == Failed; });
59
60 if (thread_state_ == Failed)
61 {
62 if (thread_.joinable())
63 {
64 thread_.join();
65 }
66 try
67 {
68 std::rethrow_exception(thread_exception_);
69 }
70 catch (...)
71 {
72 throw MiddlewareException("ZmqPublisher(): publisher thread failed to start (endpoint: " +
73 endpoint_ + ")");
74 }
75 }
76}
77
78ZmqPublisher::~ZmqPublisher()
79{
80 {
81 std::lock_guard<std::mutex> lock(mutex_);
82 thread_state_ = Stopping;
83 cond_.notify_all();
84 }
85
86 if (thread_.joinable())
87 {
88 thread_.join();
89 }
90}
91
92std::string ZmqPublisher::endpoint() const
93{
94 return endpoint_;
95}
96
97void ZmqPublisher::send_message(std::string const& message, std::string const& topic)
98{
99 std::lock_guard<std::mutex> lock(mutex_);
100
101 // Write message in the format: "<topic>:<message>"
102 message_queue_.push(topic + ':' + message);
103 cond_.notify_all();
104}
105
106void ZmqPublisher::publisher_thread()
107{
108 try
109 {
110 // Create the publisher socket
111 zmqpp::socket pub_socket(zmqpp::socket(*context_, zmqpp::socket_type::publish));
112 pub_socket.set(zmqpp::socket_option::linger, 5000);
113 safe_bind(pub_socket, endpoint_);
114
115 // Notify constructor that the thread is now running
116 std::unique_lock<std::mutex> lock(mutex_);
117 thread_state_ = Running;
118 cond_.notify_all();
119
120 // Wait for send_message or stop
121 while (true)
122 {
123 // mutex_ unlocked
124 cond_.wait(lock, [this] { return thread_state_ == Stopping || !message_queue_.empty(); });
125 // mutex_ locked
126
127 // Flush out the message queue before stopping the thread
128 if (!message_queue_.empty())
129 {
130 pub_socket.send(message_queue_.front());
131 message_queue_.pop();
132 }
133 else if (thread_state_ == Stopping)
134 {
135 break;
136 }
137 }
138
139 // Clean up
140 pub_socket.close();
141 }
142 catch (...)
143 {
144 std::lock_guard<std::mutex> lock(mutex_);
145 thread_exception_ = std::current_exception();
146 thread_state_ = Failed;
147 cond_.notify_all();
148 }
149}
150
151} // namespace zmq_middleware
152
153} // namespace internal
154
155} // namespace scopes
156
157} // namespace unity
0158
=== added file 'src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp'
--- src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp 1970-01-01 00:00:00 +0000
+++ src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,185 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#include <unity/scopes/internal/zmq_middleware/ZmqSubscriber.h>
20
21#include <unity/scopes/internal/UniqueID.h>
22#include <unity/scopes/internal/zmq_middleware/StopPublisher.h>
23#include <unity/scopes/ScopeExceptions.h>
24
25#include <zmqpp/poller.hpp>
26#include <zmqpp/socket.hpp>
27
28namespace unity
29{
30
31namespace scopes
32{
33
34namespace internal
35{
36
37namespace zmq_middleware
38{
39
40ZmqSubscriber::ZmqSubscriber(zmqpp::context* context, std::string const& publisher_id,
41 std::string const& endpoint_dir, std::string const& topic)
42 : context_(context)
43 , endpoint_("ipc://" + endpoint_dir + "/" + publisher_id)
44 , topic_(topic)
45 , thread_state_(NotRunning)
46 , thread_exception_(nullptr)
47 , callback_(nullptr)
48{
49 // Validate publisher_id
50 if (publisher_id.find('/') != std::string::npos)
51 {
52 throw MiddlewareException("ZmqSubscriber(): A publisher cannot contain a '/' in its id");
53 }
54
55 // Start thread_stopper_ publisher (used to send a stop message to the subscriber on destruction)
56 try
57 {
58 UniqueID unique_id;
59 thread_stopper_.reset(new StopPublisher(context, unique_id.gen()));
60 }
61 catch (...)
62 {
63 throw MiddlewareException("ZmqSubscriber(): thread_stopper_ failed to initialize (adapter: " + publisher_id + ")");
64 }
65
66 // Start the subscriber thread
67 thread_ = std::thread(&ZmqSubscriber::subscriber_thread, this);
68
69 std::unique_lock<std::mutex> lock(mutex_);
70 cond_.wait(lock, [this] { return thread_state_ == Running || thread_state_ == Failed; });
71
72 if (thread_state_ == Failed)
73 {
74 if (thread_.joinable())
75 {
76 thread_.join();
77 }
78 try
79 {
80 std::rethrow_exception(thread_exception_);
81 }
82 catch (...)
83 {
84 throw MiddlewareException("ZmqSubscriber(): subscriber thread failed to start (endpoint: " +
85 endpoint_ + ")");
86 }
87 }
88}
89
90ZmqSubscriber::~ZmqSubscriber()
91{
92 thread_stopper_->stop();
93
94 if (thread_.joinable())
95 {
96 thread_.join();
97 }
98}
99
100std::string ZmqSubscriber::endpoint() const
101{
102 return endpoint_;
103}
104
105void ZmqSubscriber::set_message_callback(SubscriberCallback callback)
106{
107 std::lock_guard<std::mutex> lock(mutex_);
108 callback_ = callback;
109}
110
111void ZmqSubscriber::subscriber_thread()
112{
113 try
114 {
115 // Subscribe to our associated publisher socket
116 zmqpp::socket sub_socket(*context_, zmqpp::socket_type::subscribe);
117 sub_socket.set(zmqpp::socket_option::linger, 0);
118 sub_socket.connect(endpoint_);
119 sub_socket.subscribe(topic_);
120
121 // Subscribe to the thread_stopper_ socket
122 zmqpp::socket stop_socket = thread_stopper_->subscribe();
123
124 // Configure the message poller
125 zmqpp::poller poller;
126 poller.add(sub_socket);
127 poller.add(stop_socket);
128
129 // Notify constructor that the thread is now running
130 {
131 std::lock_guard<std::mutex> lock(mutex_);
132 thread_state_ = Running;
133 cond_.notify_all();
134 }
135
136 // Poll for messages
137 std::string message;
138 while (true)
139 {
140 poller.poll();
141
142 // Flush out the message queue before stopping the thread
143 if (poller.has_input(sub_socket))
144 {
145 sub_socket.receive(message);
146
147 // Discard the message if no callback is set
148 std::lock_guard<std::mutex> lock(mutex_);
149 if (callback_)
150 {
151 // Message should arrive in the format: "<topic>:<message>"
152 if (message.length() > topic_.length() &&
153 message[topic_.length()] == ':')
154 {
155 callback_(message.substr(topic_.length() + 1));
156 }
157 }
158 }
159 else if(poller.has_input(stop_socket))
160 {
161 break;
162 }
163 }
164
165 // Clean up
166 poller.remove(sub_socket);
167 poller.remove(stop_socket);
168 sub_socket.close();
169 }
170 catch (...)
171 {
172 std::lock_guard<std::mutex> lock(mutex_);
173 thread_exception_ = std::current_exception();
174 thread_state_ = Failed;
175 cond_.notify_all();
176 }
177}
178
179} // namespace zmq_middleware
180
181} // namespace internal
182
183} // namespace scopes
184
185} // namespace unity
0186
=== modified file 'test/gtest/scopes/CMakeLists.txt'
--- test/gtest/scopes/CMakeLists.txt 2014-05-14 04:50:14 +0000
+++ test/gtest/scopes/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -14,7 +14,9 @@
14add_subdirectory(IdleShutdown)14add_subdirectory(IdleShutdown)
15add_subdirectory(Invocation)15add_subdirectory(Invocation)
16add_subdirectory(OptionSelectorFilter)16add_subdirectory(OptionSelectorFilter)
17add_subdirectory(RadioButtonsFilter)
17add_subdirectory(RangeInputFilter)18add_subdirectory(RangeInputFilter)
19add_subdirectory(RatingFilter)
18add_subdirectory(PreviewWidget)20add_subdirectory(PreviewWidget)
19add_subdirectory(QueryMetadata)21add_subdirectory(QueryMetadata)
20add_subdirectory(Registry)22add_subdirectory(Registry)
2123
=== modified file 'test/gtest/scopes/Filters/Filters_test.cpp'
--- test/gtest/scopes/Filters/Filters_test.cpp 2014-05-08 17:08:38 +0000
+++ test/gtest/scopes/Filters/Filters_test.cpp 2014-05-21 14:02:43 +0000
@@ -18,7 +18,10 @@
1818
19#include <unity/scopes/internal/RuntimeImpl.h>19#include <unity/scopes/internal/RuntimeImpl.h>
20#include <unity/scopes/internal/ScopeImpl.h>20#include <unity/scopes/internal/ScopeImpl.h>
21#include <unity/scopes/internal/FilterBaseImpl.h>
21#include <unity/scopes/FilterOption.h>22#include <unity/scopes/FilterOption.h>
23#include <unity/scopes/RadioButtonsFilter.h>
24#include <unity/scopes/RatingFilter.h>
22#include <unity/scopes/SearchMetadata.h>25#include <unity/scopes/SearchMetadata.h>
23#include <unity/UnityExceptions.h>26#include <unity/UnityExceptions.h>
24#include <gtest/gtest.h>27#include <gtest/gtest.h>
@@ -133,3 +136,72 @@
133 EXPECT_EQ("o1", option1->id());136 EXPECT_EQ("o1", option1->id());
134 }137 }
135}138}
139
140TEST(Filters, deserialize)
141{
142 // check that FilterBaseImpl::deserialize() creates valid instances of all filter types
143 {
144 OptionSelectorFilter::SPtr filter1 = OptionSelectorFilter::create("f1", "Options", false);
145 auto option1 = filter1->add_option("1", "Option 1");
146 auto var = filter1->serialize();
147
148 auto f = internal::FilterBaseImpl::deserialize(var);
149 EXPECT_TRUE(std::dynamic_pointer_cast<OptionSelectorFilter const>(f) != nullptr);
150 EXPECT_EQ("option_selector", f->filter_type());
151
152 const Filters filters {filter1};
153 EXPECT_NO_THROW(internal::FilterBaseImpl::validate_filters(filters));
154 }
155
156 {
157 RadioButtonsFilter::SPtr filter1 = RadioButtonsFilter::create("f1", "Options");
158 auto option1 = filter1->add_option("1", "Option 1");
159 auto var = filter1->serialize();
160
161 auto f = internal::FilterBaseImpl::deserialize(var);
162 EXPECT_TRUE(std::dynamic_pointer_cast<RadioButtonsFilter const>(f) != nullptr);
163 EXPECT_EQ("radio_buttons", f->filter_type());
164
165 const Filters filters {filter1};
166 EXPECT_NO_THROW(internal::FilterBaseImpl::validate_filters(filters));
167 }
168
169 {
170 RatingFilter::SPtr filter1 = RatingFilter::create("f1", "Options", 5);
171 auto var = filter1->serialize();
172
173 auto f = internal::FilterBaseImpl::deserialize(var);
174 EXPECT_TRUE(std::dynamic_pointer_cast<RatingFilter const>(f) != nullptr);
175 EXPECT_EQ("rating", f->filter_type());
176
177 const Filters filters {filter1};
178 EXPECT_NO_THROW(internal::FilterBaseImpl::validate_filters(filters));
179 }
180
181 {
182 // invalid data (no filter_type)
183 VariantMap var;
184 EXPECT_THROW(internal::FilterBaseImpl::deserialize(var), unity::LogicException);
185 }
186}
187
188TEST(Filters, validate)
189{
190 {
191 FilterBase::SPtr filter1 = OptionSelectorFilter::create("f1", "Options", false);
192 const Filters filters {filter1};
193 EXPECT_THROW(internal::FilterBaseImpl::validate_filters(filters), unity::LogicException);
194 }
195
196 {
197 FilterBase::SPtr filter1 = RadioButtonsFilter::create("f1", "Options");
198 const Filters filters {filter1};
199 EXPECT_THROW(internal::FilterBaseImpl::validate_filters(filters), unity::LogicException);
200 }
201
202 {
203 FilterBase::SPtr filter1 = RatingFilter::create("f1", "Options");
204 const Filters filters {filter1};
205 EXPECT_THROW(internal::FilterBaseImpl::validate_filters(filters), unity::LogicException);
206 }
207}
136208
=== modified file 'test/gtest/scopes/Filters/TestScope.h'
--- test/gtest/scopes/Filters/TestScope.h 2014-03-07 01:07:28 +0000
+++ test/gtest/scopes/Filters/TestScope.h 2014-05-21 14:02:43 +0000
@@ -45,7 +45,7 @@
45 virtual void run(SearchReplyProxy const& reply) override45 virtual void run(SearchReplyProxy const& reply) override
46 {46 {
47 Filters filters;47 Filters filters;
48 auto filter = OptionSelectorFilter::create("f1", "Choose an option", false);48 OptionSelectorFilter::SPtr filter = OptionSelectorFilter::create("f1", "Choose an option", false);
49 filter->add_option("o1", "Option 1");49 filter->add_option("o1", "Option 1");
50 filter->add_option("o2", "Option 2");50 filter->add_option("o2", "Option 2");
51 filters.push_back(filter);51 filters.push_back(filter);
5252
=== modified file 'test/gtest/scopes/IdleShutdown/IdleShutdown_test.cpp'
--- test/gtest/scopes/IdleShutdown/IdleShutdown_test.cpp 2014-05-14 04:50:14 +0000
+++ test/gtest/scopes/IdleShutdown/IdleShutdown_test.cpp 2014-05-21 14:02:43 +0000
@@ -40,8 +40,12 @@
40 {40 {
41 }41 }
4242
43 virtual void finished(ListenerBase::Reason /* reason */, string const& /* error_message */) override43 virtual void finished(ListenerBase::Reason reason, string const& error_message) override
44 {44 {
45 EXPECT_EQ(ListenerBase::Reason::Error, reason);
46 EXPECT_EQ("unity::scopes::MiddlewareException: unity::scopes::MiddlewareException: "
47 "Cannot invoke operations while middleware is stopped",
48 error_message);
45 lock_guard<mutex> lock(mutex_);49 lock_guard<mutex> lock(mutex_);
46 query_complete_ = true;50 query_complete_ = true;
47 cond_.notify_one();51 cond_.notify_one();
@@ -81,10 +85,10 @@
81 }85 }
8286
83 // Check that the scope has indeed timed out. The server shuts down after 2 seconds,87 // Check that the scope has indeed timed out. The server shuts down after 2 seconds,
84 // so we allow between 2 and 3 seconds for it to time out.88 // so we allow between 2 and 4 seconds for it to time out.
85 auto duration = chrono::steady_clock::now() - start_time;89 auto duration = chrono::steady_clock::now() - start_time;
86 EXPECT_TRUE(duration > chrono::seconds(2));90 EXPECT_TRUE(duration > chrono::seconds(2));
87 EXPECT_TRUE(duration < chrono::seconds(3));91 EXPECT_TRUE(duration < chrono::seconds(4));
88}92}
8993
90// Check that the idle timeout for a server waits for synchronous operations94// Check that the idle timeout for a server waits for synchronous operations
@@ -122,11 +126,13 @@
122126
123 // Check that the run time doesn't shut down until127 // Check that the run time doesn't shut down until
124 // the search in the scope has completed, which takes 4 seconds.128 // the search in the scope has completed, which takes 4 seconds.
125 // We allow 4 - 5 seconds for things to shut down before failing129 // We allow 4 - 6 seconds for things to shut down before failing
126 // (or hanging).130 // (or hanging). (On Arm, can be slow to shut down, so we allow
131 // a full two seconds for the server to go away before failing
132 // the test.)
127 auto duration = chrono::steady_clock::now() - start_time;133 auto duration = chrono::steady_clock::now() - start_time;
128 EXPECT_TRUE(duration > chrono::seconds(4));134 EXPECT_TRUE(duration > chrono::seconds(4));
129 EXPECT_TRUE(duration < chrono::seconds(5));135 EXPECT_TRUE(duration < chrono::seconds(6));
130}136}
131137
132int main(int argc, char **argv)138int main(int argc, char **argv)
133139
=== modified file 'test/gtest/scopes/IdleShutdown/SlowSearchScope.cpp'
--- test/gtest/scopes/IdleShutdown/SlowSearchScope.cpp 2014-05-14 04:50:14 +0000
+++ test/gtest/scopes/IdleShutdown/SlowSearchScope.cpp 2014-05-21 14:02:43 +0000
@@ -64,7 +64,7 @@
6464
65SearchQueryBase::UPtr SlowSearchScope::search(CannedQuery const&, SearchMetadata const &)65SearchQueryBase::UPtr SlowSearchScope::search(CannedQuery const&, SearchMetadata const &)
66{66{
67 this_thread::sleep_for(chrono::seconds(4));67 this_thread::sleep_for(chrono::seconds(4));
68 return SearchQueryBase::UPtr(new TestQuery());68 return SearchQueryBase::UPtr(new TestQuery());
69}69}
7070
7171
=== modified file 'test/gtest/scopes/IdleShutdown/Zmq.ini.in'
--- test/gtest/scopes/IdleShutdown/Zmq.ini.in 2014-05-14 04:50:14 +0000
+++ test/gtest/scopes/IdleShutdown/Zmq.ini.in 2014-05-21 14:02:43 +0000
@@ -1,3 +1,7 @@
1[Zmq]1[Zmq]
2EndpointDir = /tmp2EndpointDir = /tmp
3Default.Twoway.Timeout = 50003# We set the idle timeout to something much larger than the expected
4# time for the test to finish, so we don't see a bogus completion
5# of the slow call due to the timeout on the client side triggering,
6# rather than the server shutting down.
7Default.Twoway.Timeout = 10000
48
=== modified file 'test/gtest/scopes/OptionSelectorFilter/OptionSelectorFilter_test.cpp'
--- test/gtest/scopes/OptionSelectorFilter/OptionSelectorFilter_test.cpp 2014-05-15 08:12:32 +0000
+++ test/gtest/scopes/OptionSelectorFilter/OptionSelectorFilter_test.cpp 2014-05-21 14:02:43 +0000
@@ -62,10 +62,12 @@
6262
63 FilterState fstate;63 FilterState fstate;
64 EXPECT_FALSE(fstate.has_filter("f1"));64 EXPECT_FALSE(fstate.has_filter("f1"));
65 EXPECT_FALSE(filter1->has_active_option(fstate));
6566
66 // enable option167 // enable option1
67 filter1->update_state(fstate, option1, true);68 filter1->update_state(fstate, option1, true);
68 EXPECT_TRUE(fstate.has_filter("f1"));69 EXPECT_TRUE(fstate.has_filter("f1"));
70 EXPECT_TRUE(filter1->has_active_option(fstate));
69 auto active = filter1->active_options(fstate);71 auto active = filter1->active_options(fstate);
70 EXPECT_EQ(1u, active.size());72 EXPECT_EQ(1u, active.size());
71 EXPECT_TRUE(active.find(option1) != active.end());73 EXPECT_TRUE(active.find(option1) != active.end());
@@ -95,6 +97,7 @@
95 filter1->update_state(fstate, option1, true);97 filter1->update_state(fstate, option1, true);
96 filter1->update_state(fstate, option2, true);98 filter1->update_state(fstate, option2, true);
97 EXPECT_TRUE(fstate.has_filter("f1"));99 EXPECT_TRUE(fstate.has_filter("f1"));
100 EXPECT_TRUE(filter1->has_active_option(fstate));
98 auto active = filter1->active_options(fstate);101 auto active = filter1->active_options(fstate);
99 EXPECT_EQ(2u, active.size());102 EXPECT_EQ(2u, active.size());
100 EXPECT_TRUE(active.find(option1) != active.end());103 EXPECT_TRUE(active.find(option1) != active.end());
101104
=== added directory 'test/gtest/scopes/RadioButtonsFilter'
=== added file 'test/gtest/scopes/RadioButtonsFilter/CMakeLists.txt'
--- test/gtest/scopes/RadioButtonsFilter/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/RadioButtonsFilter/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -0,0 +1,4 @@
1add_executable(RadioButtonsFilter_test RadioButtonsFilter_test.cpp)
2target_link_libraries(RadioButtonsFilter_test ${TESTLIBS})
3
4add_test(RadioButtonsFilter RadioButtonsFilter_test)
05
=== added file 'test/gtest/scopes/RadioButtonsFilter/RadioButtonsFilter_test.cpp'
--- test/gtest/scopes/RadioButtonsFilter/RadioButtonsFilter_test.cpp 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/RadioButtonsFilter/RadioButtonsFilter_test.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,71 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17 */
18
19#include <gtest/gtest.h>
20#include <unity/scopes/FilterState.h>
21#include <unity/scopes/RadioButtonsFilter.h>
22#include <unity/UnityExceptions.h>
23
24using namespace unity::scopes;
25using namespace unity::scopes::internal;
26
27TEST(RadioButtonsFilter, basic)
28{
29 auto filter1 = RadioButtonsFilter::create("f1", "Choose");
30 EXPECT_EQ("f1", filter1->id());
31 EXPECT_EQ("Choose", filter1->label());
32 EXPECT_EQ(0u, filter1->options().size());
33
34 filter1->add_option("a", "A");
35 filter1->add_option("b", "B");
36
37 auto opts = filter1->options();
38 EXPECT_EQ(2u, opts.size());
39 EXPECT_EQ("a", opts.front()->id());
40 EXPECT_EQ("A", opts.front()->label());
41 EXPECT_EQ("b", opts.back()->id());
42 EXPECT_EQ("B", opts.back()->label());
43}
44
45TEST(RadioButtonsFilter, selection)
46{
47 auto filter1 = RadioButtonsFilter::create("f1", "Options");
48 auto option1 = filter1->add_option("1", "Option 1");
49 auto option2 = filter1->add_option("2", "Option 2");
50
51 FilterState fstate;
52 EXPECT_FALSE(fstate.has_filter("f1"));
53 EXPECT_EQ(nullptr, filter1->active_option(fstate));
54 EXPECT_FALSE(filter1->has_active_option(fstate));
55
56 // enable option1
57 filter1->update_state(fstate, option1, true);
58 EXPECT_TRUE(fstate.has_filter("f1"));
59 auto active = filter1->active_option(fstate);
60 EXPECT_EQ("1", active->id());
61
62 // enable option2, option1 get disabled
63 filter1->update_state(fstate, option2, true);
64 active = filter1->active_option(fstate);
65 EXPECT_EQ("2", active->id());
66
67 // disable option1; filter state remains in the FilterState, just no options are selected
68 filter1->update_state(fstate, option2, false);
69 EXPECT_TRUE(fstate.has_filter("f1"));
70 EXPECT_EQ(nullptr, filter1->active_option(fstate));
71}
072
=== added directory 'test/gtest/scopes/RatingFilter'
=== added file 'test/gtest/scopes/RatingFilter/CMakeLists.txt'
--- test/gtest/scopes/RatingFilter/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/RatingFilter/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -0,0 +1,4 @@
1add_executable(RatingFilter_test RatingFilter_test.cpp)
2target_link_libraries(RatingFilter_test ${TESTLIBS})
3
4add_test(RatingFilter RatingFilter_test)
05
=== added file 'test/gtest/scopes/RatingFilter/RatingFilter_test.cpp'
--- test/gtest/scopes/RatingFilter/RatingFilter_test.cpp 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/RatingFilter/RatingFilter_test.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,111 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pawel Stolowski <pawel.stolowski@canonical.com>
17 */
18
19#include <gtest/gtest.h>
20#include <unity/scopes/FilterState.h>
21#include <unity/scopes/RatingFilter.h>
22#include <unity/UnityExceptions.h>
23
24using namespace unity::scopes;
25using namespace unity::scopes::internal;
26
27TEST(RatingFilter, basic)
28{
29 {
30 auto filter1 = RatingFilter::create("f1", "Rating");
31 filter1->set_on_icon("foo");
32 filter1->set_off_icon("bar");
33 EXPECT_EQ("f1", filter1->id());
34 EXPECT_EQ("Rating", filter1->label());
35 EXPECT_EQ("foo", filter1->on_icon());
36 EXPECT_EQ("bar", filter1->off_icon());
37 EXPECT_EQ(0u, filter1->options().size());
38
39 auto o1 = filter1->add_option("a", "A");
40 auto o2 = filter1->add_option("b", "B");
41 EXPECT_EQ("a", o1->id());
42 EXPECT_EQ("b", o2->id());
43
44 auto opts = filter1->options();
45 EXPECT_EQ(2u, opts.size());
46 EXPECT_EQ("a", opts.front()->id());
47 EXPECT_EQ("A", opts.front()->label());
48 EXPECT_EQ("b", opts.back()->id());
49 EXPECT_EQ("B", opts.back()->label());
50 }
51
52 {
53 auto filter1 = RatingFilter::create("f1", "Rating", 3);
54 EXPECT_EQ("f1", filter1->id());
55 EXPECT_EQ("Rating", filter1->label());
56
57 auto opts = filter1->options();
58 EXPECT_EQ(3u, opts.size());
59 auto it = opts.begin();
60 EXPECT_EQ("1", (*it)->id());
61 EXPECT_EQ("1+", (*it)->label());
62 EXPECT_EQ("2", (*++it)->id());
63 EXPECT_EQ("2+", (*it)->label());
64 EXPECT_EQ("3", (*++it)->id());
65 EXPECT_EQ("3", (*it)->label());
66 }
67
68 {
69 EXPECT_THROW(RatingFilter::create("f1", "Rating", 11), unity::LogicException);
70 }
71
72 {
73 auto filter1 = RatingFilter::create("f1", "Rating", 10);
74 EXPECT_THROW(filter1->add_option("11", "11"), unity::LogicException);
75 }
76}
77
78TEST(RatingFilter, selection)
79{
80 auto filter1 = RatingFilter::create("f1", "Rating", 2);
81
82 FilterState fstate;
83 EXPECT_FALSE(fstate.has_filter("f1"));
84 EXPECT_FALSE(filter1->has_active_rating(fstate));
85 EXPECT_EQ(nullptr, filter1->active_rating(fstate));
86
87 auto opts = filter1->options();
88 EXPECT_EQ(2u, opts.size());
89
90 auto it = opts.begin();
91 auto option1 = *(it++);
92 auto option2 = *it;
93
94 // enable option1
95 filter1->update_state(fstate, option1, true);
96 EXPECT_TRUE(fstate.has_filter("f1"));
97 EXPECT_TRUE(filter1->has_active_rating(fstate));
98 auto active = filter1->active_rating(fstate);
99 EXPECT_EQ("1", active->id());
100
101 // enable option2, option1 get disabled
102 filter1->update_state(fstate, option2, true);
103 active = filter1->active_rating(fstate);
104 EXPECT_EQ("2", active->id());
105
106 // disable option1; filter state remains in the FilterState, just no options are selected
107 filter1->update_state(fstate, option2, false);
108 EXPECT_TRUE(fstate.has_filter("f1"));
109 EXPECT_FALSE(filter1->has_active_rating(fstate));
110 EXPECT_EQ(nullptr, filter1->active_rating(fstate));
111}
0112
=== modified file 'test/gtest/scopes/Registry/Registry_test.cpp'
--- test/gtest/scopes/Registry/Registry_test.cpp 2014-05-06 04:29:02 +0000
+++ test/gtest/scopes/Registry/Registry_test.cpp 2014-05-21 14:02:43 +0000
@@ -77,25 +77,6 @@
77 Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE);77 Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE);
78 RegistryProxy r = rt->registry();78 RegistryProxy r = rt->registry();
7979
80 // wait for the registry to become available on middleware
81 // FIXME: remove this once we have async queries and can set arbitrary timeout when calling registry
82 const int num_retries = 10;
83 bool registry_started = false;
84 for (int i = 0; i < num_retries; ++i)
85 {
86 try
87 {
88 r->list(); // this will throw if the registry is not yet available on middleware
89 registry_started = true;
90 break;
91 }
92 catch (std::exception const&)
93 {
94 sleep(1);
95 }
96 }
97 ASSERT_TRUE(registry_started);
98
99 auto meta = r->get_metadata("testscopeA");80 auto meta = r->get_metadata("testscopeA");
100 EXPECT_EQ("testscopeA", meta.scope_id());81 EXPECT_EQ("testscopeA", meta.scope_id());
101 EXPECT_EQ("Canonical Ltd.", meta.author());82 EXPECT_EQ("Canonical Ltd.", meta.author());
10283
=== modified file 'test/gtest/scopes/Registry/Zmq.ini.in'
--- test/gtest/scopes/Registry/Zmq.ini.in 2014-05-06 09:00:45 +0000
+++ test/gtest/scopes/Registry/Zmq.ini.in 2014-05-21 14:02:43 +0000
@@ -1,2 +1,3 @@
1[Zmq]1[Zmq]
2EndpointDir = /tmp2EndpointDir = /tmp
3Default.Twoway.Timeout = 2000
34
=== modified file 'test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py'
--- test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py 2014-05-09 09:56:09 +0000
+++ test/gtest/scopes/internal/smartscopes/SmartScopesClient/FakeSss.py 2014-05-21 14:02:43 +0000
@@ -60,7 +60,7 @@
60[{"base_url": "http://127.0.0.1:' + str(port) + '/fail", "id" : "fail.scope", "name": "Fail Scope", "description": "Fails due to no author.", "icon": "icon" },\60[{"base_url": "http://127.0.0.1:' + str(port) + '/fail", "id" : "fail.scope", "name": "Fail Scope", "description": "Fails due to no author.", "icon": "icon" },\
61{"base_url": "http://127.0.0.1:' + str(port) + '/demo", "id" : "dummy.scope", "name": "Dummy Demo Scope", "description": "Dummy demo scope.", "author": "Mr.Fake", "icon": "icon" },\61{"base_url": "http://127.0.0.1:' + str(port) + '/demo", "id" : "dummy.scope", "name": "Dummy Demo Scope", "description": "Dummy demo scope.", "author": "Mr.Fake", "icon": "icon" },\
62{"base_url": "http://127.0.0.1:' + str(port) + '/fail2", "name": "Fail Scope 2", "description": "Fails due to no id.", "author": "Mr.Fake", "icon": "icon" },\62{"base_url": "http://127.0.0.1:' + str(port) + '/fail2", "name": "Fail Scope 2", "description": "Fails due to no id.", "author": "Mr.Fake", "icon": "icon" },\
63{"base_url": "http://127.0.0.1:' + str(port) + '/demo2", "id" : "dummy.scope.2", "name": "Dummy Demo Scope 2", "description": "Dummy demo scope 2.", "author": "Mr.Fake", "art": "art", "invisible": true },\63{"base_url": "http://127.0.0.1:' + str(port) + '/demo2", "id" : "dummy.scope.2", "name": "Dummy Demo Scope 2", "description": "Dummy demo scope 2.", "author": "Mr.Fake", "art": "art", "invisible": true, "appearance": {"background": "#00BEEF"} },\
64{"id" : "fail.scope.3", "name": "Fail Scope 3", "description": "Fails due to no base_url.", "author": "Mr.Fake", "art": "art" }]'64{"id" : "fail.scope.3", "name": "Fail Scope 3", "description": "Fails due to no base_url.", "author": "Mr.Fake", "art": "art" }]'
6565
66search_response = '\66search_response = '\
6767
=== modified file 'test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp'
--- test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp 2014-05-09 09:56:09 +0000
+++ test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp 2014-05-21 14:02:43 +0000
@@ -81,6 +81,7 @@
81 EXPECT_EQ("icon", *scopes[0].icon);81 EXPECT_EQ("icon", *scopes[0].icon);
82 EXPECT_EQ(nullptr, scopes[0].art);82 EXPECT_EQ(nullptr, scopes[0].art);
83 EXPECT_FALSE(scopes[0].invisible);83 EXPECT_FALSE(scopes[0].invisible);
84 EXPECT_EQ(nullptr, scopes[0].appearance);
8485
85 EXPECT_EQ("dummy.scope.2", scopes[1].id);86 EXPECT_EQ("dummy.scope.2", scopes[1].id);
86 EXPECT_EQ("Dummy Demo Scope 2", scopes[1].name);87 EXPECT_EQ("Dummy Demo Scope 2", scopes[1].name);
@@ -90,6 +91,7 @@
90 EXPECT_EQ(nullptr, scopes[1].icon);91 EXPECT_EQ(nullptr, scopes[1].icon);
91 EXPECT_EQ("art", *scopes[1].art);92 EXPECT_EQ("art", *scopes[1].art);
92 EXPECT_TRUE(scopes[1].invisible);93 EXPECT_TRUE(scopes[1].invisible);
94 EXPECT_EQ("#00BEEF", (*scopes[1].appearance)["background"].get_string());
93}95}
9496
95TEST_F(SmartScopesClientTest, search)97TEST_F(SmartScopesClientTest, search)
9698
=== modified file 'test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt'
--- test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt 2014-04-14 23:47:33 +0000
+++ test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -1,4 +1,5 @@
1add_subdirectory(ObjectAdapter)1add_subdirectory(ObjectAdapter)
2add_subdirectory(PubSub)
2add_subdirectory(RegistryI)3add_subdirectory(RegistryI)
3add_subdirectory(ServantBase)4add_subdirectory(ServantBase)
4add_subdirectory(StopPublisher)5add_subdirectory(StopPublisher)
56
=== modified file 'test/gtest/scopes/internal/zmq_middleware/ObjectAdapter/ObjectAdapter_test.cpp'
--- test/gtest/scopes/internal/zmq_middleware/ObjectAdapter/ObjectAdapter_test.cpp 2014-05-02 00:00:08 +0000
+++ test/gtest/scopes/internal/zmq_middleware/ObjectAdapter/ObjectAdapter_test.cpp 2014-05-21 14:02:43 +0000
@@ -1071,8 +1071,7 @@
1071 {1071 {
1072 EXPECT_STREQ("unity::scopes::MiddlewareException: ObjectAdapter::run_workers(): broker thread failure "1072 EXPECT_STREQ("unity::scopes::MiddlewareException: ObjectAdapter::run_workers(): broker thread failure "
1073 "(adapter: testscope):\n"1073 "(adapter: testscope):\n"
1074 " unity::scopes::MiddlewareException: ObjectAdapter: broker thread failure "1074 " unity::scopes::MiddlewareException: safe_bind(): address in use: ipc://testscope", e.what());
1075 "(adapter: testscope): address in use: ipc://testscope", e.what());
1076 }1075 }
10771076
1078 {1077 {
@@ -1108,8 +1107,7 @@
1108 {1107 {
1109 EXPECT_STREQ("unity::scopes::MiddlewareException: ObjectAdapter::run_workers(): broker thread failure "1108 EXPECT_STREQ("unity::scopes::MiddlewareException: ObjectAdapter::run_workers(): broker thread failure "
1110 "(adapter: testscope):\n"1109 "(adapter: testscope):\n"
1111 " unity::scopes::MiddlewareException: ObjectAdapter: broker thread failure "1110 " unity::scopes::MiddlewareException: safe_bind(): address in use: ipc://testscope", e.what());
1112 "(adapter: testscope): address in use: ipc://testscope", e.what());
1113 }1111 }
11141112
1115 {1113 {
11161114
=== added directory 'test/gtest/scopes/internal/zmq_middleware/PubSub'
=== added file 'test/gtest/scopes/internal/zmq_middleware/PubSub/CMakeLists.txt'
--- test/gtest/scopes/internal/zmq_middleware/PubSub/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/zmq_middleware/PubSub/CMakeLists.txt 2014-05-21 14:02:43 +0000
@@ -0,0 +1,6 @@
1configure_file(Zmq.ini.in Zmq.ini)
2
3add_executable(PubSub_test PubSub_test.cpp)
4target_link_libraries(PubSub_test ${LIBS} ${TESTLIBS})
5
6add_test(PubSub PubSub_test)
07
=== added file 'test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp'
--- test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp 2014-05-21 14:02:43 +0000
@@ -0,0 +1,237 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/lzmqnses/>.
15 *
16 * Authored by: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include <scope-api-testconfig.h>
20#include <unity/scopes/internal/RuntimeImpl.h>
21#include <unity/scopes/internal/zmq_middleware/ZmqMiddleware.h>
22#include <unity/scopes/ScopeExceptions.h>
23
24#include <gtest/gtest.h>
25#include <condition_variable>
26#include <mutex>
27
28using namespace std::placeholders;
29using namespace unity::scopes;
30using namespace unity::scopes::internal;
31using namespace unity::scopes::internal::zmq_middleware;
32
33TEST(PubSub, endpoints)
34{
35 ZmqMiddleware mw("testscope", (RuntimeImpl*)0x1,
36 TEST_BUILD_ROOT "/gtest/scopes/internal/zmq_middleware/ObjectAdapter/Zmq.ini");
37
38 auto publisher = mw.create_publisher("testpublisher");
39 auto subscriber = mw.create_subscriber("testpublisher", "");
40
41 EXPECT_EQ("ipc:///tmp/testpublisher-p", publisher->endpoint());
42 EXPECT_EQ(subscriber->endpoint(), publisher->endpoint());
43}
44
45TEST(PubSub, exceptions)
46{
47 ZmqMiddleware mw("testscope", (RuntimeImpl*)0x1,
48 TEST_BUILD_ROOT "/gtest/scopes/internal/zmq_middleware/ObjectAdapter/Zmq.ini");
49
50 // Test that only one publisher can be created on a single endpoint
51 auto publisher = mw.create_publisher("testpublisher");
52 try
53 {
54 auto publisher2 = mw.create_publisher("testpublisher");
55 FAIL();
56 }
57 catch (MiddlewareException const& e)
58 {
59 EXPECT_STREQ("unity::scopes::MiddlewareException: ZmqPublisher(): publisher thread failed to start "
60 "(endpoint: ipc:///tmp/testpublisher-p):\n unity::scopes::MiddlewareException: "
61 "safe_bind(): address in use: ipc:///tmp/testpublisher-p",
62 e.what());
63 }
64
65 // Test that multiple subscribers can be created on a single endpoint
66 auto subscriber = mw.create_subscriber("testpublisher", "");
67 try
68 {
69 auto subscriber2 = mw.create_subscriber("testpublisher", "testtopic1");
70 auto subscriber3 = mw.create_subscriber("testpublisher", "testtopic2");
71 auto subscriber4 = mw.create_subscriber("testpublisher", "testtopic3");
72 auto subscriber5 = mw.create_subscriber("testpublisher", "testtopic4");
73 }
74 catch (MiddlewareException const& e)
75 {
76 FAIL();
77 }
78
79 // Test that an invalid publisher_id throws
80 try
81 {
82 auto publisher2 = mw.create_publisher("/test/");
83 FAIL();
84 }
85 catch (MiddlewareException const& e)
86 {
87 EXPECT_STREQ("unity::scopes::MiddlewareException: ZmqPublisher(): A publisher cannot contain a '/' in its id",
88 e.what());
89 }
90 try
91 {
92 auto subscriber2 = mw.create_subscriber("/test/", "testtopic");
93 FAIL();
94 }
95 catch (MiddlewareException const& e)
96 {
97 EXPECT_STREQ("unity::scopes::MiddlewareException: ZmqSubscriber(): A publisher cannot contain a '/' in its id",
98 e.what());
99 }
100}
101
102class SubMsgReceiver
103{
104public:
105 void receive1(std::string const& message)
106 {
107 last_sub_index_ = 1;
108 last_message_ = message;
109 received();
110 }
111
112 void receive2(std::string const& message)
113 {
114 last_sub_index_ = 2;
115 last_message_ = message;
116 received();
117 }
118
119 void receive3(std::string const& message)
120 {
121 last_sub_index_ = 3;
122 last_message_ = message;
123 received();
124 }
125
126 void receive4(std::string const& message)
127 {
128 last_sub_index_ = 4;
129 last_message_ = message;
130 received();
131 }
132
133 void received()
134 {
135 // Signal wait_for_message
136 std::lock_guard<std::mutex> lock(mutex_);
137 message_received_ = true;
138 cond_.notify_one();
139 }
140
141 bool wait_for_message()
142 {
143 std::unique_lock<std::mutex> lock(mutex_);
144 bool message_received = cond_.wait_for(lock, std::chrono::milliseconds(500), [this] { return this->message_received_; });
145 message_received_ = false;
146 return message_received;
147 }
148
149 int last_sub_index_ = 0;
150 std::string last_message_;
151
152 bool message_received_ = false;
153 std::mutex mutex_;
154 std::condition_variable cond_;
155};
156
157TEST(PubSub, send_receive)
158{
159 SubMsgReceiver message_receiver;
160
161 ZmqMiddleware mw("testscope", (RuntimeImpl*)0x1,
162 TEST_BUILD_ROOT "/gtest/scopes/internal/zmq_middleware/ObjectAdapter/Zmq.ini");
163
164 // Create 2 publishers
165 auto publisher = mw.create_publisher("testpublisher");
166 auto publisher2 = mw.create_publisher("testpublisher2");
167
168 // Create a few subscribers
169 auto subscriber1 = mw.create_subscriber("testpublisher", "testtopic1");
170 subscriber1->set_message_callback(std::bind(&SubMsgReceiver::receive1, &message_receiver, _1));
171
172 auto subscriber2 = mw.create_subscriber("testpublisher", "testtopic2");
173 subscriber2->set_message_callback(std::bind(&SubMsgReceiver::receive2, &message_receiver, _1));
174
175 auto subscriber3 = mw.create_subscriber("testpublisher", "");
176 subscriber3->set_message_callback(std::bind(&SubMsgReceiver::receive3, &message_receiver, _1));
177
178 auto subscriber4 = mw.create_subscriber("testpublisher2", "testtopic4");
179 subscriber4->set_message_callback(std::bind(&SubMsgReceiver::receive4, &message_receiver, _1));
180
181 // Give the subscribers some time to connect
182 std::this_thread::sleep_for(std::chrono::milliseconds(500));
183
184 // Send a "testtopic1" topic message (subscriber1)
185 publisher->send_message("hello", "testtopic1");
186 EXPECT_TRUE(message_receiver.wait_for_message());
187 EXPECT_EQ(1, message_receiver.last_sub_index_);
188 EXPECT_EQ("hello", message_receiver.last_message_);
189
190 // Send a blank "testtopic2" topic message (subscriber2)
191 publisher->send_message("", "testtopic2");
192 EXPECT_TRUE(message_receiver.wait_for_message());
193 EXPECT_EQ(2, message_receiver.last_sub_index_);
194 EXPECT_EQ("", message_receiver.last_message_);
195
196 // Send an empty topic message (subscriber3)
197 publisher->send_message("hello again!", "");
198 EXPECT_TRUE(message_receiver.wait_for_message());
199 EXPECT_EQ(3, message_receiver.last_sub_index_);
200 EXPECT_EQ("hello again!", message_receiver.last_message_);
201
202 // Send a "testtopic4" topic message (subscriber4)
203 // (no message should be received as subscriber4 is subscribed to a different publisher)
204 publisher->send_message("test", "testtopic4");
205 EXPECT_FALSE(message_receiver.wait_for_message());
206
207 // Now send a "testtopic4" topic message from the correct publisher (subscriber4)
208 publisher2->send_message("test", "testtopic4");
209 EXPECT_TRUE(message_receiver.wait_for_message());
210 EXPECT_EQ(4, message_receiver.last_sub_index_);
211 EXPECT_EQ("test", message_receiver.last_message_);
212
213 // Send a "unknown" topic message
214 // (no message should be received as none of the subscribers are listening for "unknown")
215 publisher->send_message("hello?", "unknown");
216 EXPECT_FALSE(message_receiver.wait_for_message());
217
218 publisher2->send_message("hello??", "unknown");
219 EXPECT_FALSE(message_receiver.wait_for_message());
220}
221
222TEST(PubSub, threading)
223{
224 ZmqMiddleware mw("testscope", (RuntimeImpl*)0x1,
225 TEST_BUILD_ROOT "/gtest/scopes/internal/zmq_middleware/ObjectAdapter/Zmq.ini");
226
227 {
228 // Create a publisher and a subscriber in seperate thread
229 auto subscriber_future = std::async(std::launch::async, [&mw]{ return mw.create_subscriber("testpublisher", "testtopic"); });
230 auto publisher_future = std::async(std::launch::async, [&mw]{ return mw.create_publisher("testpublisher"); });
231
232 // Obtain the publisher and subscriber handles
233 MWSubscriber::UPtr subscriber = subscriber_future.get();
234 MWPublisher::UPtr publisher = publisher_future.get();
235 }
236 // The publisher and subscriber are now destroyed in this thread (should not hang / crash)
237}
0238
=== added file 'test/gtest/scopes/internal/zmq_middleware/PubSub/Zmq.ini.in'
--- test/gtest/scopes/internal/zmq_middleware/PubSub/Zmq.ini.in 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/zmq_middleware/PubSub/Zmq.ini.in 2014-05-21 14:02:43 +0000
@@ -0,0 +1,2 @@
1[Zmq]
2EndpointDir = /tmp
03
=== modified file 'test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp'
--- test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp 2014-05-09 08:51:19 +0000
+++ test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp 2014-05-21 14:02:43 +0000
@@ -705,7 +705,7 @@
705 // check that we still have 1 child process705 // check that we still have 1 child process
706 EXPECT_EQ(1, process_count());706 EXPECT_EQ(1, process_count());
707707
708 std::this_thread::sleep_for(std::chrono::seconds{2});708 std::this_thread::sleep_for(std::chrono::seconds{3});
709709
710 // check now that the scope has shutdown automatically (timed out after 2s)710 // check now that the scope has shutdown automatically (timed out after 2s)
711 EXPECT_FALSE(reg->is_scope_running("testscopeB"));711 EXPECT_FALSE(reg->is_scope_running("testscopeB"));

Subscribers

People subscribed via source and target branches

to all changes: