redirectTimer.schedule(1000 * sessionExpirationInterval);
}
- // TODO implement shared state handling
-
- // map from paintable id to its shared state instance
- Map<String, SharedState> sharedStates = new HashMap<String, SharedState>();
-
- // TODO Cache shared state (if any) - components might not exist
- // TODO cleanup later: keep only used states
- ValueMap states = json.getValueMap("state");
- JsArrayString keyArray = states.getKeyArray();
- for (int i = 0; i < keyArray.length(); i++) {
- String paintableId = keyArray.get(i);
- // TODO handle as a ValueMap or similar object and native
- // JavaScript processing?
- JavaScriptObject value = states
- .getJavaScriptObject(paintableId);
- // TODO implement with shared state subclasses
- SharedState state = GWT.create(SharedState.class);
- Map<String, Object> stateMap = (Map<String, Object>) JsonDecoder
- .convertValue(new JSONArray(value),
- getPaintableMap());
- state.setState(stateMap);
- // TODO cache state to temporary stateMap
- sharedStates.put(paintableId, state);
- }
+ // three phases/loops:
+ // - changes: create paintables (if necessary)
+ // - state: set shared states
+ // - changes: call updateFromUIDL() for each paintable
// Process changes
JsArray<ValueMap> changes = json.getJSValueMapArray("changes");
componentCaptionSizeChanges.clear();
int length = changes.length();
+
+ // create paintables if necessary
+ for (int i = 0; i < length; i++) {
+ try {
+ final UIDL change = changes.get(i).cast();
+ final UIDL uidl = change.getChildUIDL(0);
+ VPaintable paintable = paintableMap.getPaintable(uidl
+ .getId());
+ if (null == paintable
+ && !uidl.getTag().equals(
+ configuration.getEncodedWindowTag())) {
+ // create, initialize and register the paintable
+ getPaintable(uidl);
+ }
+ } catch (final Throwable e) {
+ VConsole.error(e);
+ }
+ }
+
+ // set states for all paintables mentioned in "state"
+ ValueMap states = json.getValueMap("state");
+ JsArrayString keyArray = states.getKeyArray();
+ for (int i = 0; i < keyArray.length(); i++) {
+ try {
+ String paintableId = keyArray.get(i);
+ VPaintable paintable = paintableMap
+ .getPaintable(paintableId);
+ if (null != paintable) {
+ // TODO handle as a ValueMap or similar object and
+ // native JavaScript processing?
+ JavaScriptObject value = states
+ .getJavaScriptObject(paintableId);
+ // TODO implement with shared state subclasses
+ SharedState state = GWT.create(SharedState.class);
+ Map<String, Object> stateMap = (Map<String, Object>) JsonDecoder
+ .convertValue(new JSONArray(value),
+ getPaintableMap());
+ state.setState(stateMap);
+ paintable.updateState(state);
+ }
+ } catch (final Throwable e) {
+ VConsole.error(e);
+ }
+ }
+
+ // update paintables
for (int i = 0; i < length; i++) {
try {
final UIDL change = changes.get(i).cast();
return result.toString();
}
- public void updateComponentSize(VPaintableWidget paintable, UIDL uidl) {
- String w = uidl.hasAttribute("width") ? uidl
- .getStringAttribute("width") : "";
-
- String h = uidl.hasAttribute("height") ? uidl
- .getStringAttribute("height") : "";
+ public void updateComponentSize(VPaintableWidget paintable) {
+ SharedState state = paintable.getState();
+ String w = "";
+ String h = "";
+ if (null != state) {
+ // TODO move logging to VUIDLBrowser and VDebugConsole
+ VConsole.log("Paintable state for "
+ + getPaintableMap().getPid(paintable) + ": "
+ + String.valueOf(state.getState()));
+ if (state.getState().containsKey(ComponentState.STATE_WIDTH)) {
+ w = String.valueOf(state.getState().get(
+ ComponentState.STATE_WIDTH));
+ }
+ if (state.getState().containsKey(ComponentState.STATE_HEIGHT)) {
+ h = String.valueOf(state.getState().get(
+ ComponentState.STATE_HEIGHT));
+ }
+ } else {
+ // TODO move logging to VUIDLBrowser and VDebugConsole
+ VConsole.log("No state for paintable "
+ + getPaintableMap().getPid(paintable)
+ + " in ApplicationConnection.updateComponentSize()");
+ }
float relativeWidth = Util.parseRelativeSize(w);
float relativeHeight = Util.parseRelativeSize(h);
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import java.util.Stack;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
private static final String GET_PARAM_ANALYZE_LAYOUTS = "analyzeLayouts";
- // TODO combine with paint queue?
+ // cannot combine with paint queue:
+ // this can contain dirty components from any Root
private final ArrayList<Paintable> dirtyPaintables = new ArrayList<Paintable>();
// queue used during painting to keep track of what still needs to be
- // painted
+ // painted within the Root being painted
private LinkedList<Paintable> paintQueue = new LinkedList<Paintable>();
private final HashMap<Paintable, String> paintableIdMap = new HashMap<Paintable, String>();
// for internal use by JsonPaintTarget
public void queuePaintable(Paintable paintable) {
- paintQueue.push(paintable);
+ if (!paintQueue.contains(paintable)) {
+ paintQueue.add(paintable);
+ }
}
public void writeUidlResponce(boolean repaintAll,
windowCache);
}
+ LinkedList<Paintable> stateQueue = new LinkedList<Paintable>();
+
if (paintables != null) {
// clear and rebuild paint queue
while (!paintQueue.isEmpty()) {
final Paintable p = paintQueue.pop();
+ // for now, all painted components may need a state refresh
+ stateQueue.push(p);
// // TODO CLEAN
// if (p instanceof Root) {
paintTarget.close();
outWriter.print("], "); // close changes
- if (paintables != null) {
+ if (!stateQueue.isEmpty()) {
// paint shared state
// for now, send the complete state of all modified and new
// processing.
JSONObject sharedStates = new JSONObject();
- Stack<Paintable> paintablesWithModifiedState = new Stack<Paintable>();
- paintablesWithModifiedState.addAll(paintables);
- // TODO add all sub-components that were painted
- while (!paintablesWithModifiedState.empty()) {
- final Paintable p = paintablesWithModifiedState.pop();
+ while (!stateQueue.isEmpty()) {
+ final Paintable p = stateQueue.pop();
String paintableId = getPaintableId(p);
SharedState state = p.getState();
if (null != state) {
final ArrayList<Paintable> resultset = new ArrayList<Paintable>(
dirtyPaintables);
+ // TODO mostly unnecessary?
// The following algorithm removes any components that would be painted
// as a direct descendant of other components from the dirty components
// list. The result is that each component should be painted exactly