blob: 6cfa426e796e74df5fce4ee0df24307531ce6db7 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2017, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.r.apps.ui;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.ts.core.Tool;
@NonNullByDefault
public class AppRegistry {
public static final byte APP_STARTED= 1;
public static final byte APP_STOPPED= 2;
public static class AppStateEvent extends RApp.AppEvent {
private final byte type;
private final URL id;
public AppStateEvent(final byte type, final URL id, final RApp app) {
super(app);
this.type= type;
this.id= id;
}
public byte getType() {
return this.type;
}
public URL getId() {
return this.id;
}
}
public static interface Listener {
void onAppStateChanged(AppStateEvent event);
}
private static class AppEntry {
private final URL id;
private RApp app;
private boolean isRunning;
public AppEntry(final URL id) {
this.id= id;
}
}
private static final AppRegistry INSTANCE= new AppRegistry();
public static AppRegistry getInstance() {
return INSTANCE;
}
private final Map<URL, AppEntry> sessions= new HashMap<>();
private final CopyOnWriteIdentityListSet<Listener> listeners= new CopyOnWriteIdentityListSet<>();
public AppRegistry() {
}
public void addListener(final Listener listener) {
this.listeners.add(listener);
}
public void removeListener(final Listener listener) {
this.listeners.remove(listener);
}
private void notifyListeners(final AppStateEvent event) {
for (final Listener listener : this.listeners) {
listener.onAppStateChanged(event);
}
}
public synchronized void onAppStarted(final URL id, final RApp app) {
final AppEntry entry= this.sessions.computeIfAbsent(id, AppEntry::new);
if (entry.isRunning) {
notifyListeners(new AppStateEvent(APP_STOPPED, id, entry.app));
}
entry.app= app;
entry.isRunning= true;
notifyListeners(new AppStateEvent(APP_STARTED, id, app));
}
public synchronized void onAppStopped(final URL id, final RApp app) {
final AppEntry entry= this.sessions.get(id);
if (entry != null && entry.app == app) {
entry.isRunning= false;
notifyListeners(new AppStateEvent(APP_STOPPED, id, app));
}
}
public synchronized @Nullable RApp getApp(final URL id) {
final AppEntry entry= this.sessions.get(id);
return (entry != null) ? entry.app : null;
}
public synchronized @Nullable RApp getApp(final Tool tool) {
for (final AppEntry entry : this.sessions.values()) {
if (entry.isRunning && entry.app.getTool() == tool) {
return entry.app;
}
}
return null;
}
}