📄 uivisualizer.java
字号:
set = ((Cropper)xc).getAvailableAtClient(); cropping.put(comp, set != null ? set: Collections.EMPTY_SET); return set; } return null; } /** Process {@link ChildChangedAware} */ private void doChildChanged() { final Set ccawares = new HashSet(), checked = new HashSet(79); doChildChanged(_invalidated, ccawares, checked); doChildChanged(_attached, ccawares, checked); doChildChanged(_smartUpdated.keySet(), ccawares, checked); if (!ccawares.isEmpty()) for (Iterator it = ccawares.iterator(); it.hasNext();) addSmartUpdate((Component)it.next(), "z.chchg", "true"); } private void doChildChanged(Collection col, Set ccawares, Set checked) { for (Iterator it = col.iterator(); it.hasNext();) { Component comp = (Component)it.next(); if (!_exec.isAsyncUpdate(comp.getPage())) continue; while ((comp = comp.getParent()) != null) { if (!checked.add(comp)) break; //already checked final Object xc = ((ComponentCtrl)comp).getExtraCtrl(); if ((xc instanceof ChildChangedAware) //&& !_invalidated.contains(comp) && !_attached.contains(comp) //No need to check _invalidated... since they are optimized && ((ChildChangedAware)xc).isChildChangedAware()) ccawares.add(comp); } } } /** Prepares {@link #_pgRemoved} to contain set of pages that will * be removed. */ private void checkPageRemoved(Set removed) { //1. scan once final Desktop desktop = _exec.getDesktop(); Set pages = null; for (Iterator it = desktop.getPages().iterator(); it.hasNext();) { final Page page = (Page)it.next(); final Component owner = ((PageCtrl)page).getOwner(); if (owner != null) { //included final Page ownerPage = owner.getPage(); if (ownerPage == null //detached || (_pgInvalid != null && _pgInvalid.contains(ownerPage)) || isAncestor(_invalidated, owner, true) || isAncestor(_attached, owner, true) || isAncestor(removed, owner, true)) { addPageRemoved(page); } else { if (pages == null) pages = new HashSet(); pages.add(page); } } } if (_pgRemoved == null || pages == null) return; //done if no page is removed or no more included page //2. if a page is ever removed, it might cause chain effect //so we have to loop until nothing changed boolean pgRemovedFound; do { pgRemovedFound = false; for (Iterator it = pages.iterator(); it.hasNext();) { final Page page = (Page)it.next(); final Component owner = ((PageCtrl)page).getOwner(); if (_pgRemoved.contains(owner.getPage())) { it.remove(); addPageRemoved(page); pgRemovedFound = true; } } } while (pgRemovedFound); //loop due to chain effect } private void addPageRemoved(Page page) { if (_pgRemoved == null) _pgRemoved = new HashSet(); _pgRemoved.add(page); if (_pgInvalid != null) _pgInvalid.remove(page); if (D.ON && log.debugable()) log.debug("Page removed: "+page); } /** Clears components if it belongs to invalidated or removed page. */ private void clearInInvalidPage(Collection coll) { for (Iterator it = coll.iterator(); it.hasNext();) { final Component comp = (Component)it.next(); final Page page = comp.getPage(); if (page != null && ((_pgRemoved != null && _pgRemoved.contains(page)) || (_pgInvalid != null && _pgInvalid.contains(page)))) it.remove(); } } /** Returns whether any component in coll is an ancestor of comp. * @param includingEquals whether to return true if a equals B */ private boolean isAncestor(Collection coll, Component comp, boolean includingEquals) { for (Iterator it = coll.iterator(); it.hasNext();) { final Component c = (Component)it.next(); if ((includingEquals || c != comp) && Components.isAncestor(c, comp)) return true; } return false; } /** Returns a list of {@link AuResponse} according to what components * are invalidated and attached. */ public List getResponses() throws IOException { if (D.ON && log.finerable()) log.finer("ei: "+this+"\nInvalidated: "+_invalidated+"\nSmart Upd: "+_smartUpdated +"\nAttached: "+_attached+"\nMoved:"+_moved+"\nResponses:"+_responses +"\npgInvalid: "+_pgInvalid +"\nUuidChanged: "+_idChgd); final List responses = new LinkedList(); //1. process dead comonents, cropping and the removed page { //1a. handle _moved //The reason to remove first: some insertion might fail if the old //componetns are not removed yet //Also, we have to remove both parent and child because, at //the client, they might not be parent-child relationship Set removed = doMoved(responses); //after called, _moved is cleared (add to _attached if necessary) //1b. remove reduntant removeRedundant(_invalidated); removeRedundant(_attached); removeCrossRedundant(); //it also handle isTransparent!! //1c. process Cropper if (doCrop()) { //optimize it again since new invalidated is added removeRedundant(_invalidated); removeCrossRedundant(); } resolveDirtyTransparent(responses); //1d. prepare removed pages and optimize for invalidate or removed pages checkPageRemoved(removed); //maintain _pgRemoved for pages being removed } //2. Process removed and invalid pages //2a. clean up _invalidated and others belonging to invalid pages if (_pgInvalid != null && _pgInvalid.isEmpty()) _pgInvalid = null; if (_pgRemoved != null && _pgRemoved.isEmpty()) _pgRemoved = null; if (_pgInvalid != null || _pgRemoved != null) { clearInInvalidPage(_invalidated); clearInInvalidPage(_attached); clearInInvalidPage(_smartUpdated.keySet()); if (_idChgd != null) clearInInvalidPage(_idChgd.keySet()); } //2b. remove pages. Note: we don't need to generate rm, becausee they //are included pages. if (_pgRemoved != null) { final DesktopCtrl dtctl = (DesktopCtrl)_exec.getDesktop(); for (final Iterator it = _pgRemoved.iterator(); it.hasNext();) dtctl.removePage((Page)it.next()); } //2c. generate response for invalidated pages if (_pgInvalid != null) { for (final Iterator it = _pgInvalid.iterator(); it.hasNext();) { final Page page = (Page)it.next(); responses.add(new AuReplace(page, redraw(page))); } } //3. Remove components who is moved and its UUID is changed if (_idChgd != null) { for (Iterator it = _idChgd.values().iterator(); it.hasNext();) responses.add(new AuRemove((String)it.next())); _idChgd = null; //just in case } if (log.finerable()) log.finer("After removing redudant: invalidated: "+_invalidated +"\nAttached: "+_attached+"\nSmartUpd:"+_smartUpdated); //4. process special interfaces doChildChanged(); //ChildChangedAware //5. generate replace for invalidated for (Iterator it = _invalidated.iterator(); it.hasNext();) { final Component comp = (Component)it.next(); responses.add(new AuReplace(comp, redraw(comp))); } //6. add attached components (including setParent) //Due to cyclic references, we have to process all siblings //at the same time final List desktops = new LinkedList(); final Component[] attached = (Component[]) _attached.toArray(new Component[_attached.size()]); for (int j = 0; j < attached.length; ++j) { final Component comp = attached[j]; //Note: attached comp might change from another page to //the one being created. In this case, no need to add if (comp != null && _exec.isAsyncUpdate(comp.getPage())) { assert D.OFF || !isTransparent(comp): "not resolved?" +comp; final Component parent = getNonTransparentParent(comp); final Set newsibs = new LinkedHashSet(37); newsibs.add(comp); desktops.add(newsibs); for (int k = j + 1; k < attached.length; ++k) { final Component ck = attached[k]; if (ck != null && getNonTransparentParent(ck) == parent) { newsibs.add(ck); attached[k] = null; } } } } for (Iterator it = desktops.iterator(); it.hasNext();) { final Set newsibs = (Set)it.next(); addResponsesForCreatedPerSiblings(responses, newsibs); } //7. Adds smart updates and response at once based on their time stamp final List tvals = new LinkedList(); for (Iterator it = _smartUpdated.values().iterator(); it.hasNext();) { final Map attrs = (Map)it.next(); tvals.addAll(attrs.values()); } if (_responses != null) { for (Iterator it = _responses.values().iterator(); it.hasNext();) { final Map resps = (Map)it.next(); final List keyless = (List)resps.remove(null); //key == null if (keyless != null) tvals.addAll(keyless); tvals.addAll(resps.values()); //key != null } } if (!tvals.isEmpty()) { final TimedValue[] tvs = (TimedValue[])tvals.toArray(new TimedValue[tvals.size()]); Arrays.sort(tvs); for (int j = 0; j < tvs.length; ++j) responses.add(tvs[j].getResponse()); } //free memory _invalidated.clear(); _smartUpdated.clear(); _attached.clear(); _pgInvalid = _pgRemoved = null; _responses = null; if (D.ON && log.debugable()) log.debug("Return responses: "+responses); return responses; } private static boolean isTransparent(Component comp) { final Object xc = ((ComponentCtrl)comp).getExtraCtrl(); return (xc instanceof Transparent) && ((Transparent)xc).isTransparent(); } /** process moved components. * * <p>After called, _moved becomes empty. * If they are removed, correponding AuRemove are generated. * If not, they are added to _attached. * * @return the dead components (i.e., not belong to any page) */ private Set doMoved(List responses) { //Remove components that have to removed from the client final Set removed = new HashSet(); for (Iterator it = _moved.iterator(); it.hasNext();) { final Component comp = (Component)it.next(); final Page pg = comp.getPage(); if (pg == null) { removed.add(comp); if (_responses != null) _responses.remove(comp); _invalidated.remove(comp); _smartUpdated.remove(comp); responses.add(new AuRemove(comp)); //Note: it is too late to handle isTransparent here //because it is detached and we don't know it is ex-parent } else { if (_exec.isAsyncUpdate(pg)) responses.add(new AuRemove(comp)); _attached.add(comp); //copy to _attached since we handle them later in the same way } } _moved.clear(); //no longer required return removed; } /** Adds responses for a set of siblings which is new attached (or * parent is changed). */ private static void addResponsesForCreatedPerSiblings(List responses, Set newsibs) throws IOException { final Component ntparent; final Page page; { final Component comp = (Component)newsibs.iterator().next(); ntparent = getNonTransparentParent(comp); page = comp.getPage(); } final Collection sibs; if (ntparent != null) { sibs = resolveTransparent(ntparent.getChildren()); } else { sibs = page.getRoots(); } if (D.ON && log.finerable()) log.finer("All sibs: "+sibs+" newsibs: "+newsibs); /* Algorithm:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -