/*
* Copyright 2003-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.ide.ui.smodel;
import jetbrains.mps.smodel.ModelsEventsCollector;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.smodel.event.SModelEvent;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.Map.Entry;
/**
* User: Alexander Shatalin
* Date: 16.04.2010
*/
public class SModelEventsDispatcher {
private static SModelEventsDispatcher myInstance;
private ModelsEventsCollector myModelsEventsCollector;
private final Map<SModel, Set<SModelEventsListener>> myDescriptorsToListenersMap = new HashMap<SModel, Set<SModelEventsListener>>();
public static SModelEventsDispatcher getInstance() {
if (myInstance == null) {
myInstance = new SModelEventsDispatcher();
}
return myInstance;
}
public void registerListener(SModelEventsListener l) {
SModel modelDescriptor = l.getModelDescriptor();
Set<SModelEventsListener> listeners = myDescriptorsToListenersMap.get(modelDescriptor);
if (listeners == null) {
listeners = new HashSet();
myDescriptorsToListenersMap.put(modelDescriptor, listeners);
getModelsEventsCollector().startListeningToModel(modelDescriptor);
}
listeners.add(l);
}
public void unregisterListener(SModelEventsListener l) {
SModel modelDescriptor = l.getModelDescriptor();
Set<SModelEventsListener> listeners = myDescriptorsToListenersMap.get(modelDescriptor);
assert listeners != null : "specified listener was not registered";
listeners.remove(l);
if (listeners.isEmpty()) {
myDescriptorsToListenersMap.remove(modelDescriptor);
getModelsEventsCollector().stopListeningToModel(modelDescriptor);
if (myDescriptorsToListenersMap.isEmpty()) {
disposeEventsCollector();
}
}
}
public void dispose() {
disposeEventsCollector();
myDescriptorsToListenersMap.clear();
}
private void disposeEventsCollector() {
if (myModelsEventsCollector != null) {
myModelsEventsCollector.dispose();
myModelsEventsCollector = null;
}
}
private ModelsEventsCollector getModelsEventsCollector() {
if (myModelsEventsCollector == null) {
myModelsEventsCollector = new MyEventsCollector();
}
return myModelsEventsCollector;
}
public interface SModelEventsListener {
@NotNull
SModel getModelDescriptor();
void eventsHappened(List<SModelEvent> events);
}
private class MyEventsCollector extends ModelsEventsCollector {
@Override
protected void eventsHappened(List<SModelEvent> events) {
Map<SModel, List<SModelEvent>> descriptorsToEventsMap = new HashMap<SModel, List<SModelEvent>>();
for (SModelEvent event : events) {
SModel descriptor = event.getModelDescriptor();
List<SModelEvent> collectedEvents = descriptorsToEventsMap.get(descriptor);
if (collectedEvents == null) {
collectedEvents = new ArrayList();
descriptorsToEventsMap.put(descriptor, collectedEvents);
}
collectedEvents.add(event);
}
for (Entry<SModel, List<SModelEvent>> entry : descriptorsToEventsMap.entrySet()) {
Set<SModelEventsListener> listeners = myDescriptorsToListenersMap.get(entry.getKey());
if (listeners != null) {
for (SModelEventsListener listener : listeners) {
listener.eventsHappened(entry.getValue());
}
}
}
}
}
}