Polish up the view life-cycle logic. 70/101270/3
authorHermet Park <hermet@hermet.pe.kr>
Wed, 30 Nov 2016 13:02:52 +0000 (22:02 +0900)
committerHermet Park <chuneon.park@samsung.com>
Wed, 30 Nov 2016 13:08:50 +0000 (05:08 -0800)
Add a new c++ api destroyView() to delete a view.
Since the destructor does not guarantee the virtual functions for view's lifecycle.
We cannot call such the view state function ie, onDestroy() in the destructor.
Instead, we introduce the destroyView() member function to deal with this.

Additionally, change the behavior of the onActivate(), Deactivate(), onUnload(), onPause() ...
Those states will be called only if the view's content is existed.

Change-Id: I63241b1173e80283cff4ed8201f287e03949cf44

src/lib/efl/mobile/c/ui_view.cpp
src/lib/interface/UiIfaceOverlay.cpp
src/lib/interface/UiIfaceView.cpp
src/lib/interface/UiIfaceViewmgr.cpp

index b9e925df5183b4a30c20b9db2c490bf9878e08d4..a35b57a960df5cc30c53cef5c8016c0ef4ff8263 100644 (file)
@@ -383,12 +383,7 @@ EAPI Eo *ui_view_get_content(const ui_view *view)
 
 EAPI int ui_view_destroy(ui_view *view)
 {
-       int ret = validate_view(view);
-       if (ret != UI_VIEWMGR_ERROR_NONE) return ret;
-
-       delete (view);
-
-       return UI_VIEWMGR_ERROR_NONE;
+       return UI_VIEWMGR->destroyView(view);
 }
 
 EAPI int ui_view_set_content(ui_view *view, Eo *content)
index 5b7c76bf22e7f314c48cfe7dace3c5a95fa84710..f56b6264e00296d8180296771b7c481997f28f13 100644 (file)
@@ -118,7 +118,9 @@ void UiIfaceOverlay::onBack()
 
 int UiIfaceOverlay::activate()
 {
-       this->_impl->_view->onPause();
+       if (this->_impl->_view->getContent()) {
+               this->_impl->_view->onPause();
+       }
 
        return UI_VIEWMGR_ERROR_NONE;
 }
index 81242726ce159a436d6c8e1d25271e3b81f5b349..88c7fa5c59004c625f9da6e5762e9c535ff5e9f2 100644 (file)
@@ -130,6 +130,7 @@ void UiIfaceViewImpl::onResume() noexcept
 
 void UiIfaceViewImpl::onDestroy() noexcept
 {
+       this->_state = UI_VIEW_STATE_DESTROY;
 }
 
 UiIfaceViewImpl::UiIfaceViewImpl(UiIfaceView *view, const char *name)
@@ -154,10 +155,6 @@ UiIfaceViewImpl::~UiIfaceViewImpl()
                        this->_viewmgr->popViewFinished(pview);
                        activateTopView = true;
                }
-
-               this->_view->onDeactivate();
-               this->_view->onUnload();
-               this->_view->onDestroy();
        }
 
        if (this->_viewmgr) {
index 8f69e562bde0535f67797848ea244cf05ed761fa..2d73bf8f627d377140b04b3679f47f5cdf40cdc2 100644 (file)
@@ -164,12 +164,14 @@ void UiIfaceViewmgrImpl::pushViewFinished(UiIfaceView *view)
 
        //The previous view has been pushed. This should be unload.
        if (last != view) {
-               view->onUnload();
+               if (view->getContent()) {
+                       view->onUnload();
+               }
                return;
        }
 
        //A new view has been pushed. This should be activate.
-       view->onActivate();
+       if (view->getContent()) view->onActivate();
        this->setEventBlock(view, false);
 }
 
@@ -179,14 +181,12 @@ void UiIfaceViewmgrImpl::popViewFinished(UiIfaceView *view)
 
        //This view has been popped. It should be destroyed.
        if (last == view) {
-               view->onUnload();
-               view->onDestroy();
-               delete (view);
+               this->_inst->destroyView(view);
                return;
        }
 
        //The previous view has been popped. It should become activate.
-       view->onActivate();
+       if (view->getContent()) view->onActivate();
        this->setEventBlock(view, false);
        view->_setPopping(false);
 }
@@ -200,18 +200,15 @@ UiIfaceViewmgrImpl::~UiIfaceViewmgrImpl()
 {
        //Terminate views
        this->_destroying = EINA_TRUE;
+
        for (auto ritr = this->_viewList.rbegin(); ritr != this->_viewList.rend(); ritr++) {
                auto view = *ritr;
-               if ((view->getState() != UI_VIEW_STATE_DEACTIVATE) &&
-                       (view->getState() != UI_VIEW_STATE_UNLOAD)) {
-                       view->onDeactivate();
-               }
-               if (view->getState() != UI_VIEW_STATE_UNLOAD) {
-                       view->onUnload();
+               if (view->getState() == UI_VIEW_STATE_DESTROY) {
+                       continue;
                }
-
                view->onDestroy();
-               delete (view);
+               view->_setViewmgr(nullptr);
+               delete(view);
        }
        this->_destroying = EINA_FALSE;
 
@@ -239,7 +236,9 @@ int UiIfaceViewmgrImpl::pushView(UiIfaceView *view)
        //Previous view
        if (this->_viewList.size() > 0) {
                pview = this->_viewList.back();
-               pview->onDeactivate();
+               if (pview->getContent()) {
+                       pview->onDeactivate();
+               }
                this->setEventBlock(pview, true);
        }
 
@@ -275,16 +274,15 @@ int UiIfaceViewmgrImpl::popView()
        if (this->getViewCount() == 1) {
                //destroy viewmgr?
                UiIfaceView*view = this->_viewList.back();
-               view->onDeactivate();
-               view->onUnload();
-               view->onDestroy();
-               delete(view);
+               this->_inst->destroyView(view);
 
                return UI_VIEWMGR_ERROR_NONE;
        }
 
        view->_setPopping(true);
-       view->onDeactivate();
+       if (view->getContent()) {
+               view->onDeactivate();
+       }
        this->setEventBlock(view, true);
 
        //Below object has to be used in child class...
@@ -294,7 +292,6 @@ int UiIfaceViewmgrImpl::popView()
        auto pview = *nx;
        pview->_setPopping(true);
        if (!pview->getContent()) pview->onLoad();
-       pview->onDeactivate();
        this->setEventBlock(pview, true);
 
        return UI_VIEWMGR_ERROR_NONE;
@@ -305,7 +302,6 @@ int UiIfaceViewmgrImpl::insertViewBefore(UiIfaceView *view, UiIfaceView *before)
        if (!view) {
                LOGE("invalid view argument. view(nullptr)");
                return UI_VIEWMGR_ERROR_INVALID_PARAMETER;
-
        }
 
        if (view == before) {
@@ -393,7 +389,7 @@ int UiIfaceViewmgrImpl::activate()
        auto view = this->getLastView();
 
        if (!view->getContent()) view->onLoad();
-       view->onActivate();
+       if (view->getContent()) view->onActivate();
 
        this->_inst->activateTopView();
 
@@ -407,11 +403,10 @@ int UiIfaceViewmgrImpl::deactivate()
 
        auto view = this->getLastView();
 
-       if ((view->getState() != UI_VIEW_STATE_DEACTIVATE) &&
-               (view->getState() != UI_VIEW_STATE_UNLOAD)) {
-               view->onDeactivate();
-       }
-       if (view->getState() != UI_VIEW_STATE_UNLOAD) {
+       if (view->getContent()) {
+               if ((view->getState() == UI_VIEW_STATE_ACTIVATE) || (view->getState() == UI_VIEW_STATE_PAUSE)) {
+                       view->onDeactivate();
+               }
                view->onUnload();
        }
 
@@ -555,3 +550,29 @@ UiIfaceViewmgr* UiIfaceViewmgr::getInstance()
 {
        return UiIfaceViewmgrImpl::getInstance();
 }
+
+int UiIfaceViewmgr::destroyView(UiIfaceView *view)
+{
+       if (!view) {
+               LOGE("invalid view argument. view(nullptr)");
+               return UI_VIEWMGR_ERROR_INVALID_PARAMETER;
+       }
+
+       if (view->getState() == UI_VIEW_STATE_DESTROY)
+       {
+               LOGE("this view(%p) is already on destroying");
+               return UI_VIEWMGR_ERROR_ALREADY_IN_PROGRESS;
+       }
+
+       if (view->getContent()) {
+               if ((view->getState() == UI_VIEW_STATE_ACTIVATE) || (view->getState() == UI_VIEW_STATE_PAUSE)) {
+                       view->onDeactivate();
+               }
+               view->onUnload();
+       }
+       view->onDestroy();
+
+       delete(view);
+
+       return UI_VIEWMGR_ERROR_NONE;
+}