diff options
author | Leif Åstrand <leif@vaadin.com> | 2015-01-09 08:29:54 +0200 |
---|---|---|
committer | Henri Sara <hesara@vaadin.com> | 2015-01-12 13:00:20 +0000 |
commit | 2e0d4f149a9b02e38fe32411d66b715714bd526a (patch) | |
tree | 51b1e7d821231d743c855c4ccc6c7dad929ad553 /client | |
parent | d7dbc0fb1b863089108035cd9a4094aacbdbd290 (diff) | |
download | vaadin-framework-2e0d4f149a9b02e38fe32411d66b715714bd526a.tar.gz vaadin-framework-2e0d4f149a9b02e38fe32411d66b715714bd526a.zip |
Add @BackgroundMessage annotation (#15373)
Change-Id: Id5367b7b1ef4b7dbabfd58902ac6134222e641ba
Diffstat (limited to 'client')
5 files changed, 95 insertions, 12 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index aa00516feb..c00e5a8dae 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -81,6 +81,7 @@ import com.vaadin.client.metadata.NoDataException; import com.vaadin.client.metadata.Property; import com.vaadin.client.metadata.Type; import com.vaadin.client.metadata.TypeData; +import com.vaadin.client.metadata.TypeDataStore; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.AbstractConnector; import com.vaadin.client.ui.FontIcon; @@ -1275,7 +1276,6 @@ public class ApplicationConnection implements HasHandlers { } hasActiveRequest = true; requestStartTime = new Date(); - loadingIndicator.trigger(); eventBus.fireEvent(new RequestStartingEvent(this)); } @@ -1300,7 +1300,8 @@ public class ApplicationConnection implements HasHandlers { Scheduler.get().scheduleDeferred(new Command() { @Override public void execute() { - if (!hasActiveRequest()) { + if (!isApplicationRunning() + || !(hasActiveRequest() || deferredSendPending)) { getLoadingIndicator().hide(); // If on Liferay and session expiration management is in @@ -2720,8 +2721,8 @@ public class ApplicationConnection implements HasHandlers { * */ public void sendPendingVariableChanges() { - if (!deferedSendPending) { - deferedSendPending = true; + if (!deferredSendPending) { + deferredSendPending = true; Scheduler.get().scheduleFinally(sendPendingCommand); } } @@ -2729,11 +2730,11 @@ public class ApplicationConnection implements HasHandlers { private final ScheduledCommand sendPendingCommand = new ScheduledCommand() { @Override public void execute() { - deferedSendPending = false; + deferredSendPending = false; doSendPendingVariableChanges(); } }; - private boolean deferedSendPending = false; + private boolean deferredSendPending = false; private void doSendPendingVariableChanges() { if (isApplicationRunning()) { @@ -2768,7 +2769,7 @@ public class ApplicationConnection implements HasHandlers { */ private void buildAndSendVariableBurst( LinkedHashMap<String, MethodInvocation> pendingInvocations) { - + boolean showLoadingIndicator = false; JsonArray reqJson = Json.createArray(); if (!pendingInvocations.isEmpty()) { if (ApplicationConfiguration.isDebugMode()) { @@ -2791,10 +2792,16 @@ public class ApplicationConnection implements HasHandlers { Method method = type.getMethod(invocation .getMethodName()); parameterTypes = method.getParameterTypes(); + + showLoadingIndicator |= !TypeDataStore + .isBackgroundMessage(method); } catch (NoDataException e) { throw new RuntimeException("No type data for " + invocation.toString(), e); } + } else { + // Always show loading indicator for legacy requests + showLoadingIndicator = true; } for (int i = 0; i < invocation.getParameters().length; ++i) { @@ -2826,6 +2833,9 @@ public class ApplicationConnection implements HasHandlers { getConfiguration().setWidgetsetVersionSent(); } + if (showLoadingIndicator) { + getLoadingIndicator().trigger(); + } makeUidlRequest(reqJson, extraParams); } diff --git a/client/src/com/vaadin/client/VLoadingIndicator.java b/client/src/com/vaadin/client/VLoadingIndicator.java index e873005d3a..6a6eaf71b2 100644 --- a/client/src/com/vaadin/client/VLoadingIndicator.java +++ b/client/src/com/vaadin/client/VLoadingIndicator.java @@ -154,6 +154,18 @@ public class VLoadingIndicator { } /** + * Triggers displaying of this loading indicator unless it's already visible + * or scheduled to be shown after a delay. + * + * @since + */ + public void ensureTriggered() { + if (!isVisible() && !firstTimer.isRunning()) { + trigger(); + } + } + + /** * Shows the loading indicator in its standard state and triggers timers for * transitioning into the "second" and "third" states. */ diff --git a/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java b/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java index c46db08553..74c8dfb02f 100644 --- a/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java +++ b/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java @@ -104,6 +104,43 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector { rpcProxy.requestRows(firstRowIndex, numberOfRows, cached.getStart(), cached.length()); + + /* + * Show the progress indicator if there is a pending data request + * and some of the visible rows are being requested. The RPC in + * itself will not trigger the indicator since it might just fetch + * some rows in the background to fill the cache. + * + * The indicator will be hidden by the framework when the response + * is received (unless another request is already on its way at that + * point). + */ + if (getRequestedAvailability().intersects( + Range.withLength(firstRowIndex, numberOfRows))) { + getConnection().getLoadingIndicator().ensureTriggered(); + } + } + + @Override + public void ensureAvailability(int firstRowIndex, int numberOfRows) { + super.ensureAvailability(firstRowIndex, numberOfRows); + + /* + * We trigger the indicator already at this point since the actual + * RPC will not be sent right away when waiting for the response to + * a previous request. + * + * Only triggering here would not be enough since the check that + * sets isWaitingForData is deferred. We don't want to trigger the + * loading indicator here if we don't know that there is actually a + * request going on since some other bug might then cause the + * loading indicator to not be hidden. + */ + if (isWaitingForData() + && !Range.withLength(firstRowIndex, numberOfRows) + .isSubsetOf(getCachedRange())) { + getConnection().getLoadingIndicator().ensureTriggered(); + } } @Override diff --git a/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java b/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java index ffd1d4d170..0ad1631e19 100644 --- a/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java +++ b/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java @@ -262,10 +262,19 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> { ensureCoverageCheck(); } + /** + * Gets the row index range that was requested by the previous call to + * {@link #ensureAvailability(int, int)}. + * + * @return the requested availability range + */ + public Range getRequestedAvailability() { + return requestedAvailability; + } + private void checkCacheCoverage() { - if (currentRequestCallback != null) { - // Anyone clearing currentRequestCallback should run this method - // again + if (isWaitingForData()) { + // Anyone clearing the waiting status should run this method again return; } @@ -301,6 +310,17 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> { Profiler.leave("AbstractRemoteDataSource.checkCacheCoverage"); } + /** + * Checks whether this data source is currently waiting for more rows to + * become available. + * + * @return <code>true</code> if waiting for data; otherwise + * <code>false</code> + */ + public boolean isWaitingForData() { + return currentRequestCallback != null; + } + private void discardStaleCacheEntries() { Range[] cacheParition = cached.partitionWith(getMaxCacheRange()); dropFromCache(cacheParition[0]); @@ -378,7 +398,7 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> { Range received = Range.withLength(firstRowIndex, rowData.size()); - if (currentRequestCallback != null) { + if (isWaitingForData()) { cacheStrategy.onDataArrive(Duration.currentTimeMillis() - currentRequestCallback.requestStart, received.length()); diff --git a/client/src/com/vaadin/client/metadata/TypeDataStore.java b/client/src/com/vaadin/client/metadata/TypeDataStore.java index e3db0ccded..adbf24d411 100644 --- a/client/src/com/vaadin/client/metadata/TypeDataStore.java +++ b/client/src/com/vaadin/client/metadata/TypeDataStore.java @@ -29,7 +29,7 @@ import com.vaadin.shared.annotations.NoLayout; public class TypeDataStore { public static enum MethodAttribute { - DELAYED, LAST_ONLY, NO_LAYOUT; + DELAYED, LAST_ONLY, NO_LAYOUT, BACKGROUND_MESSAGE; } private static final String CONSTRUCTOR_NAME = "!new"; @@ -219,6 +219,10 @@ public class TypeDataStore { return hasMethodAttribute(method, MethodAttribute.DELAYED); } + public static boolean isBackgroundMessage(Method method) { + return hasMethodAttribute(method, MethodAttribute.BACKGROUND_MESSAGE); + } + private static boolean hasMethodAttribute(Method method, MethodAttribute attribute) { FastStringSet attributes = get().methodAttributes.get(method |