]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add crude support for only sending state changes (#9026)
authorLeif Åstrand <leif@vaadin.com>
Thu, 16 Aug 2012 10:42:07 +0000 (13:42 +0300)
committerLeif Åstrand <leif@vaadin.com>
Mon, 20 Aug 2012 05:53:46 +0000 (08:53 +0300)
server/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
server/src/com/vaadin/terminal/gwt/server/JsonCodec.java
server/src/com/vaadin/ui/ConnectorTracker.java

index ffee51755041f72a0382437034eae70fac8649e2..99376ffd1f974da24317fb6fc02c3a10d9f46a38 100644 (file)
@@ -68,6 +68,7 @@ import com.vaadin.external.json.JSONException;
 import com.vaadin.external.json.JSONObject;
 import com.vaadin.shared.ApplicationConstants;
 import com.vaadin.shared.Connector;
+import com.vaadin.shared.JavaScriptConnectorState;
 import com.vaadin.shared.Version;
 import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
 import com.vaadin.shared.communication.MethodInvocation;
@@ -885,23 +886,36 @@ public abstract class AbstractCommunicationManager implements Serializable {
                 try {
                     Class<? extends SharedState> stateType = connector
                             .getStateType();
-                    SharedState referenceState = null;
-                    if (repaintAll) {
+                    Object diffState = rootConnectorTracker
+                            .getDiffState(connector);
+                    if (diffState == null) {
+                        diffState = new JSONObject();
                         // Use an empty state object as reference for full
                         // repaints
-                        try {
-                            referenceState = stateType.newInstance();
-                        } catch (Exception e) {
-                            getLogger().log(
-                                    Level.WARNING,
-                                    "Error creating reference object for state of type "
-                                            + stateType.getName());
+                        boolean emptyInitialState = JavaScriptConnectorState.class
+                                .isAssignableFrom(stateType);
+                        if (!emptyInitialState) {
+                            try {
+                                SharedState referenceState = stateType
+                                        .newInstance();
+                                diffState = JsonCodec.encode(referenceState,
+                                        null, stateType,
+                                        root.getConnectorTracker());
+                            } catch (Exception e) {
+                                getLogger().log(
+                                        Level.WARNING,
+                                        "Error creating reference object for state of type "
+                                                + stateType.getName());
+                            }
                         }
+                        rootConnectorTracker.setDiffState(connector, diffState);
                     }
-                    Object stateJson = JsonCodec.encode(state, referenceState,
-                            stateType, root.getConnectorTracker());
+                    JSONObject stateJson = (JSONObject) JsonCodec.encode(state,
+                            diffState, stateType, root.getConnectorTracker());
 
-                    sharedStates.put(connector.getConnectorId(), stateJson);
+                    if (stateJson.length() != 0) {
+                        sharedStates.put(connector.getConnectorId(), stateJson);
+                    }
                 } catch (JSONException e) {
                     throw new PaintException(
                             "Failed to serialize shared state for connector "
index 94d860a2009ebe7e0cb806dc0370be2d673c445a..884e01f9a5cc69ed303a1d551b8f71012085350c 100644 (file)
@@ -526,9 +526,8 @@ public class JsonCodec implements Serializable {
         }
     }
 
-    public static Object encode(Object value, Object referenceValue,
-            Type valueType, ConnectorTracker connectorTracker)
-            throws JSONException {
+    public static Object encode(Object value, Object diffState, Type valueType,
+            ConnectorTracker connectorTracker) throws JSONException {
 
         if (valueType == null) {
             throw new IllegalArgumentException("type must be defined");
@@ -595,7 +594,7 @@ public class JsonCodec implements Serializable {
         } else {
             // Any object that we do not know how to encode we encode by looping
             // through fields
-            return encodeObject(value, referenceValue, connectorTracker);
+            return encodeObject(value, (JSONObject) diffState, connectorTracker);
         }
     }
 
@@ -603,7 +602,7 @@ public class JsonCodec implements Serializable {
         return JSONObject.NULL;
     }
 
-    private static Object encodeObject(Object value, Object referenceValue,
+    private static Object encodeObject(Object value, JSONObject diffState,
             ConnectorTracker connectorTracker) throws JSONException {
         JSONObject jsonMap = new JSONObject();
 
@@ -620,10 +619,11 @@ public class JsonCodec implements Serializable {
                 Type fieldType = getterMethod.getGenericReturnType();
                 Object fieldValue = getterMethod.invoke(value, (Object[]) null);
                 boolean equals = false;
-                Object referenceFieldValue = null;
-                if (referenceValue != null) {
-                    referenceFieldValue = getterMethod.invoke(referenceValue,
-                            (Object[]) null);
+                Object diffStateValue = null;
+                if (diffState != null) {
+                    diffStateValue = diffState.get(fieldName);
+                    Object referenceFieldValue = decodeInternalOrCustomType(
+                            fieldType, diffStateValue, connectorTracker);
                     equals = equals(fieldValue, referenceFieldValue);
                 }
                 if (!equals) {
@@ -637,8 +637,15 @@ public class JsonCodec implements Serializable {
                     }
                     jsonMap.put(
                             fieldName,
-                            encode(fieldValue, referenceFieldValue, fieldType,
+                            encode(fieldValue, diffStateValue, fieldType,
                                     connectorTracker));
+                    if (diffState != null) {
+                        diffState.put(
+                                fieldName,
+                                encode(fieldValue, null, fieldType,
+                                        connectorTracker));
+                    }
+
                     // } else {
                     // System.out.println("Skipping field " + fieldName
                     // + " of type " + fieldType.getName()
index 27dfebd95e0dacd0baa2d8000de2ac93699dbd15..f16642d91b34d2c122c82a1e453b4f557fd4f099 100644 (file)
@@ -20,6 +20,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -54,6 +55,7 @@ public class ConnectorTracker implements Serializable {
     private Set<ClientConnector> uninitializedConnectors = new HashSet<ClientConnector>();
 
     private Root root;
+    private Map<ClientConnector, Object> diffStates = new HashMap<ClientConnector, Object>();
 
     /**
      * Gets a logger for this class
@@ -140,6 +142,7 @@ public class ConnectorTracker implements Serializable {
                         + connectorId + ")");
         connectorIdToConnector.remove(connectorId);
         uninitializedConnectors.remove(connector);
+        diffStates.remove(connector);
     }
 
     /**
@@ -180,6 +183,7 @@ public class ConnectorTracker implements Serializable {
      */
     public void markAllClientSidesUninitialized() {
         uninitializedConnectors.addAll(connectorIdToConnector.values());
+        diffStates.clear();
     }
 
     /**
@@ -220,6 +224,7 @@ public class ConnectorTracker implements Serializable {
                                         + getConnectorAndParentInfo(connector)
                                         + "). This should have been done when the connector was detached.");
                 uninitializedConnectors.remove(connector);
+                diffStates.remove(connector);
                 iterator.remove();
             }
         }
@@ -372,4 +377,12 @@ public class ConnectorTracker implements Serializable {
         return dirtyConnectors;
     }
 
+    public Object getDiffState(ClientConnector connector) {
+        return diffStates.get(connector);
+    }
+
+    public void setDiffState(ClientConnector connector, Object diffState) {
+        diffStates.put(connector, diffState);
+    }
+
 }