1 package org.simantics.structural.synchronization.base;
\r
3 import gnu.trove.map.hash.THashMap;
\r
5 import java.util.Collection;
\r
6 import java.util.Collections;
\r
7 import java.util.Map;
\r
9 import org.simantics.databoard.binding.mutable.Variant;
\r
10 import org.simantics.structural.synchronization.protocol.Connection;
\r
11 import org.simantics.structural.synchronization.protocol.SerializedVariable;
\r
13 abstract public class ModuleUpdaterBase<T extends ComponentBase<T>> {
\r
15 public String moduleType;
\r
16 public THashMap<String, PropertyUpdateRule<T>> propertyUpdateRules =
\r
17 new THashMap<String, PropertyUpdateRule<T>>();
\r
18 public THashMap<String, ConnectionUpdateRule<T>> connectionUpdateRules =
\r
19 new THashMap<String, ConnectionUpdateRule<T>>();
\r
20 public boolean isUserComponent;
\r
21 public boolean isComposite;
\r
23 public ModuleUpdaterBase(String moduleType) {
\r
24 this.moduleType = moduleType;
\r
27 public void addPropertyUpdateRule(PropertyUpdateRule<T> rule) {
\r
28 propertyUpdateRules.put(rule.getPropertyName(), rule);
\r
31 public void addConnectionUpdateRule(ConnectionUpdateRule<T> rule) {
\r
32 connectionUpdateRules.put(rule.getConnectionPointName(), rule);
\r
35 public void create(ModuleUpdateContext<T> context, Collection<SerializedVariable> properties, Collection<Connection> connections) {
\r
36 context.command = createAddCommandBuilder(context.getModuleName());
\r
37 applyRules(context, true, properties, connections);
\r
40 abstract public CommandBuilder createAddCommandBuilder(String name);
\r
42 public void update(ModuleUpdateContext<T> context, Collection<SerializedVariable> properties, Collection<Connection> connections) {
\r
43 // Check that the module type matches
\r
44 int moduleTypeId = context.getSolver().getModuleType(context.getModuleId());
\r
45 String moduleTypeName = context.getSolver().getName(moduleTypeId);
\r
46 if(!moduleTypeName.equals(moduleType)) {
\r
47 context.getSolver().remove(context.getModuleId());
\r
48 context.component.componentId = -1;
\r
49 context.setModuleId(-1);
\r
50 create(context, properties, connections);
\r
55 context.command = createUpdateCommandBuilder(context.getModuleName());
\r
56 applyRules(context, false, properties, connections);
\r
60 abstract public CommandBuilder createUpdateCommandBuilder(String name);
\r
62 private void applyRules(ModuleUpdateContext<T> context, boolean inCreate,
\r
63 Collection<SerializedVariable> properties, Collection<Connection> connections) {
\r
64 THashMap<String, Variant> propertyMap = new THashMap<String, Variant>(properties.size());
\r
65 Map<String, Collection<String>> connectionMap = connections.isEmpty()
\r
66 ? Collections.<String, Collection<String>>emptyMap()
\r
67 : new THashMap<String, Collection<String>>(connections.size());
\r
68 for(SerializedVariable property : properties)
\r
69 propertyMap.put(property.name, property.value);
\r
70 for(Connection connection : connections)
\r
71 connectionMap.put(connection.relation, connection.connectionPoints);
\r
73 context.incPendingCount(); // To prevent premature execution of the command
\r
74 for(SerializedVariable property : properties) {
\r
75 PropertyUpdateRule<T> rule = propertyUpdateRules.get(property.name);
\r
77 rule.apply(context, inCreate, propertyMap, connectionMap, property.value);
\r
78 else if(property.name.equals("IsAttached"))
\r
81 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
\r
82 System.out.println(" skipped property " + property.name + " " + property.toString());
\r
85 for(Connection connection : connections) {
\r
86 ConnectionUpdateRule<T> rule = connectionUpdateRules.get(connection.relation);
\r
88 rule.apply(context, propertyMap, connection.connectionPoints);
\r
90 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
\r
91 System.out.println(" skipped connection " + connection.relation + " " + connection.connectionPoints);
\r
95 THashMap<String, ConnectionUpdateRule<T>> unusedConnectionUpdateRules =
\r
96 new THashMap<String, ConnectionUpdateRule<T>>(connectionUpdateRules);
\r
97 for(Connection connection : connections) {
\r
98 ConnectionUpdateRule<T> rule = unusedConnectionUpdateRules.remove(connection.relation);
\r
100 rule.apply(context, propertyMap, connection.connectionPoints);
\r
102 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
\r
103 System.out.println(" skipped connection " + connection.relation + " " + connection.connectionPoints);
\r
105 for(ConnectionUpdateRule<T> rule : unusedConnectionUpdateRules.values())
\r
106 rule.apply(context, propertyMap, Collections.<String>emptyList());
\r
108 context.decPendingCount();
\r