+
+ static void notifyListeners(ProjectContextEvent projectContextEvent)
+ {
+ listeners.forEach(l -> l.onProjectContextChange(projectContextEvent));
+ }
+
+ public static void addProjectContextListener(ProjectContextListener listener)
+ {
+ listeners.add(listener);
+ }
+
+ public static void removeProjectContextListener(ProjectContextListener listener)
+ {
+ listeners.remove(listener);
+ }
+
+ static
+ {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(ProjectMachineContext::resourceChanged);
+ MachineRegistry.addMachineRegistryListener(newMap -> updateAllStatus());
+ }
+
+ private static void updateAllStatus()
+ {
+ projectMachineContexts.forEach((p, mc) -> mc.updateStatus());
+ }
+
+ private static void resourceChanged(IResourceChangeEvent event)
+ {
+ // We try to do as many cheap tests first as possible, because this listener is not limited to plain project actions.
+ if (event.getResource() == null)
+ return;
+ IProject project = event.getResource().getProject();
+ if (project == null)
+ return;
+ MachineContext mc = projectMachineContexts.get(project);
+ if (mc == null)
+ return;
+ ProjectContextEventType eventType = ProjectContextEventType.ofResourceChangeEvent(event.getType());
+// if (eventType == ProjectContextEventType.OTHER_CHANGE && project.isOpen())
+// return; // we don't care about all small changes (TODO: research if this has any drawbacks)
+ eventType.getForcedStatus().ifPresent(mc::forceUpdateStatus);
+ notifyListeners(new ProjectContextEvent(mc, eventType));
+ }