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