From: Igor Nazarov Date: Fri, 2 Jun 2017 17:44:03 +0000 (+0300) Subject: TizenRefApp-8607 [Gallery] Implement autohighlighting feature while X-Git-Tag: submit/tizen/20170703.071445~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2d04413c1fc309fbb62a9eab89d4a66cf357b471;p=profile%2Fwearable%2Fapps%2Fnative%2Fgallery.git TizenRefApp-8607 [Gallery] Implement autohighlighting feature while scrolling in ScreenReader mode - Implemented autohighlighting in ImageGrid while scrolling; - UCL: added Timeout class; - UCL: smartDelegateion moved from "misc" to "util". Change-Id: Ib97b1bcc663b2f125e4d8a6cd0eb5f6b7eaed043 --- diff --git a/edc/layouts.edc b/edc/layouts.edc index 20dc42c..65211b8 100644 --- a/edc/layouts.edc +++ b/edc/layouts.edc @@ -14,6 +14,10 @@ * limitations under the License. */ +group { "elm/layout/gallery/fake_access_object"; + data.item: "access_highlight" "on"; +} + group { "elm/layout/gallery/more_options"; parts { swallow { "elm.swallow.content"; diff --git a/inc/types.h b/inc/types.h index 8983855..9a1476e 100644 --- a/inc/types.h +++ b/inc/types.h @@ -22,8 +22,7 @@ #include "ucl/util/types.h" #include "ucl/util/memory.h" #include "ucl/util/delegation.h" - -#include "ucl/misc/smartDelegation.h" +#include "ucl/util/smartDelegation.h" namespace gallery { diff --git a/inc/view/ImageGrid.h b/inc/view/ImageGrid.h index 399201b..540cafa 100644 --- a/inc/view/ImageGrid.h +++ b/inc/view/ImageGrid.h @@ -19,8 +19,11 @@ #include +#include "ucl/gui/Layout.h" #include "ucl/gui/StyledWidget.h" +#include "ucl/misc/Timeout.h" + #include "types.h" namespace gallery { @@ -129,12 +132,28 @@ namespace gallery { template ucl::Result showItem(int itemIndex, SHOW_FUNC &&showFunc); + bool isItemFullyVisible(int itemIndex); + bool isItemFullyVisible(int itemIndex, + int &minVisibleOffset, int &maxVisibleOffset) const; + bool isItemFullyVisible(int slotIndex, int itemOffset, + int &minVisibleOffset, int &maxVisibleOffset) const; + void forceBoxSizeCalculate(); void addUnrealizeLock(); void removeUnrealizeLock(); void handleItemEvent(int itemIndex, int event, int x, int y) const; + + // Accessibility + + void onItemHighlighted(int itemIndex); + void onItemUnhighlighted(int itemIndex); + void onKeeperUnhighlighted(Widget &sender, void *eventInfo); + + void updateHighlightTimeout(); + void onHighlightTimeout(ucl::Timeout *sender); + Elm_Interface_Atspi_Accessible *requestAtspi(int itemIndex); Elm_Interface_Atspi_Accessible *getItemAtspi(int itemIndex); @@ -150,6 +169,7 @@ namespace gallery { // Initialization void prepare(); void createCircleScroller(); + void createHighlighKeeper(); // Actual slots count bool updateSlotCount(); @@ -243,6 +263,11 @@ namespace gallery { int m_scrollLockIndex; bool m_isInSelectMode; bool m_isRotaryActive; + + ucl::LayoutSRef m_highlighKeeper; + ucl::TimeoutSRef m_highlightTimeout; + int m_highlightID; + bool m_isHighlightLocked; }; } diff --git a/src/view/ImageGrid.cpp b/src/view/ImageGrid.cpp index 6c8e14c..278a745 100644 --- a/src/view/ImageGrid.cpp +++ b/src/view/ImageGrid.cpp @@ -20,6 +20,7 @@ #include #include "ucl/gui/Layout.h" +#include "ucl/gui/Window.h" #include "view/IImageGridListener.h" #include "view/TouchParser.h" @@ -53,7 +54,11 @@ namespace gallery { namespace { namespace impl { constexpr EdjeSignal BTN_UNBLOCK_CLICKS {"gallery,unblock,clicks"}; // Other // + constexpr LayoutTheme LAYOUT_FAKE_ACCESS_OBJECT + {"layout", "gallery", "fake_access_object"}; + constexpr auto HCOMB_SCROLL_LIMIT = 1000; + constexpr auto SCROLL_HIGHLIGHT_TIMEOUT_SEC = 0.1; bool getImageSize(const Widget &image, int &w, int &h) { @@ -145,6 +150,11 @@ namespace gallery { return 0; } + virtual int getHighlightScanRange() const + { + return 1; + } + Info(const std::array &slotThemes, const std::array &slotLens, const ElmStyle btnStyle, @@ -158,6 +168,8 @@ namespace gallery { isHorizontal(isHorizontal) { } + + virtual ~Info() = default; }; // ImageGrid::HcombInfo // @@ -192,6 +204,11 @@ namespace gallery { return slotSize; } + virtual int getHighlightScanRange() const final override + { + return totalLength; + } + HcombInfo(const int totalLength, const std::array &slotThemes, const ElmStyle btnStyle) : @@ -257,6 +274,10 @@ namespace gallery { m_btn.addEventHandler(BTN_CLICKED, WEAK_DELEGATE( Item::onClicked, asWeak(*this))); + m_btn.addEventHandler(ATSPI_HIGHLIGHTED, WEAK_DELEGATE( + Item::onHighlighted, asWeak(*this))); + m_btn.addEventHandler(ATSPI_UNHIGHLIGHTED, WEAK_DELEGATE( + Item::onUnhighlighted, asWeak(*this))); elm_atspi_accessible_gesture_cb_set(m_btn, CALLBACK_A(Item::onAtspiGesture), this); @@ -329,6 +350,11 @@ namespace gallery { return; } + if (m_isHighlighted && m_imageGrid.m_highlightTimeout) { + m_imageGrid.m_isHighlightLocked = true; + elm_atspi_component_highlight_clear(m_btn); + } + const int itemIndex = m_realizeIndex; m_realizeIndex = -1; @@ -496,32 +522,59 @@ namespace gallery { void onClicked(Widget &widget, void *eventInfo) { - if (isRealized()) { - m_imageGrid.handleItemEvent(m_realizeIndex, - ITEM_EVENT_CLICK, -1, -1); + if (!isRealized()) { + LOG_RETURN_VOID(RES_ILLEGAL_STATE, "Item is not realized!"); } + m_imageGrid.handleItemEvent(m_realizeIndex, + ITEM_EVENT_CLICK, -1, -1); } void onDoubleTap(const int x, const int y) { - if (isRealized()) { - m_imageGrid.handleItemEvent(m_realizeIndex, - ITEM_EVENT_DOUBLE_TAP, x, y); + if (!isRealized()) { + LOG_RETURN_VOID(RES_ILLEGAL_STATE, "Item is not realized!"); } + m_imageGrid.handleItemEvent(m_realizeIndex, + ITEM_EVENT_DOUBLE_TAP, x, y); } void onTapAndHold(const int x, const int y) { - if (isRealized()) { - m_imageGrid.handleItemEvent(m_realizeIndex, - ITEM_EVENT_TAP_AND_HOLD, x, y); + if (!isRealized()) { + LOG_RETURN_VOID(RES_ILLEGAL_STATE, "Item is not realized!"); + } + m_imageGrid.handleItemEvent(m_realizeIndex, + ITEM_EVENT_TAP_AND_HOLD, x, y); + } + + void onHighlighted(Widget &widget, void *eventInfo) + { + if (m_isHighlighted) { + return; + } + m_isHighlighted = true; + if (!isRealized()) { + LOG_RETURN_VOID(RES_ILLEGAL_STATE, "Item is not realized!"); + } + m_imageGrid.onItemHighlighted(m_realizeIndex); + } + + void onUnhighlighted(Widget &widget, void *eventInfo) + { + if (!m_isHighlighted) { + return; + } + m_isHighlighted = false; + if (!isRealized()) { + LOG_RETURN_VOID(RES_ILLEGAL_STATE, "Item is not realized!"); } + m_imageGrid.onItemUnhighlighted(m_realizeIndex); } Eina_Bool onAtspiGesture(Elm_Atspi_Gesture_Info gestureInfo, Evas_Object *obj) { - if (m_realizeIndex == -1) { + if (!isRealized()) { LOG_RETURN_VALUE(RES_ILLEGAL_STATE, EINA_FALSE, "Item is not realized!"); } @@ -565,6 +618,7 @@ namespace gallery { bool m_isImageLoaded = false; bool m_isClicksBlocked = false; bool m_isSelected = false; + bool m_isHighlighted = false; }; public: @@ -736,7 +790,10 @@ namespace gallery { m_animator(nullptr), m_scrollLockIndex(0), m_isInSelectMode(selectModeStartup), - m_isRotaryActive(false) + m_isRotaryActive(false), + + m_highlightID(-1), + m_isHighlightLocked(false) { prepare(); @@ -809,6 +866,8 @@ namespace gallery { createCircleScroller(); + createHighlighKeeper(); + m_scroller->addEventHandler(WidgetEvent::RESIZE, WEAK_DELEGATE(ImageGrid::onScrollerResize, asWeak(*this))); @@ -841,6 +900,30 @@ namespace gallery { } } + void ImageGrid::createHighlighKeeper() + { + m_highlighKeeper = Layout::Builder(). + setTheme(impl::LAYOUT_FAKE_ACCESS_OBJECT). + setIsOwner(true). + build(*m_box.getWindow()); + UCL_ASSERT(m_highlighKeeper, "m_highlighKeeper is NULL"); + + m_highlighKeeper->setGeometry(0, 0, 1, 1); + show(*m_highlighKeeper); + + elm_atspi_accessible_reading_info_type_set(*m_highlighKeeper, 0); + + elm_atspi_accessible_gesture_cb_set(*m_highlighKeeper, + [](void *, Elm_Atspi_Gesture_Info, Evas_Object *) -> Eina_Bool + { + return EINA_TRUE; + }, + nullptr); + + m_highlighKeeper->addEventHandler(ATSPI_UNHIGHLIGHTED, + WEAK_DELEGATE(ImageGrid::onKeeperUnhighlighted, asWeak(*this))); + } + void ImageGrid::setListener(IImageGridListener *const listener) { m_listener = listener; @@ -1117,19 +1200,15 @@ namespace gallery { return doWithCell(itemIndex, [this, &showFunc](const int slotIndex, const int itemOffset) { - const int extraPadding = ((slotIndex & 1) ? - m_info.calcExtraPaddingSize(m_slotSize) : 0); - - const int maxOffest = ((slotIndex / 2) * m_slotSize); - const int minOffset = (maxOffest + extraPadding - - ((m_scrollerSize / m_slotSize) - 1) * m_slotSize); - if ((m_scrollOffset >= minOffset) && - (m_scrollOffset <= maxOffest)) { + int minVisibleOffset = 0; + int maxVisibleOffset = 0; + if (isItemFullyVisible(slotIndex, itemOffset, + minVisibleOffset, maxVisibleOffset)) { return RES_OK; } - const int scrollOffset = ((m_scrollOffset > maxOffest) ? - maxOffest : minOffset); + const int scrollOffset = ((m_scrollOffset > maxVisibleOffset) ? + maxVisibleOffset : minVisibleOffset); if (m_info.isHorizontal) { showFunc(*m_scroller, scrollOffset, 0, m_scrollerSize, 1); } else { @@ -1140,6 +1219,47 @@ namespace gallery { }); } + bool ImageGrid::isItemFullyVisible(int itemIndex) + { + int minVisibleOffset = 0; + int maxVisibleOffset = 0; + return isItemFullyVisible(itemIndex, + minVisibleOffset, maxVisibleOffset); + } + + bool ImageGrid::isItemFullyVisible(const int itemIndex, + int &minVisibleOffset, int &maxVisibleOffset) const + { + return (doWithCell(itemIndex, + [this, &minVisibleOffset, &maxVisibleOffset]( + const int slotIndex, const int itemOffset) + { + return (isItemFullyVisible(slotIndex, itemOffset, + minVisibleOffset, maxVisibleOffset) ? + RES_OK : RES_FALSE); + } + ) == RES_OK); + } + + bool ImageGrid::isItemFullyVisible( + const int slotIndex, const int itemOffset, + int &minVisibleOffset, int &maxVisibleOffset) const + { + const int extraPadding = ((slotIndex & 1) ? + m_info.calcExtraPaddingSize(m_slotSize) : 0); + + maxVisibleOffset = ((slotIndex / 2) * m_slotSize); + minVisibleOffset = (maxVisibleOffset + extraPadding - + ((m_scrollerSize / m_slotSize) - 1) * m_slotSize); + + if ((m_scrollOffset >= minVisibleOffset) && + (m_scrollOffset <= maxVisibleOffset)) { + return true; + } + + return false; + } + void ImageGrid::forceBoxSizeCalculate() { for (int i = 0; i < m_slotCount; ++i) { @@ -1196,6 +1316,83 @@ namespace gallery { } } + void ImageGrid::onItemHighlighted(const int itemIndex) + { + m_highlightID = itemIndex; + m_highlightTimeout.reset(); + } + + void ImageGrid::onItemUnhighlighted(const int itemIndex) + { + if (m_highlightID == itemIndex) { + m_highlightID = (-1 - itemIndex); + if (m_isHighlightLocked) { + elm_atspi_component_highlight_grab(*m_highlighKeeper); + } else { + m_highlightTimeout.reset(); + } + } else { + WLOG("Item was not highlighted: %d.", itemIndex); + } + } + + void ImageGrid::onKeeperUnhighlighted(Widget &sender, void *eventInfo) + { + m_isHighlightLocked = false; + m_highlightTimeout.reset(); + } + + void ImageGrid::updateHighlightTimeout() + { + if (m_highlightID >= 0) { + if (isItemFullyVisible(m_highlightID)) { + m_highlightTimeout.reset(); + return; + } + } else if (!m_isHighlightLocked) { + return; + } + + m_highlightTimeout = Timeout::create( + impl::SCROLL_HIGHLIGHT_TIMEOUT_SEC, WEAK_DELEGATE( + ImageGrid::onHighlightTimeout, asWeak(*this))); + } + + void ImageGrid::onHighlightTimeout(Timeout *sender) + { + m_highlightTimeout.reset(); + + int itemIndex = ((m_highlightID >= 0) ? + m_highlightID : (-1 - m_highlightID)); + bool found = false; + + for (int i = m_info.getHighlightScanRange(); ((i >= 0) && + (itemIndex >= 0) && (itemIndex < m_itemCount)); --i) { + int minVisibleOffset = 0; + int maxVisibleOffset = 0; + if (isItemFullyVisible(itemIndex, + minVisibleOffset, maxVisibleOffset)) { + found = true; + } else if (m_scrollOffset > maxVisibleOffset) { + ++itemIndex; + } else { + --itemIndex; + } + } + + if (!found) { + itemIndex = getScrolledToItemIndex(); + } + + FAIL_RETURN_VOID(doWithItem(itemIndex, + [](Slot &slot, const int itemOffset) + { + elm_atspi_component_highlight_grab( + slot.getItemAtspi(itemOffset)); + return RES_OK; + }), "Failed to get item Atspi!"); + } + Elm_Interface_Atspi_Accessible *ImageGrid::requestAtspi(const int itemIndex) { if ((itemIndex < 0) || (itemIndex >= m_itemCount)) { @@ -1563,9 +1760,12 @@ namespace gallery { } ++m_eventsLock; - if (updateScrollOffset() && updateBeginSlotIndex()) { - realizeSlots(); - updateRectMins(); + if (updateScrollOffset()) { + if (updateBeginSlotIndex()) { + realizeSlots(); + updateRectMins(); + } + updateHighlightTimeout(); } --m_eventsLock; diff --git a/src/view/common.h b/src/view/common.h index e1d87b0..b6bcb12 100644 --- a/src/view/common.h +++ b/src/view/common.h @@ -29,6 +29,9 @@ namespace gallery { constexpr ucl::SmartEvent BTN_CLICKED {"clicked"}; constexpr ucl::SmartEvent POPUP_DISMISSED {"dismissed"}; + constexpr ucl::SmartEvent ATSPI_HIGHLIGHTED {"atspi,highlighted"}; + constexpr ucl::SmartEvent ATSPI_UNHIGHLIGHTED {"atspi,unhighlighted"}; + constexpr ucl::ElmStyle SCROLLER_STYLE {"effect"}; constexpr ucl::ElmStyle NAVIFRAME_NO_CLIP {"gallery_no_clip"}; diff --git a/ucl/inc/ucl/gui/types.h b/ucl/inc/ucl/gui/types.h index f4deb13..3ed1afa 100644 --- a/ucl/inc/ucl/gui/types.h +++ b/ucl/inc/ucl/gui/types.h @@ -22,8 +22,8 @@ #include "ucl/util/types.h" #include "ucl/util/memory.h" #include "ucl/util/delegation.h" +#include "ucl/util/smartDelegation.h" -#include "ucl/misc/smartDelegation.h" #include "ucl/misc/Aspect.h" #include "ucl/misc/TString.h" #include "ucl/misc/Variant.h" diff --git a/ucl/inc/ucl/misc/Timeout.h b/ucl/inc/ucl/misc/Timeout.h new file mode 100644 index 0000000..707c25c --- /dev/null +++ b/ucl/inc/ucl/misc/Timeout.h @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UCL_MISC_TIMEOUT_H__ +#define __UCL_MISC_TIMEOUT_H__ + +#include + +#include "ucl/util/types.h" +#include "ucl/util/smartDelegation.h" + +namespace ucl { + + UCL_DECLARE_REF_ALIASES(Timeout); + + class Timeout final : public NonCopyable { + public: + using TimeoutHandler = WeakDelegate; + + public: + static TimeoutSRef create(double timeoutSec, + const TimeoutHandler &handler); + + bool isExpired() const; + + private: + friend class RefCountObj; + Timeout(const TimeoutHandler &handler); + ~Timeout(); + + Result prepare(double timeoutSec); + + Eina_Bool onTimer(); + + private: + Ecore_Timer *m_timer; + TimeoutHandler m_handler; + }; +} + +#endif // __UCL_MISC_TIMEOUT_H__ diff --git a/ucl/inc/ucl/misc/smartDelegation.h b/ucl/inc/ucl/misc/smartDelegation.h deleted file mode 100644 index f921743..0000000 --- a/ucl/inc/ucl/misc/smartDelegation.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Flora License, Version 1.1 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UCL_MISC_SMART_DELEGATION_H__ -#define __UCL_MISC_SMART_DELEGATION_H__ - -#include "smartDelegation/WeakDelegate.h" - -#include "smartDelegation/macro.h" - -#if (UCL_INCLUDE_SMART_DELEGATION_SHORT_MACRO_H) -#include "smartDelegation/shortMacro.h" -#endif - -#endif // __UCL_MISC_SMART_DELEGATION_H__ diff --git a/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.h b/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.h deleted file mode 100644 index 0a5e976..0000000 --- a/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Flora License, Version 1.1 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UCL_MISC_SMART_DELEGATION_WEAK_DELEGATE_H__ -#define __UCL_MISC_SMART_DELEGATION_WEAK_DELEGATE_H__ - -#include "ucl/util/delegation.h" -#include "ucl/util/memory.h" - -namespace ucl { - - template - class WeakDelegate; - - template - class WeakDelegate : - public BaseDelegate> { - public: - using BaseDelegate>::BaseDelegate; - - template - static WeakDelegate make(const WeakRef &data) noexcept; - - template - static WeakDelegate make(const WeakRef &data) noexcept; - }; -} - -#include "WeakDelegate.hpp" - -#endif // __UCL_MISC_SMART_DELEGATION_WEAK_DELEGATE_H__ diff --git a/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.hpp b/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.hpp deleted file mode 100644 index e4b4b5d..0000000 --- a/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Flora License, Version 1.1 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace ucl { - - template - template - inline WeakDelegate WeakDelegate::make( - const WeakRef &data) noexcept - { - return {data, WeakDelegate::Cb::template stubA}; - } - - template - template - inline WeakDelegate WeakDelegate::make( - const WeakRef &data) noexcept - { - return {constRefCast(data), - WeakDelegate::Cb::template stubA}; - } -} diff --git a/ucl/inc/ucl/misc/smartDelegation/macro.h b/ucl/inc/ucl/misc/smartDelegation/macro.h deleted file mode 100644 index 5368eda..0000000 --- a/ucl/inc/ucl/misc/smartDelegation/macro.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Flora License, Version 1.1 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UCL_MISC_SMART_DELEGATION_MACRO_H__ -#define __UCL_MISC_SMART_DELEGATION_MACRO_H__ - -#define UCL_WEAK_DELEGATE(FUNC, DATA) \ - _UCL_DELEGATE(::ucl::WeakDelegate, FUNC, DATA) - -#endif // __UCL_MISC_SMART_DELEGATION_MACRO_H__ diff --git a/ucl/inc/ucl/misc/smartDelegation/shortMacro.h b/ucl/inc/ucl/misc/smartDelegation/shortMacro.h deleted file mode 100644 index 43c1ec3..0000000 --- a/ucl/inc/ucl/misc/smartDelegation/shortMacro.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Flora License, Version 1.1 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UCL_MISC_SMART_DELEGATION_SHORT_MACRO_H__ -#define __UCL_MISC_SMART_DELEGATION_SHORT_MACRO_H__ - -#define WEAK_DELEGATE(FUNC, DATA) UCL_WEAK_DELEGATE(FUNC, DATA) - -#endif // __UCL_MISC_SMART_DELEGATION_SHORT_MACRO_H__ diff --git a/ucl/inc/ucl/util/smartDelegation.h b/ucl/inc/ucl/util/smartDelegation.h new file mode 100644 index 0000000..6714411 --- /dev/null +++ b/ucl/inc/ucl/util/smartDelegation.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UCL_UTIL_SMART_DELEGATION_H__ +#define __UCL_UTIL_SMART_DELEGATION_H__ + +#include "smartDelegation/WeakDelegate.h" + +#include "smartDelegation/macro.h" + +#if (UCL_INCLUDE_SMART_DELEGATION_SHORT_MACRO_H) +#include "smartDelegation/shortMacro.h" +#endif + +#endif // __UCL_UTIL_SMART_DELEGATION_H__ diff --git a/ucl/inc/ucl/util/smartDelegation/WeakDelegate.h b/ucl/inc/ucl/util/smartDelegation/WeakDelegate.h new file mode 100644 index 0000000..0d29f0f --- /dev/null +++ b/ucl/inc/ucl/util/smartDelegation/WeakDelegate.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UCL_UTIL_SMART_DELEGATION_WEAK_DELEGATE_H__ +#define __UCL_UTIL_SMART_DELEGATION_WEAK_DELEGATE_H__ + +#include "ucl/util/delegation.h" +#include "ucl/util/memory.h" + +namespace ucl { + + template + class WeakDelegate; + + template + class WeakDelegate : + public BaseDelegate> { + public: + using BaseDelegate>::BaseDelegate; + + template + static WeakDelegate make(const WeakRef &data) noexcept; + + template + static WeakDelegate make(const WeakRef &data) noexcept; + }; +} + +#include "WeakDelegate.hpp" + +#endif // __UCL_UTIL_SMART_DELEGATION_WEAK_DELEGATE_H__ diff --git a/ucl/inc/ucl/util/smartDelegation/WeakDelegate.hpp b/ucl/inc/ucl/util/smartDelegation/WeakDelegate.hpp new file mode 100644 index 0000000..e4b4b5d --- /dev/null +++ b/ucl/inc/ucl/util/smartDelegation/WeakDelegate.hpp @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace ucl { + + template + template + inline WeakDelegate WeakDelegate::make( + const WeakRef &data) noexcept + { + return {data, WeakDelegate::Cb::template stubA}; + } + + template + template + inline WeakDelegate WeakDelegate::make( + const WeakRef &data) noexcept + { + return {constRefCast(data), + WeakDelegate::Cb::template stubA}; + } +} diff --git a/ucl/inc/ucl/util/smartDelegation/macro.h b/ucl/inc/ucl/util/smartDelegation/macro.h new file mode 100644 index 0000000..b117820 --- /dev/null +++ b/ucl/inc/ucl/util/smartDelegation/macro.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UCL_UTIL_SMART_DELEGATION_MACRO_H__ +#define __UCL_UTIL_SMART_DELEGATION_MACRO_H__ + +#define UCL_WEAK_DELEGATE(FUNC, DATA) \ + _UCL_DELEGATE(::ucl::WeakDelegate, FUNC, DATA) + +#endif // __UCL_UTIL_SMART_DELEGATION_MACRO_H__ diff --git a/ucl/inc/ucl/util/smartDelegation/shortMacro.h b/ucl/inc/ucl/util/smartDelegation/shortMacro.h new file mode 100644 index 0000000..ddf5e35 --- /dev/null +++ b/ucl/inc/ucl/util/smartDelegation/shortMacro.h @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UCL_UTIL_SMART_DELEGATION_SHORT_MACRO_H__ +#define __UCL_UTIL_SMART_DELEGATION_SHORT_MACRO_H__ + +#define WEAK_DELEGATE(FUNC, DATA) UCL_WEAK_DELEGATE(FUNC, DATA) + +#endif // __UCL_UTIL_SMART_DELEGATION_SHORT_MACRO_H__ diff --git a/ucl/inc/ucl/util/types/classTypes.h b/ucl/inc/ucl/util/types/classTypes.h index 89d33dd..1b1402d 100644 --- a/ucl/inc/ucl/util/types/classTypes.h +++ b/ucl/inc/ucl/util/types/classTypes.h @@ -51,7 +51,7 @@ namespace ucl { public: virtual IPRODUCT *newInstance() const = 0; protected: - ~IFactory() = default; + virtual ~IFactory() = default; }; template diff --git a/ucl/src/common.h b/ucl/src/common.h index f03d194..f358669 100644 --- a/ucl/src/common.h +++ b/ucl/src/common.h @@ -30,6 +30,6 @@ #include "ucl/util/shortLogs.h" #include "ucl/util/delegation/shortMacro.h" -#include "ucl/misc/smartDelegation/shortMacro.h" +#include "ucl/util/smartDelegation/shortMacro.h" #endif // __UCL_COMMON_H__ diff --git a/ucl/src/misc/Timeout.cpp b/ucl/src/misc/Timeout.cpp new file mode 100644 index 0000000..41a3d3f --- /dev/null +++ b/ucl/src/misc/Timeout.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ucl/misc/Timeout.h" + +#include "common.h" + +namespace ucl { + + TimeoutSRef Timeout::create(double timeoutSec, + const TimeoutHandler &handler) + { + auto result = makeShared(handler); + + FAIL_RETURN_VALUE(result->prepare(timeoutSec), {}, + "result->prepare() failed!"); + + return result; + } + + Timeout::Timeout(const TimeoutHandler &handler) : + m_timer(nullptr), + m_handler(handler) + { + } + + Timeout::~Timeout() + { + if (m_timer) { + ecore_timer_del(m_timer); + } + } + + Result Timeout::prepare(const double timeoutSec) + { + m_timer = ecore_timer_add(timeoutSec, + [](void *data) -> Eina_Bool + { + const auto self = static_cast(data); + self->m_timer = nullptr; + if (self->m_handler) { + self->m_handler(self); + } + return ECORE_CALLBACK_CANCEL; + }, + this); + + if (!m_timer) { + FAIL_RETURN(RES_FAIL, "ecore_timer_add() failed!"); + } + + return RES_OK; + } + + bool Timeout::isExpired() const + { + return !m_timer; + } +}