Example #1
0
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        proxy = weakref.proxy(self)
        self.__containers = {}
        for container in containers:
            raise isinstance(container, AbstractViewContainer) or AssertionError
            self.__containers[container.getViewType()] = container(proxy)

        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()
Example #2
0
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        self.__globalContainer = _GlobalViewContainer(weakref.proxy(self))
        for container in containers:
            raise isinstance(container, ViewContainer) or AssertionError
            self.__globalContainer.addChildContainer(container)

        self.__loader = loader
        self.__loader.onViewLoaded += self.__onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()
        self.__viewCache = _ViewCollection()
        self.__chainMng = _ChainManager(weakref.proxy(self))
Example #3
0
 def __init__(self, loader):
     super(ContainerManager, self).__init__()
     proxy = weakref.proxy(self)
     self.__containers = {
         ViewTypes.DEFAULT: _DefaultContainer(proxy),
         ViewTypes.CURSOR: _DefaultContainer(proxy),
         ViewTypes.WAITING: _DefaultContainer(proxy),
         ViewTypes.WINDOW: _PopUpContainer(proxy),
         ViewTypes.BROWSER: _PopUpContainer(proxy),
         ViewTypes.TOP_WINDOW: _PopUpContainer(proxy),
         ViewTypes.SERVICE_LAYOUT: _DefaultContainer(proxy)
     }
     self._loadingViews = dict()
     self.__loader = loader
     self.__loader.onViewLoaded += self.__loader_onViewLoaded
     self.__scopeController = GlobalScopeController()
     self.__scopeController.create()
Example #4
0
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        proxy = weakref.proxy(self)
        self.__containers = {}
        for container in containers:
            raise isinstance(container, AbstractViewContainer) or AssertionError
            self.__containers[container.getViewType()] = container(proxy)

        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()
Example #5
0
 def __init__(self, loader):
     super(ContainerManager, self).__init__()
     proxy = weakref.proxy(self)
     self.__containers = {ViewTypes.DEFAULT: _DefaultContainer(proxy),
      ViewTypes.CURSOR: _DefaultContainer(proxy),
      ViewTypes.WAITING: _DefaultContainer(proxy),
      ViewTypes.WINDOW: _PopUpContainer(proxy),
      ViewTypes.BROWSER: _PopUpContainer(proxy),
      ViewTypes.TOP_WINDOW: _PopUpContainer(proxy),
      ViewTypes.SERVICE_LAYOUT: _DefaultContainer(proxy)}
     self._loadingViews = dict()
     self.__loader = loader
     self.__loader.onViewLoaded += self.__loader_onViewLoaded
     self.__scopeController = GlobalScopeController()
     self.__scopeController.create()
Example #6
0
class ContainerManager(ContainerManagerMeta):
    """
    Class of container manager.
    """
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        proxy = weakref.proxy(self)
        self.__containers = {}
        for container in containers:
            raise isinstance(container,
                             AbstractViewContainer) or AssertionError
            self.__containers[container.getViewType()] = container(proxy)

        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()

    def load(self, alias, name=None, *args, **kwargs):
        """
        Loads view to container.
        :param alias:
        :param name:
        :param args:
        :param kwargs:
        :return:
        """
        if name is None:
            name = alias
        isViewExists = self.as_getViewS(name)
        if not isViewExists and (alias, name) not in self._loadingViews:
            pyEntity = self.__loader.loadView(alias, name, *args, **kwargs)
            self.__scopeController.addLoadingView(pyEntity, False)
            curType = pyEntity.settings.type
            if self.canCancelPreviousLoading(curType):
                result = []
                for kev, val in self._loadingViews.iteritems():
                    if val.settings.type == pyEntity.settings.type:
                        result.append(val)

                if result:
                    self.__cancelLoadingForPyEntities(result)
            self._loadingViews[alias, name] = pyEntity
        return

    def canCancelPreviousLoading(self, containerType):
        container = self.getContainer(containerType)
        if container is not None:
            return container.canCancelPreviousLoading()
        else:
            return False
            return

    def addContainer(self, viewType, name, container=None):
        result = True
        if viewType not in self.__containers:
            if container is None:
                self.__containers[viewType] = DefaultContainer(
                    viewType, weakref.proxy(self))
                self.as_registerContainerS(viewType, name)
            elif isinstance(container, AbstractViewContainer):
                self.__containers[viewType] = container
                self.as_registerContainerS(viewType, name)
            else:
                LOG_ERROR('Container must be implemented IViewContainer',
                          container)
                result = False
        else:
            LOG_ERROR('Container already registered', viewType)
            result = False
        return result

    def removeContainer(self, viewType):
        self.__scopeController.removeSubScopeController(
            ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType())
        result = True
        if viewType in self.__containers:
            container = self.__containers[viewType]
            container.destroy()
            self.as_unregisterContainerS(viewType)
            del self.__containers[viewType]
        else:
            result = False
        return result

    def getContainer(self, viewType):
        if viewType in self.__containers:
            return self.__containers[viewType]
        else:
            return None

    def isModalViewsIsExists(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None and container.getViewCount(isModal=True):
                return True

        return False

    def getView(self, viewType, criteria=None):
        container = self.getContainer(viewType)
        if container is not None:
            view = container.getView(criteria=criteria)
        else:
            raise Exception('Container for %s view is None!' % viewType)
        return view

    def isViewAvailable(self, viewType, criteria=None):
        container = self.getContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False
            return

    def showContainers(self, *viewTypes):
        self.as_showContainersS(viewTypes)

    def hideContainers(self, *viewTypes):
        self.as_hideContainersS(viewTypes)

    def isContainerShown(self, viewType):
        return self.as_isContainerShownS(viewType)

    def closePopUps(self):
        self.as_closePopUpsS()

    def clear(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None:
                container.clear()

        return

    def removeLoadingView(self, alias, uniqueName):
        self._loadingViews.pop((alias, uniqueName), None)
        return

    def _dispose(self):
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__loader_onViewLoaded
            self.__loader = None
        for viewType in _CONTAINERS_DESTROY_ORDER:
            if viewType in self.__containers:
                container = self.__containers.pop(viewType)
                LOG_DEBUG('CONTAINER: {}/{}'.format(container, viewType))
                container.destroy()

        if len(self.__containers):
            LOG_ERROR('No all containers are destructed.')
        self.__containers.clear()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        self._loadingViews.clear()
        self._loadingViews = None
        super(ContainerManager, self)._dispose()
        return

    def __cancelLoadingForPyEntities(self, pyEntities):
        for curEntity in pyEntities:
            self._loadingViews.pop(
                (curEntity.settings.alias, curEntity.uniqueName))
            self.__loader.cancelLoadingByName(curEntity.uniqueName)
            curEntity.destroy()

    def __loader_onViewLoaded(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR('Type of view is not defined', pyView.settings)
        viewKey = (pyView.alias, pyView.uniqueName)
        if viewKey in self._loadingViews:
            self._loadingViews.pop(viewKey)
        if viewType in self.__containers:
            if ViewTypes.DEFAULT == viewType:
                self.closePopUps()
            if self.__scopeController.isViewLoading(pyView):
                container = self.__containers[viewType]
                if container.add(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    subContainerType = pyView.getSubContainerType()
                    if subContainerType is not None:
                        self.addContainer(subContainerType, pyView.uniqueName)
                    LOG_DEBUG('View added to container', pyView)
                    self.onViewAddedToContainer(container, pyView)
            else:
                LOG_DEBUG(
                    '"%s" view cancelled to load, because its scope has been destroyed.'
                    % str(pyView))
                self.as_hideS(pyView.uniqueName)
                pyView.destroy()
        else:
            LOG_ERROR('Type "%s" of view "%s" is not supported' %
                      (viewType, pyView))
        return
Example #7
0
class ContainerManager(ContainerManagerMeta, IContainerManager):
    """
    The container manager manages overlapping of views and their life time based on their type
    and scope. Performs loading of views through the specified loader.
    
    1. Overlapping of views
    UI consists of several layers. Each layer has its own Z index. It allows to control overlapping
    of views (views of the top level layer overlap views of underlying layers). The set of default
    layers depends on entry (application) type (lobby and battle have their own configuration).
    Each view can belong to one layer and it is defined by view's type. With each layer associated
    one view container that is managed by the container manager. There are two types of layers
    (view containers):
    - DefaultContainer - only one top level view can be placed in the container (layer) and if a
      new view is placed to it the previous one is destroyed;
    - PopUpContainer - several views can exist at the same time in one layer.
    Also any top level view can include a subview that is placed into a sub-container. If a top
    level view can include a sub-view, the sub-container is created after the top level view is loaded and
    initialized. When sub-view is loaded, it is placed into the top level view's sub-container. The sub-container
    is destroyed when the top level view is destroyed.
    
    2. Views life time
    The 'view scope' concept is introduced to simplify views lifetime management. View lifetime is
    defined by its scope and is controlled by the container manager through the scope controller.
    View scope defines when the view should be destroyed: if the parent view (parent scope) is
    destroyed, the subview is destroyed too. For details please see ScopeController description.
    """
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        self.__globalContainer = _GlobalViewContainer(weakref.proxy(self))
        for container in containers:
            raise isinstance(container, ViewContainer) or AssertionError
            self.__globalContainer.addChildContainer(container)

        self.__loader = loader
        self.__loader.onViewLoaded += self.__onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()
        self.__viewCache = _ViewCollection()
        self.__chainMng = _ChainManager(weakref.proxy(self))

    def _dispose(self):
        self.__viewCache.destroy()
        self.__chainMng.destroy()
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__onViewLoaded
            self.__loader = None
        for viewType in _CONTAINERS_DESTROY_ORDER:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                LOG_DEBUG('Destroy container {} ({})'.format(
                    viewType, container))
                container.destroy()

        self.__globalContainer.destroy()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        super(ContainerManager, self)._dispose()
        return

    def destroyViews(self, alias, name=None):
        def compareByAlias(view):
            return view.key.alias == alias

        def compareByAliasAndName(view):
            viewKey = view.key
            return viewKey.alias == alias and viewKey.name == name

        if name is None:
            comparator = compareByAlias
        else:
            comparator = compareByAliasAndName
        views = self.__scopeController.findViews(comparator)
        views.extend(self.__viewCache.findViews(comparator))
        for view in views:
            if not view.isDisposed():
                LOG_DEBUG('The view {} will be destroyed...'.format(view))
                view.destroy()

        viewKey = ViewKey(alias, name)
        chain = self.__chainMng.getChainByViewKey(viewKey)
        if chain is not None:
            chain.removeViewByViewKey(viewKey)
        return

    def loadChain(self, chainItems):
        """
        Loads the given views (chain items) one after the other.
        
        :param chainItems: list of ChainItem items.
        """
        chain = _LoadingChain(chainItems)
        if self.__chainMng.addChain(chain):
            chain.run()
        else:
            LOG_WARNING(
                'Could not add a new chain. Loading of chain [{}] is canceled.'
                .format(chainItems))
            chain.destroy()

    def load(self, loadParams, *args, **kwargs):
        """
        Loads a view with the given alias and puts it to the appropriate container (layer).
        
        :param loadParams: instance of ViewLoadParams
        :param args: args to be passed to view's constructor.
        :param kwargs: kwargs to be passed to view's constructor.
        :return: instance of view (loading or loaded). None if no view is loaded.
        """
        viewKey = loadParams.viewKey
        viewLoadingItem = self.__loader.getViewLoadingItem(viewKey)
        if viewLoadingItem is not None:
            LOG_DEBUG('View with key {} is already loading. item=[{}]'.format(
                viewKey, viewLoadingItem))
            view = viewLoadingItem.pyEntity
            if loadParams.loadMode == ViewLoadMode.DEFAULT:
                loadingViewLoadMode = viewLoadingItem.loadParams.loadMode
                if loadingViewLoadMode == ViewLoadMode.PRELOAD:
                    viewLoadingItem.loadParams = loadParams
                    self.__addLoadingView(view)
            elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                pass
            else:
                LOG_WARNING(
                    'Unsupported load mode {}. View loading will be skipped.'.
                    format(loadParams))
                view = None
        else:
            view = self.__globalContainer.findView(viewKey)
            if view is None:
                view = self.__viewCache.getView(viewKey)
                if view is None:
                    chain = self.__chainMng.getChainByViewKey(viewKey)
                    if chain is not None:
                        LOG_WARNING(
                            'View with loadParams={} is in the loading chain {}. The request will be skipped.'
                            .format(loadParams, chain))
                    else:
                        LOG_DEBUG(
                            'Load view with loadParams={}. Loader=[{}]'.format(
                                loadParams, self.__loader))
                        if loadParams.loadMode == ViewLoadMode.DEFAULT:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                            self.__addLoadingView(view)
                        elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                        else:
                            LOG_WARNING(
                                'Unsupported load mode {}. View loading will be skipped.'
                                .format(loadParams))
                elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                    LOG_DEBUG(
                        'View with key {} ({}) is already pre-loaded.'.format(
                            viewKey, view))
                elif loadParams.loadMode == ViewLoadMode.DEFAULT:
                    LOG_DEBUG(
                        'Load view with loadParams={} from the cache. Cache=[{}]'
                        .format(loadParams, self.__viewCache))
                    self.__viewCache.removeView(viewKey)
                    self.__showAndInitializeView(view)
                    view.validate(*args, **kwargs)
                else:
                    LOG_WARNING(
                        'Unsupported load mode {}. View loading will be skipped.'
                        .format(loadParams))
                    view = None
            else:
                LOG_DEBUG('View with key {} ({}) is already loaded.'.format(
                    viewKey, view))
                viewType = view.settings.type
                viewContainer = self.__globalContainer.findContainer(viewType)
                viewContainer.addView(view)
                view.validate(*args, **kwargs)
        return view

    def getContainer(self, viewType):
        """
        Returns container by the given type or None if there is no such container.
        
        :param viewType: viewType: View type. @see ViewTypes.
        """
        return self.__globalContainer.findContainer(viewType)

    def isModalViewsIsExists(self):
        """
        Returns True if a modal view exists, otherwise returns False.
        """
        for viewType in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None and container.getViewCount(isModal=True):
                return True

        return False

    def getView(self, viewType, criteria=None):
        """
        Gets view by the given type and criteria if it is defined.
        
        :param viewType: type of view. @see ViewTypes.
        :param criteria: criteria to find view in container.
        :return: instance of view.
        """
        container = self.__globalContainer.findContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria)
        else:
            LOG_WARNING('Could not found container {}.'.format(viewType))
            return

    def isViewAvailable(self, viewType, criteria=None):
        """
        If you want to get some view from some container, it`s may be
        unsafely operation. For example, I want to get a Hangar from a Lobby
        view. it`s a bad situation and method "getView" detects this state.
        Then, if you just want to detect an existing View, use isViewAvailable method.
        
        :param viewType: type of view. @see ViewTypes.
        :param criteria: criteria to find view in container.
        """
        container = self.__globalContainer.findContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False

    def showContainers(self, *viewTypes):
        """
        Shows containers for given view types.
        
        :param viewTypes: View types
        """
        self.as_showContainersS(viewTypes)

    def hideContainers(self, *viewTypes):
        """
        Hides containers for given view types.
        
        :param viewTypes: View types
        """
        self.as_hideContainersS(viewTypes)

    def isContainerShown(self, viewType):
        """
        Returns True if a container with the given view type is shown, otherwise returns False.
        
        :param viewType: View types
        """
        return self.as_isContainerShownS(viewType)

    def clear(self):
        """
        Clears pop-ups containers.
        """
        for viewType in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                container.clear()

        return

    def closePopUps(self):
        """
        Closes all popUps: widows and dialogs.
        """
        self.as_closePopUpsS()

    def registerViewContainer(self, viewType, uniqueName):
        self.as_registerContainerS(viewType, uniqueName)
        LOG_DEBUG(
            'A new container [type={}, name={}] has been registered.'.format(
                viewType, uniqueName))

    def unregisterViewContainer(self, viewType):
        self.as_unregisterContainerS(viewType)
        LOG_DEBUG(
            'The container [type={}] has been unregistered.'.format(viewType))

    def __addLoadingView(self, pyView):
        viewType = pyView.settings.type
        viewContainer = self.__globalContainer.findContainer(viewType)
        if viewContainer is not None:
            viewContainer.addLoadingView(pyView)
        else:
            LOG_WARNING(
                'Loading of view {} is requested but the container {} is still not exist!'
                .format(pyView, viewType))
        self.__scopeController.addLoadingView(pyView, False)
        return

    def __showAndInitializeView(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR(
                'Type of view is not defined. View {} will be destroyed.',
                pyView)
            pyView.destroy()
            return False
        else:
            status = False
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                if ViewTypes.DEFAULT == viewType:
                    self.closePopUps()
                if container.addView(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    self.onViewAddedToContainer(container, pyView)
                    status = True
                else:
                    LOG_ERROR(
                        '{} view cannot be added to container {} and will be destroyed.'
                        .format(pyView, container))
                    pyView.destroy()
            else:
                LOG_ERROR(
                    'Type {} of view {} is not supported or container has not been properly created'
                    .format(viewType, pyView))
                pyView.destroy()
            return status

    def __addViewToCache(self, pyView):
        view = self.__viewCache.getView(pyView.key)
        if view is not None:
            LOG_UNEXPECTED(
                'The view with key {} is already in the cache.'.format(
                    pyView.key), pyView, view)
            if view != pyView:
                view.destroy()
                if self.__viewCache.addView(pyView):
                    LOG_DEBUG('View {} has been added to the cache {}'.format(
                        pyView, self.__viewCache))
                else:
                    LOG_DEBUG('Cannot add view {} in the cache {}'.format(
                        pyView, self.__viewCache))
        elif self.__viewCache.addView(pyView):
            LOG_DEBUG('View {} has been added to the cache {}'.format(
                pyView, self.__viewCache))
        else:
            LOG_DEBUG('Cannot add view {} in the cache {}'.format(
                pyView, self.__viewCache))
        return

    def __onViewLoaded(self, pyView, loadParams):
        loadMode = loadParams.loadMode
        if loadMode == ViewLoadMode.DEFAULT:
            if self.__scopeController.isViewLoading(pyView=pyView):
                self.__showAndInitializeView(pyView)
            else:
                LOG_DEBUG(
                    '{} view loading is cancelled because its scope has been destroyed.'
                    .format(pyView))
                pyView.destroy()
        elif loadMode == ViewLoadMode.PRELOAD:
            self.__addViewToCache(pyView)
        else:
            LOG_WARNING(
                'Unsupported load mode {}. View {} will be destroyed.'.format(
                    loadMode, pyView))
            pyView.destroy()
Example #8
0
class ContainerManager(ContainerManagerMeta, IContainerManager):
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        self.onViewLoading = Event()
        self.onViewLoaded = Event()
        self.__globalContainer = _GlobalViewContainer(weakref.proxy(self))
        for container in containers:
            self.__globalContainer.addChildContainer(container)

        self.__loader = loader
        self.__loader.onViewLoadInit += self.__onViewLoadInit
        self.__loader.onViewLoaded += self.__onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()
        self.__viewCache = _ViewCollection()
        self.__chainMng = _ChainManager(weakref.proxy(self))

    def _dispose(self):
        self.__viewCache.destroy()
        self.__chainMng.destroy()
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__onViewLoaded
            self.__loader.onViewLoadInit -= self.__onViewLoadInit
            self.__loader = None
        for layer, layerName in enumerate(LAYER_NAMES.LAYER_ORDER):
            container = self.__globalContainer.findContainer(layer)
            if container is not None:
                _logger.debug('Destroy container %s (%r)', layerName,
                              container)
                container.destroy()

        self.__globalContainer.destroy()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        super(ContainerManager, self)._dispose()
        return

    def destroyViews(self, alias, name=None):
        def compareByAlias(view):
            return view.key.alias == alias

        def compareByAliasAndName(view):
            viewKey = view.key
            return viewKey.alias == alias and viewKey.name == name

        if name is None:
            comparator = compareByAlias
        else:
            comparator = compareByAliasAndName
        views = self.__scopeController.findViews(comparator)
        views.extend(self.__viewCache.findViews(comparator))
        for view in views:
            if not view.isDisposed():
                _logger.debug('The view %r will be destroyed...', view)
                view.destroy()

        viewKey = ViewKey(alias, name)
        chain = self.__chainMng.getChainByViewKey(viewKey)
        if chain is not None:
            chain.removeViewByViewKey(viewKey)
        return

    def loadChain(self, chainItems):
        chain = _LoadingChain(chainItems)
        if self.__chainMng.addChain(chain):
            chain.run()
        else:
            _logger.warning(
                'Could not add a new chain. Loading of chain [%r] is canceled.',
                chainItems)
            chain.destroy()

    def load(self, loadParams, *args, **kwargs):
        viewKey = loadParams.viewKey
        viewLoadingItem = self.__loader.getViewLoadingItem(viewKey)
        if viewLoadingItem is not None:
            _logger.debug('View with key %s is already loading. item=[%r]',
                          viewKey, viewLoadingItem)
            view = viewLoadingItem.pyEntity
            if loadParams.loadMode == ViewLoadMode.DEFAULT:
                loadingViewLoadMode = viewLoadingItem.loadParams.loadMode
                if loadingViewLoadMode == ViewLoadMode.PRELOAD:
                    viewLoadingItem.loadParams = loadParams
                    self.__addLoadingView(view)
            elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                pass
            else:
                _logger.warning(
                    'Unsupported load mode %r. View loading will be skipped.',
                    loadParams)
                view = None
        else:
            view = self.__globalContainer.findView(viewKey)
            if view is None:
                view = self.__viewCache.getView(viewKey)
                if view is None:
                    chain = self.__chainMng.getChainByViewKey(viewKey)
                    if chain is not None:
                        _logger.warning(
                            'View with loadParams=%r is in the loading chain %r. The request will be skipped.',
                            loadParams, chain)
                    else:
                        _logger.debug(
                            'Load view with loadParams=%r. Loader=[%r]',
                            loadParams, self.__loader)
                        if loadParams.loadMode == ViewLoadMode.DEFAULT:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                            self.__addLoadingView(view)
                        elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                        else:
                            _logger.warning(
                                'Unsupported load mode %r. View loading will be skipped.',
                                loadParams)
                elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                    _logger.debug(
                        'View with key %s (%r) is already pre-loaded.',
                        viewKey, view)
                elif loadParams.loadMode == ViewLoadMode.DEFAULT:
                    _logger.debug(
                        'Load view with loadParams=%r from the cache. Cache=[%r]',
                        loadParams, self.__viewCache)
                    self.__viewCache.removeView(viewKey)
                    self.__showAndInitializeView(view)
                    view.validate(*args, **kwargs)
                else:
                    _logger.warning(
                        'Unsupported load mode %r. View loading will be skipped.',
                        loadParams)
                    view = None
            else:
                _logger.debug('View with key %s (%r) is already loaded.',
                              viewKey, view)
                layer = view.layer
                viewContainer = self.__globalContainer.findContainer(layer)
                viewContainer.addView(view)
                view.validate(*args, **kwargs)
        return view

    def getContainer(self, layer):
        return self.__globalContainer.findContainer(layer)

    def getViewByKey(self, viewKey):
        if self.__loader is not None:
            loadingItem = self.__loader.getViewLoadingItem(viewKey)
            if loadingItem is not None:
                return loadingItem.pyEntity
        sources = (self.__globalContainer.findView, self.__viewCache.getView)
        for source in sources:
            view = source(viewKey)
            if view is not None:
                return view

        return

    def isViewCreated(self, viewKey):
        return self.__globalContainer.findView(viewKey) is not None

    def isViewInCache(self, viewKey):
        return self.__viewCache.getView(viewKey) is not None

    def isModalViewsIsExists(self):
        for layer in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(layer)
            if container is not None and container.getViewCount(
                    isModal=True) or self.__loader.isModalViewLoading():
                return True

        return False

    def getView(self, layer, criteria=None):
        container = self.__globalContainer.findContainer(layer)
        if container is not None:
            return container.getView(criteria=criteria)
        else:
            _logger.warning('Could not found container %s.', layer)
            return

    def isViewAvailable(self, layer, criteria=None):
        container = self.__globalContainer.findContainer(layer)
        return container.getView(
            criteria=criteria) is not None if container is not None else False

    def showContainers(self, layers, time=0):
        self.as_showContainersS(layers, time)

    def hideContainers(self, layers, time=0):
        self.as_hideContainersS(layers, time)

    def getVisibleLayers(self):
        return self.as_getVisibleLayersS()

    def setVisibleLayers(self, layerList):
        self.as_setVisibleLayersS(layerList)

    def isContainerShown(self, layer):
        return self.as_isContainerShownS(layer)

    def clear(self):
        for layer in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(layer)
            if container is not None:
                container.clear()

        return

    def closePopUps(self):
        self.as_closePopUpsS()

    def registerViewContainer(self, layer, uniqueName):
        self.as_registerContainerS(layer, uniqueName)
        _logger.debug(
            'A new container [layer=%d, name=%s] has been registered.', layer,
            uniqueName)

    def unregisterViewContainer(self, layer):
        self.as_unregisterContainerS(layer)
        _logger.debug('The container [layer=%d] has been unregistered.', layer)

    def __addLoadingView(self, pyView):
        layer = pyView.layer
        viewContainer = self.__globalContainer.findContainer(layer)
        if viewContainer is not None:
            viewContainer.addLoadingView(pyView)
        else:
            _logger.warning(
                'Loading of view %r is requested but the container %d is still not exist!',
                pyView, layer)
        self.__scopeController.addLoadingView(pyView, False)
        return

    def __showAndInitializeView(self, pyView):
        layer = pyView.layer
        if layer is None:
            _logger.error(
                'Type of view is not defined. View %r will be destroyed.',
                pyView)
            pyView.destroy()
            return False
        else:
            status = False
            container = self.__globalContainer.findContainer(layer)
            if container is not None:
                if WindowLayer.VIEW == layer:
                    self.closePopUps()
                if container.addView(pyView):
                    self.__scopeController.addView(pyView, False)
                    if pyView.uiImpl == UIFrameworkImpl.SCALEFORM:
                        self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    self.onViewAddedToContainer(container, pyView)
                    status = True
                else:
                    _logger.error(
                        '%r view cannot be added to container %r and will be destroyed.',
                        pyView, container)
                    pyView.destroy()
            else:
                _logger.error(
                    'Layer %s of view %r is not supported or container has not been properly created',
                    layer, pyView)
                pyView.destroy()
            return status

    def __addViewToCache(self, pyView):
        view = self.__viewCache.getView(pyView.key)
        if view is not None:
            _logger.warning('The view with key %r is already in the cache.',
                            pyView.key)
            if view != pyView:
                view.destroy()
                if self.__viewCache.addView(pyView):
                    _logger.debug('View %r has been added to the cache %r',
                                  pyView, self.__viewCache)
                else:
                    _logger.debug('Cannot add view %r in the cache %r', pyView,
                                  self.__viewCache)
        elif self.__viewCache.addView(pyView):
            _logger.debug('View %r has been added to the cache %r', pyView,
                          self.__viewCache)
        else:
            _logger.debug('Cannot add view %r in the cache %r', pyView,
                          self.__viewCache)
        return

    def __onViewLoaded(self, pyView, loadParams):
        self.onViewLoaded(pyView)
        loadMode = loadParams.loadMode
        if loadMode == ViewLoadMode.DEFAULT:
            if self.__scopeController.isViewLoading(pyView=pyView):
                self.__showAndInitializeView(pyView)
            else:
                _logger.debug(
                    '%r view loading is cancelled because its scope has been destroyed.',
                    pyView)
                pyView.destroy()
        elif loadMode == ViewLoadMode.PRELOAD:
            self.__addViewToCache(pyView)
        else:
            _logger.warning(
                'Unsupported load mode %s. View %r will be destroyed.',
                loadMode, pyView)
            pyView.destroy()

    def __onViewLoadInit(self, view, *args, **kwargs):
        self.onViewLoading(view)
Example #9
0
class ContainerManager(ContainerManagerMeta):
    onViewAddedToContainer = Event()
    __DESTROY_ORDER = (ViewTypes.DEFAULT,
     ViewTypes.LOBBY_SUB,
     ViewTypes.WINDOW,
     ViewTypes.BROWSER,
     ViewTypes.TOP_WINDOW,
     ViewTypes.WAITING,
     ViewTypes.CURSOR,
     ViewTypes.SERVICE_LAYOUT)
    __CONTAINERS_TO_CLEAR = (ViewTypes.WINDOW, ViewTypes.BROWSER, ViewTypes.TOP_WINDOW)

    def __init__(self, loader):
        super(ContainerManager, self).__init__()
        proxy = weakref.proxy(self)
        self.__containers = {ViewTypes.DEFAULT: _DefaultContainer(proxy),
         ViewTypes.CURSOR: _DefaultContainer(proxy),
         ViewTypes.WAITING: _DefaultContainer(proxy),
         ViewTypes.WINDOW: _PopUpContainer(proxy),
         ViewTypes.BROWSER: _PopUpContainer(proxy),
         ViewTypes.TOP_WINDOW: _PopUpContainer(proxy),
         ViewTypes.SERVICE_LAYOUT: _DefaultContainer(proxy)}
        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()

    def load(self, alias, name = None, *args, **kwargs):
        if name is None:
            name = alias
        isViewExists = self.as_getViewS(name)
        if not isViewExists and (alias, name) not in self._loadingViews:
            pyEntity = self.__loader.loadView(alias, name, *args, **kwargs)
            self.__scopeController.addLoadingView(pyEntity, False)
            curType = pyEntity.settings.type
            if self.canCancelPreviousLoading(curType):
                result = []
                for kev, val in self._loadingViews.iteritems():
                    if val.settings.type == pyEntity.settings.type:
                        result.append(val)

                if len(result) > 0:
                    self.__cancelLoadingForPyEntities(result)
            self._loadingViews[alias, name] = pyEntity
        return

    def __cancelLoadingForPyEntities(self, pyEntities):
        for curEntity in pyEntities:
            self._loadingViews.pop((curEntity.settings.alias, curEntity.uniqueName))
            self.__loader.cancelLoadingByName(curEntity.uniqueName)
            curEntity.destroy()

    def canCancelPreviousLoading(self, containerType):
        container = self.getContainer(containerType)
        if container is not None:
            return container.canCancelPreviousLoading()
        else:
            return False
            return

    def addContainer(self, containerType, name, container = None):
        result = True
        if containerType not in self.__containers:
            if container is None:
                self.__containers[containerType] = _DefaultContainer(weakref.proxy(self))
                self.as_registerContainerS(containerType, name)
            elif isinstance(container, IViewContainer):
                self.__containers[containerType] = container
                self.as_registerContainerS(containerType, name)
            else:
                LOG_ERROR('Container must be implemented IViewContainer', container)
                result = False
        else:
            LOG_ERROR('Container already registered', containerType)
            result = False
        return result

    def removeContainer(self, viewType):
        self.__scopeController.removeSubScopeController(ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType())
        result = True
        if viewType in self.__containers:
            container = self.__containers[viewType]
            container.destroy()
            self.as_unregisterContainerS(viewType)
            del self.__containers[viewType]
        else:
            result = False
        return result

    def getContainer(self, viewType):
        if viewType in self.__containers:
            return self.__containers[viewType]
        else:
            return None

    def isModalViewsIsExists(self):
        if self.getContainer(ViewTypes.TOP_WINDOW).getViewCount(isModal=True) > 0:
            return True
        elif self.getContainer(ViewTypes.BROWSER).getViewCount(isModal=True) > 0:
            return True
        else:
            return self.getContainer(ViewTypes.WINDOW).getViewCount(isModal=True) > 0

    def getView(self, viewType, criteria = None):
        view = None
        container = self.getContainer(viewType)
        if container is not None:
            view = container.getView(criteria=criteria)
        else:
            raise Exception('Container for %s view is None!' % viewType)
        return view

    def isViewAvailable(self, viewType, criteria = None):
        container = self.getContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False
            return

    def closePopUps(self):
        self.as_closePopUpsS()

    def clear(self):
        for c in self.__CONTAINERS_TO_CLEAR:
            self.getContainer(c).clear()

    def _dispose(self):
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__loader_onViewLoaded
            self.__loader = None
        for viewType in self.__DESTROY_ORDER:
            if viewType in self.__containers:
                container = self.__containers.pop(viewType)
                LOG_DEBUG('CONTAINER: ' + str(container) + '/' + viewType)
                container.destroy()

        if len(self.__containers):
            LOG_ERROR('No all containers are destructed.')
        self.__containers.clear()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        self._loadingViews.clear()
        self._loadingViews = None
        super(ContainerManager, self)._dispose()
        return

    def __loader_onViewLoaded(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR('Type of view is not defined', pyView.settings)
        viewKey = (pyView.alias, pyView.uniqueName)
        if viewKey in self._loadingViews:
            self._loadingViews.pop(viewKey)
        if viewType in self.__containers:
            if ViewTypes.DEFAULT == viewType:
                self.closePopUps()
            if self.__scopeController.isViewLoading(pyView):
                container = self.__containers[viewType]
                if container.add(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    subContainerType = pyView.getSubContainerType()
                    if subContainerType is not None:
                        self.addContainer(subContainerType, pyView.uniqueName)
                    LOG_DEBUG('View added to container', pyView)
                    self.onViewAddedToContainer(container, pyView)
            else:
                LOG_DEBUG('"%s" view cancelled to load, because its scope has been destroyed.' % str(pyView))
                self.as_hideS(pyView.uniqueName)
                pyView.destroy()
        else:
            LOG_ERROR('Type "%s" of view "%s" is not supported' % (viewType, pyView))
        return
Example #10
0
class ContainerManager(ContainerManagerMeta):
    """
    Class of container manager.
    """

    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        proxy = weakref.proxy(self)
        self.__containers = {}
        for container in containers:
            raise isinstance(container, AbstractViewContainer) or AssertionError
            self.__containers[container.getViewType()] = container(proxy)

        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()

    def load(self, alias, name = None, *args, **kwargs):
        """
        Loads view to container.
        :param alias:
        :param name:
        :param args:
        :param kwargs:
        :return:
        """
        if name is None:
            name = alias
        isViewExists = self.as_getViewS(name)
        if not isViewExists and (alias, name) not in self._loadingViews:
            pyEntity = self.__loader.loadView(alias, name, *args, **kwargs)
            self.__scopeController.addLoadingView(pyEntity, False)
            curType = pyEntity.settings.type
            if self.canCancelPreviousLoading(curType):
                result = []
                for kev, val in self._loadingViews.iteritems():
                    if val.settings.type == pyEntity.settings.type:
                        result.append(val)

                if result:
                    self.__cancelLoadingForPyEntities(result)
            self._loadingViews[alias, name] = pyEntity
        return

    def canCancelPreviousLoading(self, containerType):
        container = self.getContainer(containerType)
        if container is not None:
            return container.canCancelPreviousLoading()
        else:
            return False
            return

    def addContainer(self, viewType, name, container = None):
        result = True
        if viewType not in self.__containers:
            if container is None:
                self.__containers[viewType] = DefaultContainer(viewType, weakref.proxy(self))
                self.as_registerContainerS(viewType, name)
            elif isinstance(container, AbstractViewContainer):
                self.__containers[viewType] = container
                self.as_registerContainerS(viewType, name)
            else:
                LOG_ERROR('Container must be implemented IViewContainer', container)
                result = False
        else:
            LOG_ERROR('Container already registered', viewType)
            result = False
        return result

    def removeContainer(self, viewType):
        self.__scopeController.removeSubScopeController(ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType())
        result = True
        if viewType in self.__containers:
            container = self.__containers[viewType]
            container.destroy()
            self.as_unregisterContainerS(viewType)
            del self.__containers[viewType]
        else:
            result = False
        return result

    def getContainer(self, viewType):
        if viewType in self.__containers:
            return self.__containers[viewType]
        else:
            return None

    def isModalViewsIsExists(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None and container.getViewCount(isModal=True):
                return True

        return False

    def getView(self, viewType, criteria = None):
        container = self.getContainer(viewType)
        if container is not None:
            view = container.getView(criteria=criteria)
        else:
            raise Exception('Container for %s view is None!' % viewType)
        return view

    def isViewAvailable(self, viewType, criteria = None):
        container = self.getContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False
            return

    def showContainers(self, *viewTypes):
        self.as_showContainersS(viewTypes)

    def hideContainers(self, *viewTypes):
        self.as_hideContainersS(viewTypes)

    def isContainerShown(self, viewType):
        return self.as_isContainerShownS(viewType)

    def closePopUps(self):
        self.as_closePopUpsS()

    def clear(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.getContainer(viewType)
            if container is not None:
                container.clear()

        return

    def removeLoadingView(self, alias, uniqueName):
        self._loadingViews.pop((alias, uniqueName), None)
        return

    def _dispose(self):
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__loader_onViewLoaded
            self.__loader = None
        for viewType in _CONTAINERS_DESTROY_ORDER:
            if viewType in self.__containers:
                container = self.__containers.pop(viewType)
                LOG_DEBUG('CONTAINER: {}/{}'.format(container, viewType))
                container.destroy()

        if len(self.__containers):
            LOG_ERROR('No all containers are destructed.')
        self.__containers.clear()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        self._loadingViews.clear()
        self._loadingViews = None
        super(ContainerManager, self)._dispose()
        return

    def __cancelLoadingForPyEntities(self, pyEntities):
        for curEntity in pyEntities:
            self._loadingViews.pop((curEntity.settings.alias, curEntity.uniqueName))
            self.__loader.cancelLoadingByName(curEntity.uniqueName)
            curEntity.destroy()

    def __loader_onViewLoaded(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR('Type of view is not defined', pyView.settings)
        viewKey = (pyView.alias, pyView.uniqueName)
        if viewKey in self._loadingViews:
            self._loadingViews.pop(viewKey)
        if viewType in self.__containers:
            if ViewTypes.DEFAULT == viewType:
                self.closePopUps()
            if self.__scopeController.isViewLoading(pyView):
                container = self.__containers[viewType]
                if container.add(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    subContainerType = pyView.getSubContainerType()
                    if subContainerType is not None:
                        self.addContainer(subContainerType, pyView.uniqueName)
                    LOG_DEBUG('View added to container', pyView)
                    self.onViewAddedToContainer(container, pyView)
            else:
                LOG_DEBUG('"%s" view cancelled to load, because its scope has been destroyed.' % str(pyView))
                self.as_hideS(pyView.uniqueName)
                pyView.destroy()
        else:
            LOG_ERROR('Type "%s" of view "%s" is not supported' % (viewType, pyView))
        return
Example #11
0
class ContainerManager(ContainerManagerMeta):
    onViewAddedToContainer = Event()
    __DESTROY_ORDER = (ViewTypes.DEFAULT, ViewTypes.LOBBY_SUB,
                       ViewTypes.WINDOW, ViewTypes.BROWSER,
                       ViewTypes.TOP_WINDOW, ViewTypes.WAITING,
                       ViewTypes.CURSOR, ViewTypes.SERVICE_LAYOUT)
    __CONTAINERS_TO_CLEAR = (ViewTypes.WINDOW, ViewTypes.BROWSER,
                             ViewTypes.TOP_WINDOW)

    def __init__(self, loader):
        super(ContainerManager, self).__init__()
        proxy = weakref.proxy(self)
        self.__containers = {
            ViewTypes.DEFAULT: _DefaultContainer(proxy),
            ViewTypes.CURSOR: _DefaultContainer(proxy),
            ViewTypes.WAITING: _DefaultContainer(proxy),
            ViewTypes.WINDOW: _PopUpContainer(proxy),
            ViewTypes.BROWSER: _PopUpContainer(proxy),
            ViewTypes.TOP_WINDOW: _PopUpContainer(proxy),
            ViewTypes.SERVICE_LAYOUT: _DefaultContainer(proxy)
        }
        self._loadingViews = dict()
        self.__loader = loader
        self.__loader.onViewLoaded += self.__loader_onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()

    def load(self, alias, name=None, *args, **kwargs):
        if name is None:
            name = alias
        isViewExists = self.as_getViewS(name)
        if not isViewExists and (alias, name) not in self._loadingViews:
            pyEntity = self.__loader.loadView(alias, name, *args, **kwargs)
            self.__scopeController.addLoadingView(pyEntity, False)
            curType = pyEntity.settings.type
            if self.canCancelPreviousLoading(curType):
                result = []
                for kev, val in self._loadingViews.iteritems():
                    if val.settings.type == pyEntity.settings.type:
                        result.append(val)

                if len(result) > 0:
                    self.__cancelLoadingForPyEntities(result)
            self._loadingViews[alias, name] = pyEntity

    def __cancelLoadingForPyEntities(self, pyEntities):
        for curEntity in pyEntities:
            self._loadingViews.pop(
                (curEntity.settings.alias, curEntity.uniqueName))
            self.__loader.cancelLoadingByName(curEntity.uniqueName)
            curEntity.destroy()

    def canCancelPreviousLoading(self, containerType):
        container = self.getContainer(containerType)
        if container is not None:
            return container.canCancelPreviousLoading()
        else:
            return False

    def addContainer(self, containerType, name, container=None):
        result = True
        if containerType not in self.__containers:
            if container is None:
                self.__containers[containerType] = _DefaultContainer(
                    weakref.proxy(self))
                self.as_registerContainerS(containerType, name)
            elif isinstance(container, IViewContainer):
                self.__containers[containerType] = container
                self.as_registerContainerS(containerType, name)
            else:
                LOG_ERROR('Container must be implemented IViewContainer',
                          container)
                result = False
        else:
            LOG_ERROR('Container already registered', containerType)
            result = False
        return result

    def removeContainer(self, viewType):
        self.__scopeController.removeSubScopeController(
            ScopeTemplates.VIEW_TYPES_TO_SCOPES[viewType].getScopeType())
        result = True
        if viewType in self.__containers:
            container = self.__containers[viewType]
            container.destroy()
            self.as_unregisterContainerS(viewType)
            del self.__containers[viewType]
        else:
            result = False
        return result

    def getContainer(self, viewType):
        if viewType in self.__containers:
            return self.__containers[viewType]

    def isModalViewsIsExists(self):
        if self.getContainer(
                ViewTypes.TOP_WINDOW).getViewCount(isModal=True) > 0:
            return True
        elif self.getContainer(
                ViewTypes.BROWSER).getViewCount(isModal=True) > 0:
            return True
        else:
            return self.getContainer(
                ViewTypes.WINDOW).getViewCount(isModal=True) > 0

    def getView(self, viewType, criteria=None):
        view = None
        container = self.getContainer(viewType)
        if container is not None:
            view = container.getView(criteria=criteria)
        else:
            raise Exception('Container for %s view is None!' % viewType)
        return view

    def isViewAvailable(self, viewType, criteria=None):
        container = self.getContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria) is not None
        else:
            return False

    def closePopUps(self):
        self.as_closePopUpsS()

    def clear(self):
        for c in self.__CONTAINERS_TO_CLEAR:
            self.getContainer(c).clear()

    def _dispose(self):
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__loader_onViewLoaded
            self.__loader = None
        for viewType in self.__DESTROY_ORDER:
            if viewType in self.__containers:
                container = self.__containers.pop(viewType)
                LOG_DEBUG('CONTAINER: ' + str(container) + '/' + viewType)
                container.destroy()

        if len(self.__containers):
            LOG_ERROR('No all containers are destructed.')
        self.__containers.clear()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        self._loadingViews.clear()
        self._loadingViews = None
        super(ContainerManager, self)._dispose()

    def __loader_onViewLoaded(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR('Type of view is not defined', pyView.settings)
        viewKey = (pyView.alias, pyView.uniqueName)
        if viewKey in self._loadingViews:
            self._loadingViews.pop(viewKey)
        if viewType in self.__containers:
            if ViewTypes.DEFAULT == viewType:
                self.closePopUps()
            if self.__scopeController.isViewLoading(pyView):
                container = self.__containers[viewType]
                if container.add(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    subContainerType = pyView.getSubContainerType()
                    if subContainerType is not None:
                        self.addContainer(subContainerType, pyView.uniqueName)
                    LOG_DEBUG('View added to container', pyView)
                    self.onViewAddedToContainer(container, pyView)
            else:
                LOG_DEBUG(
                    '"%s" view cancelled to load, because its scope has been destroyed.'
                    % str(pyView))
                self.as_hideS(pyView.uniqueName)
                pyView.destroy()
        else:
            LOG_ERROR('Type "%s" of view "%s" is not supported' %
                      (viewType, pyView))
Example #12
0
class ContainerManager(ContainerManagerMeta, IContainerManager):
    def __init__(self, loader, *containers):
        super(ContainerManager, self).__init__()
        self.onViewAddedToContainer = Event()
        self.onViewLoading = Event()
        self.onViewLoaded = Event()
        self.__globalContainer = _GlobalViewContainer(weakref.proxy(self))
        for container in containers:
            self.__globalContainer.addChildContainer(container)

        self.__loader = loader
        self.__loader.onViewLoadInit += self.__onViewLoadInit
        self.__loader.onViewLoaded += self.__onViewLoaded
        self.__scopeController = GlobalScopeController()
        self.__scopeController.create()
        self.__viewCache = _ViewCollection()
        self.__chainMng = _ChainManager(weakref.proxy(self))

    def _dispose(self):
        self.__viewCache.destroy()
        self.__chainMng.destroy()
        if self.__loader is not None:
            self.__loader.onViewLoaded -= self.__onViewLoaded
            self.__loader.onViewLoadInit -= self.__onViewLoadInit
            self.__loader = None
        for viewType in _CONTAINERS_DESTROY_ORDER:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                LOG_DEBUG('Destroy container {} ({})'.format(
                    viewType, container))
                container.destroy()

        self.__globalContainer.destroy()
        self.onViewAddedToContainer.clear()
        self.__scopeController.destroy()
        self.__scopeController = None
        super(ContainerManager, self)._dispose()
        return

    def destroyViews(self, alias, name=None):
        def compareByAlias(view):
            return view.key.alias == alias

        def compareByAliasAndName(view):
            viewKey = view.key
            return viewKey.alias == alias and viewKey.name == name

        if name is None:
            comparator = compareByAlias
        else:
            comparator = compareByAliasAndName
        views = self.__scopeController.findViews(comparator)
        views.extend(self.__viewCache.findViews(comparator))
        for view in views:
            if not view.isDisposed():
                LOG_DEBUG('The view {} will be destroyed...'.format(view))
                view.destroy()

        viewKey = ViewKey(alias, name)
        chain = self.__chainMng.getChainByViewKey(viewKey)
        if chain is not None:
            chain.removeViewByViewKey(viewKey)
        return

    def loadChain(self, chainItems):
        chain = _LoadingChain(chainItems)
        if self.__chainMng.addChain(chain):
            chain.run()
        else:
            LOG_WARNING(
                'Could not add a new chain. Loading of chain [{}] is canceled.'
                .format(chainItems))
            chain.destroy()

    def load(self, loadParams, *args, **kwargs):
        viewKey = loadParams.viewKey
        viewLoadingItem = self.__loader.getViewLoadingItem(viewKey)
        if viewLoadingItem is not None:
            LOG_DEBUG('View with key {} is already loading. item=[{}]'.format(
                viewKey, viewLoadingItem))
            view = viewLoadingItem.pyEntity
            if loadParams.loadMode == ViewLoadMode.DEFAULT:
                loadingViewLoadMode = viewLoadingItem.loadParams.loadMode
                if loadingViewLoadMode == ViewLoadMode.PRELOAD:
                    viewLoadingItem.loadParams = loadParams
                    self.__addLoadingView(view)
            elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                pass
            else:
                LOG_WARNING(
                    'Unsupported load mode {}. View loading will be skipped.'.
                    format(loadParams))
                view = None
        else:
            view = self.__globalContainer.findView(viewKey)
            if view is None:
                view = self.__viewCache.getView(viewKey)
                if view is None:
                    chain = self.__chainMng.getChainByViewKey(viewKey)
                    if chain is not None:
                        LOG_WARNING(
                            'View with loadParams={} is in the loading chain {}. The request will be skipped.'
                            .format(loadParams, chain))
                    else:
                        LOG_DEBUG(
                            'Load view with loadParams={}. Loader=[{}]'.format(
                                loadParams, self.__loader))
                        if loadParams.loadMode == ViewLoadMode.DEFAULT:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                            self.__addLoadingView(view)
                        elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                            view = self.__loader.loadView(
                                loadParams, *args, **kwargs)
                        else:
                            LOG_WARNING(
                                'Unsupported load mode {}. View loading will be skipped.'
                                .format(loadParams))
                elif loadParams.loadMode == ViewLoadMode.PRELOAD:
                    LOG_DEBUG(
                        'View with key {} ({}) is already pre-loaded.'.format(
                            viewKey, view))
                elif loadParams.loadMode == ViewLoadMode.DEFAULT:
                    LOG_DEBUG(
                        'Load view with loadParams={} from the cache. Cache=[{}]'
                        .format(loadParams, self.__viewCache))
                    self.__viewCache.removeView(viewKey)
                    self.__showAndInitializeView(view)
                    view.validate(*args, **kwargs)
                else:
                    LOG_WARNING(
                        'Unsupported load mode {}. View loading will be skipped.'
                        .format(loadParams))
                    view = None
            else:
                LOG_DEBUG('View with key {} ({}) is already loaded.'.format(
                    viewKey, view))
                viewType = view.settings.type
                viewContainer = self.__globalContainer.findContainer(viewType)
                viewContainer.addView(view)
                view.validate(*args, **kwargs)
        return view

    def getContainer(self, viewType):
        return self.__globalContainer.findContainer(viewType)

    def getViewByKey(self, viewKey):
        if self.__loader is not None:
            loadingItem = self.__loader.getViewLoadingItem(viewKey)
            if loadingItem is not None:
                return loadingItem.pyEntity
        sources = (self.__globalContainer.findView, self.__viewCache.getView)
        for source in sources:
            view = source(viewKey)
            if view is not None:
                return view

        return

    def isViewCreated(self, viewKey):
        return self.__globalContainer.findView(viewKey) is not None

    def isViewInCache(self, viewKey):
        return self.__viewCache.getView(viewKey) is not None

    def isModalViewsIsExists(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None and container.getViewCount(isModal=True):
                return True

        return False

    def getView(self, viewType, criteria=None):
        container = self.__globalContainer.findContainer(viewType)
        if container is not None:
            return container.getView(criteria=criteria)
        else:
            LOG_WARNING('Could not found container {}.'.format(viewType))
            return

    def isViewAvailable(self, viewType, criteria=None):
        container = self.__globalContainer.findContainer(viewType)
        return container.getView(
            criteria=criteria) is not None if container is not None else False

    def showContainers(self, *viewTypes):
        self.as_showContainersS(viewTypes)

    def hideContainers(self, *viewTypes):
        self.as_hideContainersS(viewTypes)

    def isContainerShown(self, viewType):
        return self.as_isContainerShownS(viewType)

    def clear(self):
        for viewType in _POPUPS_CONTAINERS:
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                container.clear()

        return

    def closePopUps(self):
        self.as_closePopUpsS()

    def registerViewContainer(self, viewType, uniqueName):
        self.as_registerContainerS(viewType, uniqueName)
        LOG_DEBUG(
            'A new container [type={}, name={}] has been registered.'.format(
                viewType, uniqueName))

    def unregisterViewContainer(self, viewType):
        self.as_unregisterContainerS(viewType)
        LOG_DEBUG(
            'The container [type={}] has been unregistered.'.format(viewType))

    def __addLoadingView(self, pyView):
        viewType = pyView.settings.type
        viewContainer = self.__globalContainer.findContainer(viewType)
        if viewContainer is not None:
            viewContainer.addLoadingView(pyView)
        else:
            LOG_WARNING(
                'Loading of view {} is requested but the container {} is still not exist!'
                .format(pyView, viewType))
        self.__scopeController.addLoadingView(pyView, False)
        return

    def __showAndInitializeView(self, pyView):
        viewType = pyView.settings.type
        if viewType is None:
            LOG_ERROR(
                'Type of view is not defined. View {} will be destroyed.',
                pyView)
            pyView.destroy()
            return False
        else:
            status = False
            container = self.__globalContainer.findContainer(viewType)
            if container is not None:
                if ViewTypes.DEFAULT == viewType:
                    self.closePopUps()
                if container.addView(pyView):
                    self.__scopeController.addView(pyView, False)
                    self.as_showS(pyView.uniqueName, 0, 0)
                    pyView.create()
                    self.onViewAddedToContainer(container, pyView)
                    status = True
                else:
                    LOG_ERROR(
                        '{} view cannot be added to container {} and will be destroyed.'
                        .format(pyView, container))
                    pyView.destroy()
            else:
                LOG_ERROR(
                    'Type {} of view {} is not supported or container has not been properly created'
                    .format(viewType, pyView))
                pyView.destroy()
            return status

    def __addViewToCache(self, pyView):
        view = self.__viewCache.getView(pyView.key)
        if view is not None:
            LOG_UNEXPECTED(
                'The view with key {} is already in the cache.'.format(
                    pyView.key), pyView, view)
            if view != pyView:
                view.destroy()
                if self.__viewCache.addView(pyView):
                    LOG_DEBUG('View {} has been added to the cache {}'.format(
                        pyView, self.__viewCache))
                else:
                    LOG_DEBUG('Cannot add view {} in the cache {}'.format(
                        pyView, self.__viewCache))
        elif self.__viewCache.addView(pyView):
            LOG_DEBUG('View {} has been added to the cache {}'.format(
                pyView, self.__viewCache))
        else:
            LOG_DEBUG('Cannot add view {} in the cache {}'.format(
                pyView, self.__viewCache))
        return

    def __onViewLoaded(self, pyView, loadParams):
        self.onViewLoaded(pyView)
        loadMode = loadParams.loadMode
        if loadMode == ViewLoadMode.DEFAULT:
            if self.__scopeController.isViewLoading(pyView=pyView):
                self.__showAndInitializeView(pyView)
            else:
                LOG_DEBUG(
                    '{} view loading is cancelled because its scope has been destroyed.'
                    .format(pyView))
                pyView.destroy()
        elif loadMode == ViewLoadMode.PRELOAD:
            self.__addViewToCache(pyView)
        else:
            LOG_WARNING(
                'Unsupported load mode {}. View {} will be destroyed.'.format(
                    loadMode, pyView))
            pyView.destroy()

    def __onViewLoadInit(self, view, *args, **kwargs):
        self.onViewLoading(view)