--- /dev/null
+package org.simantics.structural.synchronization.base;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+\r
+public class ModuleUpdateContext<T extends ComponentBase<T>> {\r
+\r
+ private ModuleUpdaterBase<T> updater;\r
+ private final SynchronizationEventHandlerBase<T> handler;\r
+ public final T component;\r
+ public CommandBuilder command;\r
+ private ArrayList<Runnable> postUpdateActions; \r
+ private THashMap<String, Variant> storedProperties;\r
+ \r
+ private int pendingRuleCount;\r
+ public boolean stateLoadedFromUndo;\r
+\r
+ public ModuleUpdateContext(SynchronizationEventHandlerBase<T> handler, ModuleUpdaterBase<T> updater, T component) {\r
+ assert(updater != null);\r
+ this.handler = handler;\r
+ this.updater = updater;\r
+ this.component = component;\r
+ }\r
+\r
+ public void incPendingCount() {\r
+ ++pendingRuleCount;\r
+ }\r
+ \r
+ public void decPendingCount() {\r
+ --pendingRuleCount;\r
+ if(pendingRuleCount == 0) {\r
+ try {\r
+ command.apply(getSolver());\r
+ command = null;\r
+ } catch (Exception e) {\r
+ handler.reportProblem("Exception while issuing command.", e);\r
+ }\r
+ if(getModuleId() <= 0) {\r
+ setModuleId(getSolver().getId(getModuleName()));\r
+ component.setModuleId(getModuleId());\r
+ }\r
+ if(postUpdateActions != null) {\r
+ for(Runnable action : postUpdateActions)\r
+ try {\r
+ action.run();\r
+ } catch(Exception e) {\r
+ handler.reportProblem("Post update action failed.", e);\r
+ }\r
+ postUpdateActions = null;\r
+ }\r
+ handler.resolver.unmarkPending(component);\r
+ }\r
+ }\r
+ \r
+ public void addPostUpdateAction(Runnable action) {\r
+ if(postUpdateActions == null)\r
+ postUpdateActions = new ArrayList<Runnable>(2);\r
+ postUpdateActions.add(action);\r
+ }\r
+\r
+ public int getModuleId() {\r
+ return component.getModuleId();\r
+ }\r
+ \r
+ public SynchronizationEventHandlerBase<T> getHandler() {\r
+ return handler;\r
+ }\r
+\r
+ public void setModuleId(int moduleId) {\r
+ component.setModuleId(moduleId);\r
+ }\r
+\r
+ public Solver getSolver() {\r
+ return handler.solver;\r
+ }\r
+ \r
+ public <S> S getConcreteSolver() {\r
+ return handler.solver.getConcreteSolver();\r
+ }\r
+ \r
+ public String getModuleName() {\r
+ return component.solverComponentName;\r
+ }\r
+\r
+ public void setModuleName(String moduleName) {\r
+ component.solverComponentName = moduleName;\r
+ }\r
+\r
+ public void reportProblem(String description) {\r
+ handler.reportProblem(description);\r
+ \r
+ }\r
+ \r
+ public void reportProblem(String description, Exception e) {\r
+ handler.reportProblem(description, e);\r
+ }\r
+\r
+ public void resolveReference(String connectionPoint, ModuleCallback moduleCallback) {\r
+ handler.resolver.resolveReference(component, connectionPoint, moduleCallback);\r
+ }\r
+ \r
+ public void storeProperty(String name, Variant value) {\r
+ if(storedProperties == null)\r
+ storedProperties = new THashMap<String, Variant>();\r
+ storedProperties.put(name, value);\r
+ }\r
+ \r
+ public Variant getStoredProperty(String name) {\r
+ if(storedProperties == null)\r
+ return null;\r
+ return storedProperties.get(name);\r
+ }\r
+\r
+ public void addPostSynchronizationAction(Runnable action) {\r
+ handler.addPostSynchronizationAction(action); \r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ public <C> C getConcreteCommand() {\r
+ return (C)command.getConcrete();\r
+ }\r
+\r
+ public void setDidChanges() {\r
+ handler.setDidChanges();\r
+ }\r
+ \r
+ ArrayList<ResynchronizeAction> resynchronizeActions;\r
+\r
+ private class ResynchronizeAction {\r
+ final String connectionPoint;\r
+ final ModuleCallback callback;\r
+ \r
+ public ResynchronizeAction(String connectionPoint,\r
+ ModuleCallback callback) {\r
+ this.connectionPoint = connectionPoint;\r
+ this.callback = callback;\r
+ }\r
+ }\r
+ \r
+ public void resynchronize(String connectionPoint, ModuleCallback callback) {\r
+ if(resynchronizeActions == null) {\r
+ resynchronizeActions = new ArrayList<ResynchronizeAction>();\r
+ handler.addPostSynchronizationAction(new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ ArrayList<ResynchronizeAction> resynchronizeActions = ModuleUpdateContext.this.resynchronizeActions;\r
+ ModuleUpdateContext.this.resynchronizeActions = null;\r
+ \r
+ command = updater.createUpdateCommandBuilder(getModuleName());\r
+ for(ResynchronizeAction action : resynchronizeActions)\r
+ resolveReference(action.connectionPoint, action.callback);\r
+ try {\r
+ command.apply(getSolver());\r
+ } catch (Exception e) {\r
+ handler.reportProblem("Exception while issuing command.", e);\r
+ }\r
+ }\r
+ });\r
+ }\r
+ resynchronizeActions.add(new ResynchronizeAction(connectionPoint, callback));\r
+ }\r
+\r
+}\r