TizenRefApp-8433 [Gallery] Implement event and caching mechanism in Model 33/127533/1
authorIgor Nazarov <i.nazarov@samsung.com>
Thu, 27 Apr 2017 16:51:49 +0000 (19:51 +0300)
committerIgor Nazarov <i.nazarov@samsung.com>
Thu, 27 Apr 2017 16:58:37 +0000 (19:58 +0300)
- IMediaAlbum and Gallery interfaces extended. Reimplemented GalleryAlbum
  to cache MediaItems instead of requesting from DB each time;
- Fixed bux when transtion finished was not called from Naviframe in some
  cases;
- ucl::Event invoke() method renamed to dispatch();
- ucl::Event dispatch() method logic changed to not dispatch to a newly
  registered handlers while handling current event.

Change-Id: Ic8c99c4baca33aff104bbf221194207752677cbd

14 files changed:
inc/model/Gallery.h
inc/model/IMediaAlbum.h
src/model/Gallery.cpp
src/model/GalleryAlbum.cpp
src/model/GalleryAlbum.h
src/presenters/Instance.cpp
src/presenters/Page.cpp
ucl/inc/ucl/gui/Naviframe.h
ucl/inc/ucl/gui/Naviframe.hpp
ucl/inc/ucl/misc/Event.h
ucl/inc/ucl/misc/Event.hpp
ucl/src/appfw/SysEventProvider.cpp
ucl/src/gui/NaviItem.cpp
ucl/src/gui/Naviframe.cpp

index e3f994d2a7247b9bc864bf108bf720bcfce988c9..3026a7b10f94b915be8fbd24f7237446130af9f6 100644 (file)
@@ -26,6 +26,9 @@ namespace gallery {
                static GallerySRef newInstance();
                ~Gallery();
 
+               // TODO Temporary feature while support only offline mode
+               void updateAlbum();
+
                IMediaAlbumSRef getAlbum();
 
        private:
index c8933d19c530d0d068a2cc0740cce0881371de0f..81db7596c0448bc7a814d71fd4c07912bb34116b 100644 (file)
@@ -26,8 +26,13 @@ namespace gallery {
                using EachCb = ucl::Delegate<bool(MediaItemSRef &&media)>;
 
        public:
+               virtual void addChangeHandler(const NotiHandler &handler) = 0;
+               virtual void delChangeHandler(const NotiHandler &handler) = 0;
+
                virtual ucl::Result forEachMedia(EachCb cb) const = 0;
                virtual ucl::Result getMediaCount(int &count) const = 0;
+
+               virtual void defragment() = 0;
        };
 
        // Non-member functions //
index 73c804d9b1a829852ffe00136a73d8e37218c34e..c8e511a6ba2db078cba97cec1fd9026b6eedfe6a 100644 (file)
@@ -55,14 +55,28 @@ namespace gallery {
 
                m_isMediaDbConnected = true;
 
-               m_album = GalleryAlbum::newInstance();
-               if (!m_album) {
+               auto album = GalleryAlbum::newInstance();
+               if (!album) {
                        LOG_RETURN(RES_FAIL, "GalleryAlbum::newInstance() failed!");
                }
 
+               FAIL_RETURN(album->update(), "album->update() failed!");
+
+               m_album = std::move(album);
+
                return RES_OK;
        }
 
+       void Gallery::updateAlbum()
+       {
+               const auto album = dynamic_cast<GalleryAlbum *>(m_album.get());
+               if (album) {
+                       album->update();
+               } else {
+                       ELOG("m_album is not a GalleryAlbum!");
+               }
+       }
+
        IMediaAlbumSRef Gallery::getAlbum()
        {
                return m_album;
index 68326d9a90e29bc3043c31ae5a7d98676481088b..51be5db2262a799d245e454915f8c3f4ad1bdea5 100644 (file)
@@ -35,7 +35,8 @@ namespace gallery {
        using namespace ucl;
 
        GalleryAlbum::GalleryAlbum() :
-               m_filter(nullptr)
+               m_filter(nullptr),
+               m_isValid(false)
        {
        }
 
@@ -84,41 +85,95 @@ namespace gallery {
                return RES_OK;
        }
 
-       Result GalleryAlbum::forEachMedia(EachCb cb) const
+       Result GalleryAlbum::update()
        {
-               MutexLock lock(getMediaMutex());
-
-               const int ret = media_info_foreach_media_from_db(m_filter,
-                       [](media_info_h media, void *user_data)
-                       {
-                               auto item = MediaItem::newInstance(media);
-                               if (!item) {
-                                       ELOG("MediaItem::newInstance() failed! Skipping");
+               Items newItems;
+
+               {
+                       MutexLock lock(getMediaMutex());
+
+                       const int ret = media_info_foreach_media_from_db(m_filter,
+                               [](media_info_h media, void *user_data)
+                               {
+                                       Items &newItems = (*static_cast<Items *>(user_data));
+                                       auto item = MediaItem::newInstance(media);
+                                       if (!item) {
+                                               ELOG("MediaItem::newInstance() failed! Skipping");
+                                               return true;
+                                       }
+                                       newItems.emplace_back(std::move(item));
                                        return true;
-                               }
-                               return (*static_cast<EachCb *>(user_data))(std::move(item));
-                       },
-                       &cb);
+                               },
+                               &newItems);
 
-               if (ret != 0) {
-                       ELOG("media_info_foreach_media_from_db() failed: %d", ret);
-                       return RES_FAIL;
+                       if (ret != 0) {
+                               ELOG("media_info_foreach_media_from_db() failed: %d", ret);
+                               return RES_FAIL;
+                       }
                }
 
+               swap(newItems, m_items);
+               m_isValid = true;
+
+               m_onChange.dispatch();
+
                return RES_OK;
        }
 
-       Result GalleryAlbum::getMediaCount(int &count) const
+       void GalleryAlbum::addChangeHandler(const NotiHandler &handler)
        {
-               MutexLock lock(getMediaMutex());
+               m_onChange += handler;
+       }
+
+       void GalleryAlbum::delChangeHandler(const NotiHandler &handler)
+       {
+               m_onChange -= handler;
+       }
 
-               const int ret = media_info_get_media_count_from_db(m_filter, &count);
-               if ((ret != 0) || (count < 0)) {
-                       count = 0;
-                       LOG_RETURN(RES_FAIL,
-                                       "media_info_foreach_media_from_db() failed: %d", ret);
+       Result GalleryAlbum::forEachMedia(EachCb cb) const
+       {
+               if (!m_isValid) {
+                       LOG_RETURN(RES_INVALID_DATA, "m_isValid: false;");
                }
 
+               for (auto item: m_items) {
+                       if (!item->isValid()) {
+                               WLOG("Fragmented!");
+                       } else if (!cb(std::move(item))) {
+                               break;
+                       }
+               }
+
+               return RES_OK;
+       }
+
+       Result GalleryAlbum::getMediaCount(int &count) const
+       {
+               if (!m_isValid) {
+                       LOG_RETURN(RES_INVALID_DATA, "m_isValid: false;");
+               }
+
+               count = m_items.size();
+
                return RES_OK;
        }
+
+       void GalleryAlbum::defragment()
+       {
+               if (!m_isValid) {
+                       LOG_RETURN_VOID(RES_INVALID_DATA, "m_isValid: false;");
+               }
+
+               const auto newEnd = std::remove_if(
+                       m_items.begin(), m_items.end(),
+                       [](const MediaItemSRef &item)
+                       {
+                               return !item->isValid();
+                       });
+
+               if (newEnd != m_items.end()) {
+                       m_items.erase(newEnd, m_items.end());
+                       m_onChange.dispatch();
+               }
+       }
 }
index f5816a792efcd0a3ae0d0cdf5edc51ff471b2043..027ce173bac40bb27056ee7e42916cfe99ca2367 100644 (file)
 #ifndef __GALLERY_MODEL_GALLERY_ALBUM_H__
 #define __GALLERY_MODEL_GALLERY_ALBUM_H__
 
+#include <vector>
+
+#include "ucl/misc/Event.h"
+
 #include "model/IMediaAlbum.h"
 
 namespace gallery {
@@ -28,19 +32,34 @@ namespace gallery {
                static GalleryAlbumSRef newInstance();
                virtual ~GalleryAlbum();
 
+               ucl::Result update();
+
                // IMediaAlbum //
 
+               virtual void addChangeHandler(
+                               const NotiHandler &handler) final override;
+               virtual void delChangeHandler(
+                               const NotiHandler &handler) final override;
+
                virtual ucl::Result forEachMedia(EachCb cb) const final override;
                virtual ucl::Result getMediaCount(int &count) const final override;
 
+               virtual void defragment() final override;
+
        private:
                friend class ucl::RefCountObj<GalleryAlbum>;
                GalleryAlbum();
 
                ucl::Result prepare();
 
+       private:
+               using Items = std::vector<MediaItemSRef>;
+
        private:
                filter_h m_filter;
+               ucl::Event<NotiHandler> m_onChange;
+               Items m_items;
+               bool m_isValid;
        };
 }
 
index debee11d0dc3b3e4f48710a94c54c995c636e2b0..a9f2d953e8b678d2d44e305164fc9523c89e8e1d 100644 (file)
@@ -153,6 +153,8 @@ namespace gallery {
 
                m_isScanInProgress = false;
 
+               m_gallery->updateAlbum();
+
                const auto thumbPage = dynamicRefCast<ThumbnailPage>(m_page);
 
                if (isNotEmpty(m_gallery->getAlbum())) {
index f1404f961402e2750ee49ecb852ddba7577658d5..c3d4f7bf40d163153367d7ff8ec9e9b535be0ae7 100644 (file)
@@ -81,7 +81,12 @@ namespace gallery {
 
        void Page::dispatchTopPageChanged()
        {
-               m_navi->callEvent(impl::TOP_PAGE_CHANGED, nullptr);
+               if (!m_navi->isInTransition()) {
+                       m_navi->callEvent(impl::TOP_PAGE_CHANGED, nullptr);
+               } else {
+                       WLOG("Forcig Transition Finished!");
+                       m_navi->setInTransition(false);
+               }
        }
 
        void Page::onItemDel(Evas_Object *obj, void *eventInfo)
index 5a6622242f4087a636735eec76e73e5141808673..0cf36f61531edfab3039c424ea1efb15cca13999 100644 (file)
@@ -43,6 +43,7 @@ namespace ucl {
                };
 
        public:
+               void setInTransition(bool inTransition);
                bool isInTransition() const;
 
                void setAutoBackBtn(bool value);
@@ -85,11 +86,8 @@ namespace ucl {
 
        private:
                friend class RefCountObj<Naviframe>;
-               friend class NaviItem;
                Naviframe(RefCountObjBase &rc, Evas_Object *eo);
 
-               void startTransition();
-
                void onTransitionFinished(Widget &widget, void *eventInfo);
 
        private:
index 4c56f4adc8c044362ed285ec9486ffba909ec7e4..e8fdc19087cd296c9921dbe1aa106f33f0b863df 100644 (file)
@@ -78,7 +78,7 @@ namespace ucl {
        {
                auto result = elm_naviframe_item_pop(getEo());
                if (getBottomItem()) {
-                       startTransition();
+                       setInTransition(true);
                }
                return result;
        }
@@ -91,7 +91,7 @@ namespace ucl {
                                nullptr, backBtn, moreBtn, content, style.name));
                result.setTitle(title);
                if (result != getBottomItem()) {
-                       startTransition();
+                       setInTransition(true);
                }
                return result;
        }
index efa93ceb3c625943108fd3ea0fb51d26b1411b75..420954ae25494eb4c4daee96c7b783d341f860c2 100644 (file)
@@ -36,13 +36,13 @@ namespace ucl {
                bool isEmpty() const;
 
                template <class ...ARGS>
-               void invoke(ARGS &&...args);
+               void dispatch(ARGS &&...args);
                template <class PREDICATE, class ...ARGS>
-               void invokePred(PREDICATE &&pred, ARGS &&...args);
+               void dispatchPred(PREDICATE &&pred, ARGS &&...args);
 
        private:
                template <class DO_INVOKE, class ...ARGS>
-               void invokeImpl(const DO_INVOKE &doInvoke, ARGS &&...args);
+               void dispatchImpl(const DO_INVOKE &doInvoke, ARGS &&...args);
 
                void lock();
                void unlock();
index 53e58a231a5f086494b7b1de7e200d386852c243..f0caec0837e4700e2abb95c0d01905307dbfd87d 100644 (file)
@@ -78,9 +78,9 @@ namespace ucl {
 
        template <class DELEGATE>
        template <class ...ARGS>
-       void Event<DELEGATE>::invoke(ARGS &&...args)
+       void Event<DELEGATE>::dispatch(ARGS &&...args)
        {
-               invokeImpl(
+               dispatchImpl(
                        [](const DELEGATE &delegate, ARGS &&...args)
                        {
                                delegate(std::forward<ARGS>(args)...);
@@ -91,9 +91,9 @@ namespace ucl {
 
        template <class DELEGATE>
        template <class PREDICATE, class ...ARGS>
-       void Event<DELEGATE>::invokePred(PREDICATE &&pred, ARGS &&...args)
+       void Event<DELEGATE>::dispatchPred(PREDICATE &&pred, ARGS &&...args)
        {
-               invokeImpl(
+               dispatchImpl(
                        [&pred](const DELEGATE &delegate, ARGS &&...args)
                        {
                                return impl::doInvokePred(std::forward<PREDICATE>(pred),
@@ -104,10 +104,11 @@ namespace ucl {
 
        template <class DELEGATE>
        template <class DO_INVOKE, class ...ARGS>
-       void Event<DELEGATE>::invokeImpl(const DO_INVOKE &doInvoke, ARGS &&...args)
+       void Event<DELEGATE>::dispatchImpl(const DO_INVOKE &doInvoke, ARGS &&...args)
        {
                lock();
-               for (size_t i = 0; i < m_delegates.size(); ++i) {
+               const auto size = m_delegates.size();
+               for (size_t i = 0; i < size; ++i) {
                        const auto &delegate = m_delegates[i];
                        if (delegate) {
                                if (!doInvoke(delegate, std::forward<ARGS>(args)...)) {
index 20ae94c6a4502abd19f1e75fb299e5050183e883..8958aaf401d5300888b2ff80aab12aa7a10c1960 100644 (file)
@@ -108,6 +108,6 @@ namespace ucl {
 
        void SysEventProvider::dispatch(SysEvent sysEvent)
        {
-               m_event.invoke(sysEvent);
+               m_event.dispatch(sysEvent);
        }
 }
index 052a8ea159215eb8d938f645b161adaba1a65ae4..dd212bfa9add22473914a287485f9c349d5b1641 100644 (file)
@@ -30,7 +30,7 @@ namespace ucl {
                elm_naviframe_item_pop_to(getIt());
 
                if (needStartTransition) {
-                       navi->startTransition();
+                       navi->setInTransition(true);
                }
        }
 
@@ -43,7 +43,7 @@ namespace ucl {
                elm_naviframe_item_promote(getIt());
 
                if (needStartTransition) {
-                       navi->startTransition();
+                       navi->setInTransition(true);
                }
        }
 }
index 1d78998e26a4f9b4bd9cbff3692110f7177f6b0c..881390c859983ab1d9bef404f94bcc06c9bfafa8 100644 (file)
@@ -55,11 +55,15 @@ namespace ucl {
                                Naviframe::onTransitionFinished, asWeak(*this)));
        }
 
-       void Naviframe::startTransition()
+       void Naviframe::setInTransition(const bool inTransition)
        {
-               if (!m_isInTransition) {
-                       m_isInTransition = true;
-                       callEvent(NAVI_TRANSITION_STARTED);
+               if (inTransition != m_isInTransition) {
+                       m_isInTransition = inTransition;
+                       if (inTransition) {
+                               callEvent(NAVI_TRANSITION_STARTED);
+                       } else {
+                               callEvent(NAVI_TRANSITION_FINISHED);
+                       }
                }
        }