blob: 638dee76309a8e93c769c147502752622db613b6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.core.internal.contexts;
import java.lang.ref.Reference;
import java.util.Objects;
import java.util.Set;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.contexts.RunAndTrack;
import org.eclipse.e4.core.internal.contexts.EclipseContext.Scheduled;
public class TrackableComputationExt extends Computation {
final private IEclipseContext originatingContext;
final private RunAndTrack runnable;
private ContextChangeEvent cachedEvent;
public TrackableComputationExt(RunAndTrack runnable, IEclipseContext originatingContext) {
this.runnable = runnable;
this.originatingContext = originatingContext;
init();
}
@Override
public int hashCode() {
return hashCode;
}
@Override
protected int calcHashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Objects.hashCode(originatingContext);
return prime * result + Objects.hashCode(runnable);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TrackableComputationExt other = (TrackableComputationExt) obj;
return Objects.equals(this.originatingContext, other.originatingContext)
&& Objects.equals(this.runnable, other.runnable);
}
@Override
public void handleInvalid(ContextChangeEvent event, Set<Scheduled> scheduledList) {
// don't call super - we keep the link unless uninjected / disposed
int eventType = event.getEventType();
if (eventType == ContextChangeEvent.INITIAL || eventType == ContextChangeEvent.DISPOSE) {
// process right away
update(event);
} else {
// schedule processing
scheduledList.add(new Scheduled(this, event));
}
}
public boolean update(ContextChangeEvent event) {
// is this a structural event?
// structural changes: INITIAL, DISPOSE, UNINJECTED are always processed right away
int eventType = event.getEventType();
if ((runnable instanceof RunAndTrackExt) && ((RunAndTrackExt) runnable).batchProcess()) {
if ((eventType == ContextChangeEvent.ADDED) || (eventType == ContextChangeEvent.REMOVED)) {
cachedEvent = event;
EclipseContext eventsContext = (EclipseContext) event.getContext();
eventsContext.addWaiting(this);
return true;
}
}
((EclipseContext) originatingContext).pushComputation(this);
boolean result = true;
try {
if (cachedEvent != null) {
if (runnable instanceof RunAndTrackExt) {
result = ((RunAndTrackExt) runnable).update(event.getContext(), event.getEventType(), event.getArguments());
if (eventType != ContextChangeEvent.DISPOSE && eventType != ContextChangeEvent.UNINJECTED)
cachedEvent = null;
} else if (eventType != ContextChangeEvent.DISPOSE && eventType != ContextChangeEvent.UNINJECTED) {
result = runnable.changed(originatingContext);
cachedEvent = null;
}
}
if (eventType != ContextChangeEvent.UPDATE) {
if (runnable instanceof RunAndTrackExt)
result = ((RunAndTrackExt) runnable).update(event.getContext(), event.getEventType(), event.getArguments());
else if (eventType != ContextChangeEvent.DISPOSE && eventType != ContextChangeEvent.UNINJECTED)
result = runnable.changed(originatingContext);
}
} finally {
((EclipseContext) originatingContext).popComputation(this);
}
EclipseContext eventsContext = (EclipseContext) event.getContext();
if (eventType == ContextChangeEvent.DISPOSE) {
if (originatingContext.equals(eventsContext)) {
((EclipseContext) originatingContext).removeRAT(this);
return false;
}
}
if (!result) {
((EclipseContext) originatingContext).removeRAT(this);
}
return result;
}
@Override
public String toString() {
return runnable.toString();
}
public Reference<Object> getReference() {
if (runnable instanceof RunAndTrackExt)
return ((RunAndTrackExt) runnable).getReference();
return null;
}
}