b1708482514def0ded98bbacd3b584d979c709aa
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / nature / MachineContext.java
1 package net.mograsim.plugin.nature;
2
3 import java.io.IOException;
4 import java.util.HashSet;
5 import java.util.Objects;
6 import java.util.Optional;
7 import java.util.Set;
8
9 import org.eclipse.core.resources.IProject;
10 import org.eclipse.jface.util.PropertyChangeEvent;
11 import org.eclipse.ui.preferences.ScopedPreferenceStore;
12
13 import net.mograsim.machine.Machine;
14 import net.mograsim.machine.MachineDefinition;
15 import net.mograsim.machine.MachineRegistry;
16
17 public class MachineContext
18 {
19         IProject owner;
20         ScopedPreferenceStore prefs;
21         Optional<String> machineId;
22         Optional<MachineDefinition> machineDefinition;
23         Optional<Machine> activeMachine;
24
25         private final Set<ActiveMachineListener> observers = new HashSet<>();
26
27         public MachineContext(IProject owner)
28         {
29                 this.owner = Objects.requireNonNull(owner);
30                 prefs = ProjectMachineContext.getProjectPrefs(owner);
31                 prefs.addPropertyChangeListener(this::preferenceListener);
32                 machineId = ProjectMachineContext.getMachineIdFrom(prefs);
33                 updateDefinition();
34         }
35
36         public final IProject getProject()
37         {
38                 return owner;
39         }
40
41         public final ScopedPreferenceStore getPreferences()
42         {
43                 return prefs;
44         }
45
46         /**
47          * Returns true if the project configuration is valid in the current environment
48          */
49         public final boolean isCurrentyValid()
50         {
51                 return machineDefinition.isPresent();
52         }
53
54         /**
55          * Returns true if the persisted project configuration itself is intact
56          */
57         public final boolean isIntact()
58         {
59                 return machineId.isPresent();
60         }
61
62         /**
63          * Returns true if a machine is instantiated and (possibly) running
64          */
65         public final boolean isActive()
66         {
67                 return activeMachine.isPresent();
68         }
69
70         /**
71          * Sets the projects machineId. Will likely break things, if the {@link MachineContext} {@link #isActive()}.
72          */
73         public final boolean setMachineId(String machineId)
74         {
75                 prefs.setValue(ProjectMachineContext.MACHINE_PROPERTY, machineId);
76                 try
77                 {
78                         prefs.save();
79                 }
80                 catch (IOException e)
81                 {
82                         e.printStackTrace();
83                         return false;
84                 }
85                 return true;
86         }
87
88         /**
89          * Sets the active machine in the {@link MachineContext}'s project scope.
90          */
91         public final void setActiveMachine(Machine machine)
92         {
93                 activeMachine = Optional.ofNullable(machine);
94                 notifyObservers();
95         }
96
97         public final Optional<String> getMachineId()
98         {
99                 return machineId;
100         }
101
102         public final Optional<MachineDefinition> getMachineDefinition()
103         {
104                 return machineDefinition;
105         }
106
107         public final Optional<Machine> getActiveMachine()
108         {
109                 return activeMachine;
110         }
111
112         final void updateDefinition()
113         {
114                 machineDefinition = machineId.map(MachineRegistry::getMachine);
115         }
116
117         private void preferenceListener(PropertyChangeEvent changeEvent)
118         {
119                 if (changeEvent.getProperty().equals(ProjectMachineContext.MACHINE_PROPERTY))
120                 {
121                         machineId = Optional.ofNullable((String) changeEvent.getNewValue());
122                         updateDefinition();
123                 }
124         }
125
126         public void registerObserver(ActiveMachineListener ob)
127         {
128                 observers.add(ob);
129                 ob.setMachine(activeMachine);
130         }
131
132         public void deregisterObserver(ActiveMachineListener ob)
133         {
134                 observers.remove(ob);
135         }
136
137         private void notifyObservers()
138         {
139                 observers.forEach(ob -> ob.setMachine(activeMachine));
140         }
141
142         @FunctionalInterface
143         public static interface ActiveMachineListener
144         {
145                 void setMachine(Optional<Machine> machine);
146         }
147 }