Search in sources :

Example 1 with TableViewportSubscription

use of io.deephaven.web.client.api.subscription.TableViewportSubscription in project deephaven-core by deephaven.

the class JsTable method setSize.

public void setSize(double s) {
    boolean changed = this.size != s;
    if (changed) {
        JsLog.debug("Table ", this, " size changed from ", this.size, " to ", s);
    }
    this.size = s;
    TableViewportSubscription subscription = subscriptions.get(getHandle());
    if (changed && (subscription == null || subscription.getStatus() == TableViewportSubscription.Status.DONE)) {
        // If the size changed, and we have no subscription active, fire. Otherwise, we want to let the
        // subscription itself manage this, so that the size changes are synchronized with data changes,
        // and consumers won't be confused by the table size not matching data.
        CustomEventInit event = CustomEventInit.create();
        event.setDetail(s);
        fireEvent(JsTable.EVENT_SIZECHANGED, event);
    }
    fireEvent(JsTable.INTERNAL_EVENT_SIZELISTENER);
}
Also used : CustomEventInit(elemental2.dom.CustomEventInit) TableViewportSubscription(io.deephaven.web.client.api.subscription.TableViewportSubscription)

Example 2 with TableViewportSubscription

use of io.deephaven.web.client.api.subscription.TableViewportSubscription in project deephaven-core by deephaven.

the class JsTable method setState.

@Override
public void setState(final ClientTableState state) {
    state.onRunning(s -> {
        if (state == currentState) {
            lastVisibleState = state;
            hasInputTable = s.getTableDef().getAttributes().isInputTable();
            // defer the size change so that is there is a viewport sub also waiting for onRunning, it gets it first
            LazyPromise.runLater(() -> {
                if (state == state()) {
                    setSize(state.getSize());
                }
            });
        }
    }, JsRunnable.doNothing());
    final ClientTableState was = currentState;
    if (was != state) {
        state.onRunning(s -> {
            // If already closed, we can ignore this, since we already cleaned those up
            if (!isClosed() && was != null && was != state()) {
                // if we held a subscription
                TableViewportSubscription existingSubscription = subscriptions.remove(was.getHandle());
                if (existingSubscription != null && existingSubscription.getStatus() != TableViewportSubscription.Status.DONE) {
                    JsLog.debug("closing old viewport", state(), existingSubscription.state());
                    // with the replacement state successfully running, we can shut down the old viewport (unless
                    // something
                    // external retained it)
                    existingSubscription.internalClose();
                }
            }
        }, JsRunnable.doNothing());
        boolean historyChanged = false;
        if (was != null) {
            // check if the new state is derived from the current state
            historyChanged = !state.isAncestor(was);
            was.pause(this);
            JsLog.debug("Table state change (new history? ", historyChanged, ") " + "from ", was.getHandle().toString(), was, " to ", state.getHandle().toString(), state);
        }
        currentState = state;
        ActiveTableBinding active = state.getActiveBinding(this);
        if (active == null) {
            state.createBinding(this);
        } else {
            active.changeState(state);
        }
        if (historyChanged) {
            // when the new state is not derived from the current state,
            // then, when the new state succeeds, we will totally releaseTable the previous table,
            // allowing it to be automatically released (if nobody else needs it).
            state.onRunning(success -> {
                if (isClosed()) {
                    // if already closed, we should have already released that handle too
                    return;
                }
                if (currentState != state) {
                    // ancestor
                    return;
                }
                final boolean shouldRelease = !state().isAncestor(was);
                JsLog.debug("History changing state update complete; release? ", shouldRelease, " state: ", was, LazyString.of(was::toStringMinimal));
                if (shouldRelease) {
                    was.releaseTable(this);
                }
            }, () -> {
                LazyPromise.runLater(() -> {
                    if (isClosed()) {
                        // if already closed, we should have already released that handle too
                        return;
                    }
                    if (currentState != state) {
                        // ancestor
                        return;
                    }
                    final boolean shouldRelease = !currentState.isAncestor(was);
                    JsLog.debug("History changing state update failed; release? ", shouldRelease, " state: ", was, LazyString.of(was::toStringMinimal));
                    if (shouldRelease) {
                        was.releaseTable(this);
                    }
                });
            });
        }
        final CustomEventInit init = CustomEventInit.create();
        init.setDetail(state);
        fireEvent(INTERNAL_EVENT_STATECHANGED, init);
    }
}
Also used : ActiveTableBinding(io.deephaven.web.client.state.ActiveTableBinding) ClientTableState(io.deephaven.web.client.state.ClientTableState) CustomEventInit(elemental2.dom.CustomEventInit) TableViewportSubscription(io.deephaven.web.client.api.subscription.TableViewportSubscription)

Example 3 with TableViewportSubscription

use of io.deephaven.web.client.api.subscription.TableViewportSubscription in project deephaven-core by deephaven.

the class JsTable method close.

@JsMethod
public void close() {
    if (currentState == null) {
        // deliberately avoiding JsLog so that it shows up (with stack trace) in developer's console
        JsLog.warn("Table.close() called twice, second call being ignored", this);
        return;
    }
    onClosed.forEach(JsRunnable::run);
    onClosed.clear();
    currentState.pause(this);
    for (ClientTableState s : currentState.reversed()) {
        s.releaseTable(this);
    }
    // make this table unusable.
    currentState = null;
    // LATER: add more cleanup / assertions to aggressively enable GC
    subscriptions.values().forEach(TableViewportSubscription::internalClose);
    subscriptions.clear();
}
Also used : JsRunnable(io.deephaven.web.shared.fu.JsRunnable) ClientTableState(io.deephaven.web.client.state.ClientTableState) TableViewportSubscription(io.deephaven.web.client.api.subscription.TableViewportSubscription) JsMethod(jsinterop.annotations.JsMethod)

Example 4 with TableViewportSubscription

use of io.deephaven.web.client.api.subscription.TableViewportSubscription in project deephaven-core by deephaven.

the class JsTable method setViewport.

@JsMethod
public TableViewportSubscription setViewport(double firstRow, double lastRow, @JsOptional JsArray<Column> columns, @JsOptional Double updateIntervalMs) {
    if (lastVisibleState().getTableDef().getAttributes().getTreeHierarchicalColumnName() != null) {
        // we only need to check the last visible state since if it isn't a tree, our current state isnt either
        throw new IllegalStateException("Cannot set a normal table viewport on a treetable - please re-fetch this as a treetable");
    }
    Column[] columnsCopy = columns != null ? Js.uncheckedCast(columns.slice()) : null;
    ClientTableState currentState = state();
    TableViewportSubscription activeSubscription = subscriptions.get(getHandle());
    if (activeSubscription != null && activeSubscription.getStatus() != TableViewportSubscription.Status.DONE) {
        // hasn't finished, lets reuse it
        activeSubscription.setInternalViewport(firstRow, lastRow, columnsCopy, updateIntervalMs);
        return activeSubscription;
    } else {
        // In the past, we left the old sub going until the new one was ready, then started the new one. But now,
        // we want to reference the old or the new as appropriate - until the new state is running, we keep pumping
        // the old one, then cross over once we're able.
        // We're not responsible here for shutting down the old one here - setState will do that after the new one
        // is running.
        // rewrap current state in a new one, when ready the viewport will be applied
        TableViewportSubscription replacement = new TableViewportSubscription(firstRow, lastRow, columnsCopy, updateIntervalMs, this);
        subscriptions.put(currentState.getHandle(), replacement);
        return replacement;
    }
}
Also used : ClientTableState(io.deephaven.web.client.state.ClientTableState) TableViewportSubscription(io.deephaven.web.client.api.subscription.TableViewportSubscription) JsMethod(jsinterop.annotations.JsMethod)

Aggregations

TableViewportSubscription (io.deephaven.web.client.api.subscription.TableViewportSubscription)4 ClientTableState (io.deephaven.web.client.state.ClientTableState)3 CustomEventInit (elemental2.dom.CustomEventInit)2 JsMethod (jsinterop.annotations.JsMethod)2 ActiveTableBinding (io.deephaven.web.client.state.ActiveTableBinding)1 JsRunnable (io.deephaven.web.shared.fu.JsRunnable)1