package jetbrains.mps.vcs.changesmanager;
/*Generated by MPS */
import com.intellij.util.containers.BidirectionalMultiMap;
import org.jetbrains.mps.openapi.model.SNodeId;
import jetbrains.mps.smodel.event.SModelEvent;
import com.intellij.util.containers.BidirectionalMap;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.smodel.event.SModelRootEvent;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import jetbrains.mps.smodel.event.SModelChildEvent;
import jetbrains.mps.smodel.event.SModelPropertyEvent;
import jetbrains.mps.smodel.event.SModelReferenceEvent;
public class EventConsumingMapping {
private BidirectionalMultiMap<SNodeId, SModelEvent> myNodesToUnconsumedEvents = new BidirectionalMultiMap<SNodeId, SModelEvent>();
private BidirectionalMap<SNodeId, SModelEvent> myAddedNodesToEvents = new BidirectionalMap<SNodeId, SModelEvent>();
public EventConsumingMapping() {
}
private void consumeAllForNode(SNode node) {
final SNodeId id = node.getNodeId();
Sequence.fromIterable(((Iterable<SModelEvent>) myNodesToUnconsumedEvents.getValues(id))).where(new IWhereFilter<SModelEvent>() {
public boolean accept(SModelEvent e) {
return !(e instanceof SModelRootEvent);
}
}).toListSequence().visitAll(new IVisitor<SModelEvent>() {
public void visit(SModelEvent e) {
myNodesToUnconsumedEvents.remove(id, e);
}
});
}
public synchronized void addEvent(SModelEvent event) {
SNode affectedNode = null;
SNode addedNode = null;
if (event instanceof SModelRootEvent) {
SModelRootEvent re = (SModelRootEvent) event;
affectedNode = re.getRoot();
if (re.isAdded()) {
addedNode = affectedNode;
}
} else if (event instanceof SModelChildEvent) {
SModelChildEvent ce = (SModelChildEvent) event;
affectedNode = ce.getParent();
if (ce.isAdded()) {
addedNode = ce.getChild();
}
} else if (event instanceof SModelPropertyEvent) {
affectedNode = ((SModelPropertyEvent) event).getNode();
} else if (event instanceof SModelReferenceEvent) {
affectedNode = ((SModelReferenceEvent) event).getReference().getSourceNode();
}
if (affectedNode == null) {
myNodesToUnconsumedEvents.put(null, event);
return;
}
if (!(myAddedNodesToEvents.containsKey(affectedNode.getNodeId()))) {
if (event instanceof SModelRootEvent) {
SModelRootEvent rootEvent = (SModelRootEvent) event;
if (rootEvent.isRemoved()) {
consumeAllForNode(affectedNode);
}
} else if (event instanceof SModelChildEvent) {
SModelChildEvent childEvent = (SModelChildEvent) event;
SNode child = childEvent.getChild();
if (childEvent.isRemoved()) {
consumeAllForNode(child);
}
}
myNodesToUnconsumedEvents.put(affectedNode.getNodeId(), event);
}
if (addedNode != null) {
myAddedNodesToEvents.put(addedNode.getNodeId(), event);
}
}
public synchronized boolean removeEvent(SModelEvent event) {
// return true if this event should be processed
myAddedNodesToEvents.removeValue(event);
return myNodesToUnconsumedEvents.removeValue(event);
}
}