Browse Source

Add crude support for only sending state changes (#9026)

tags/7.0.0.beta1
Leif Åstrand 12 years ago
parent
commit
4863e07878

+ 26
- 12
server/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java View 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 "

+ 17
- 10
server/src/com/vaadin/terminal/gwt/server/JsonCodec.java View 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()

+ 13
- 0
server/src/com/vaadin/ui/ConnectorTracker.java View 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);
}

}

Loading…
Cancel
Save