X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fscl%2FSCLNodeManager.java;h=2e53ce85a8227591f968c592ed4e5fe789f8c662;hb=82ed7c74;hp=8a0ee6ef1715ee91477976e6eac24440c2745033;hpb=fdbe87627e92805701d0672fbe8f1dc60b7f7b00;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLNodeManager.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLNodeManager.java index 8a0ee6ef1..2e53ce85a 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLNodeManager.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLNodeManager.java @@ -1,278 +1,283 @@ -package org.simantics.modeling.scl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.simantics.databoard.Datatypes; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.type.Datatype; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.variable.NodeSupport; -import org.simantics.modeling.ModelingResources; -import org.simantics.scl.compiler.types.Type; -import org.simantics.simulator.variable.Realm; -import org.simantics.simulator.variable.exceptions.NodeManagerException; -import org.simantics.simulator.variable.exceptions.NotInRealmException; -import org.simantics.simulator.variable.impl.AbstractNodeManager; -import org.simantics.structural.stubs.StructuralResource2; - -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - -public class SCLNodeManager extends AbstractNodeManager { - - public static final String ROOT = "@"; - - SCLRealm realm; - THashMap valueCache = new THashMap(); - THashMap> listeners = new THashMap>(); - - AtomicBoolean fireNodeListenersScheduled = new AtomicBoolean(false); - Runnable fireNodeListeners = new Runnable() { - @Override - public void run() { - fireNodeListenersScheduled.set(false); - final TObjectProcedure procedure = new TObjectProcedure() { - @Override - public boolean execute(Runnable object) { - object.run(); - return true; - } - }; - synchronized(listeners) { - listeners.forEachValue(new TObjectProcedure>() { - @Override - public boolean execute(THashSet object) { - object.forEach(procedure); - return true; - } - }); - } - } - }; - - Runnable clearValueCache = new Runnable() { - @Override - public void run() { - valueCache.clear(); - } - }; - - public SCLNodeManager(SCLRealm realm) { - super(); - this.realm = realm; - } - - @Override - public Realm getRealm() { - return realm; - } - - public String getRoot() { - return ROOT; - } - - @Override - public String getName(String node) { - if(ROOT.equals(node)) { - String id = realm.id; - int lastSlash = id.lastIndexOf("/"); - if(lastSlash == -1) throw new IllegalStateException("Invalid realm id " + id); - String name = id.substring(lastSlash+1); - return name; - } else - return node; - } - - @Override - public void addNodeListener(String node, Runnable listener) { - synchronized(listeners) { - THashSet l = listeners.get(node); - if(l == null) { - l = new THashSet(); - listeners.put(node, l); - } - l.add(listener); - } - realm.asyncExec(listener); - } - - @Override - public void removeNodeListener(String node, Runnable listener) { - synchronized(listeners) { - THashSet l = listeners.get(node); - if(l != null) { - l.remove(listener); - if(l.isEmpty()) - listeners.remove(node); - } - } - } - - public void fireNodeListeners() { - if(!fireNodeListenersScheduled.getAndSet(true)) - realm.asyncExec(fireNodeListeners); - } - - public void fireNodeListenersSync() { - try { - realm.syncExec(fireNodeListeners); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - public void refreshVariables() { - realm.asyncExec(clearValueCache); - fireNodeListeners(); - } - - public void refreshVariablesSync() { - try { - realm.syncExec(clearValueCache); - } catch (InterruptedException e) { - e.printStackTrace(); - } - fireNodeListenersSync(); - } - - @Override - public String getNode(String path) throws NodeManagerException { - checkThreadAccess(); - throw new UnsupportedOperationException(); - } - - @Override - public String getChild(String node, String name) - throws NodeManagerException { - checkThreadAccess(); - return null; - } - - @Override - public String getProperty(String node, String name) - throws NodeManagerException { - checkThreadAccess(); - if(node.equals(ROOT)) - return name; - else - return null; - } - - @Override - public List getChildren(String node) throws NodeManagerException { - checkThreadAccess(); - return Collections.emptyList(); - } - - @Override - public List getProperties(String node) throws NodeManagerException { - checkThreadAccess(); - if(!node.equals(ROOT)) - return Collections.emptyList(); - - Set variables = realm.getConnection().getVariables(); - return new ArrayList(variables); - - } - - @Override - public Datatype getDatatype(String node) throws NodeManagerException { - checkThreadAccess(); - try { - Datatype type = getDatatypeForValue(getSCLValue(node)); - return type; - } catch (DatabaseException e) { - e.printStackTrace(); - } - return null; - } - - @Override - public Object getValue(String node, Binding binding) throws NodeManagerException { - checkThreadAccess(); - return getSCLValue(node); - } - - - private Type getType(String name) { - return realm.getConnection().getVariableType(name); - } - - private Datatype getDatatypeForValue(Object value) throws DatabaseException { - if(value instanceof Double) return Datatypes.DOUBLE; - if(value instanceof Float) return Datatypes.FLOAT; - if(value instanceof Integer) return Datatypes.INTEGER; - if(value instanceof Long) return Datatypes.LONG; - if(value instanceof String) return Datatypes.STRING; - if(value instanceof Boolean) return Datatypes.BOOLEAN; - - if (value instanceof List) return null; - - if (value instanceof Object) return null; - - if (value == null) return null; - - else throw new DatabaseException("No Datatype for value " + value); - } - - @Override - public void setValue(String node, Object value, Binding binding) - throws NodeManagerException { - checkThreadAccess(); - valueCache.put(node, value); - realm.getConnection().setVariable(node, getType(node), value); - realm.nodeManager.valueCache.put(node, value); - refreshVariables(); - } - - public void setValue(String node, Type type, Object value) - throws NodeManagerException { - - checkThreadAccess(); - valueCache.put(node, value); - realm.getConnection().setVariable(node, type, value); - - NodeSupport support = SCLSessionManager.getOrCreateNodeSupport(realm.getId()); - support.structureCache.put(ROOT, null); - support.valueCache.put(node, null); - - realm.nodeManager.valueCache.put(node, value); - realm.nodeManager. - refreshVariables(); - } - - static final Set COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component); - - @Override - public Set getClassifications(String node) throws NodeManagerException { - checkThreadAccess(); - if(node.equals(ROOT)) - return COMPONENT_CLASS; - else - return Collections.emptySet(); - } - - private Object getSCLValue(String node) throws NodeManagerException { - Object value = valueCache.get(node); - if(value == null) { - value = realm.getConnection().getVariableValue(node); - valueCache.put(node, value); - } - return value; - } - - private void checkThreadAccess() throws NodeManagerException { - if(Thread.currentThread() != realm.getThread()) - throw new NotInRealmException(); - } - - @Override - public String getPropertyURI(String parent, String property) { - return ModelingResources.URIs.SCLCommandSession_hasValue; - } -} +package org.simantics.modeling.scl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.simantics.databoard.Datatypes; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.type.Datatype; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.NodeSupport; +import org.simantics.modeling.ModelingResources; +import org.simantics.scl.compiler.types.Type; +import org.simantics.simulator.variable.Realm; +import org.simantics.simulator.variable.exceptions.NodeManagerException; +import org.simantics.simulator.variable.exceptions.NotInRealmException; +import org.simantics.simulator.variable.impl.AbstractNodeManager; +import org.simantics.structural.stubs.StructuralResource2; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + +public class SCLNodeManager extends AbstractNodeManager { + + public static final String ROOT = "@"; + + SCLRealm realm; + THashMap valueCache = new THashMap(); + THashMap> listeners = new THashMap>(); + + AtomicBoolean fireNodeListenersScheduled = new AtomicBoolean(false); + Runnable fireNodeListeners = new Runnable() { + @Override + public void run() { + fireNodeListenersScheduled.set(false); + final TObjectProcedure procedure = new TObjectProcedure() { + @Override + public boolean execute(Runnable object) { + object.run(); + return true; + } + }; + synchronized(listeners) { + listeners.forEachValue(new TObjectProcedure>() { + @Override + public boolean execute(THashSet object) { + object.forEach(procedure); + return true; + } + }); + } + } + }; + + Runnable clearValueCache = new Runnable() { + @Override + public void run() { + valueCache.clear(); + } + }; + + public SCLNodeManager(SCLRealm realm) { + super(); + this.realm = realm; + } + + @Override + public Realm getRealm() { + return realm; + } + + public String getRoot() { + return ROOT; + } + + @Override + public String getName(String node) { + if(ROOT.equals(node)) { + String id = realm.getId(); + int lastSlash = id.lastIndexOf("/"); + if(lastSlash == -1) throw new IllegalStateException("Invalid realm id " + id); + String name = id.substring(lastSlash+1); + return name; + } else + return node; + } + + @Override + public void addNodeListener(String node, Runnable listener) { + synchronized(listeners) { + THashSet l = listeners.get(node); + if(l == null) { + l = new THashSet(); + listeners.put(node, l); + } + l.add(listener); + } + realm.asyncExec(listener); + } + + @Override + public void removeNodeListener(String node, Runnable listener) { + synchronized(listeners) { + THashSet l = listeners.get(node); + if(l != null) { + l.remove(listener); + if(l.isEmpty()) + listeners.remove(node); + } + } + } + + public void fireNodeListeners() { + if(!fireNodeListenersScheduled.getAndSet(true)) + realm.asyncExec(fireNodeListeners); + } + + public void fireNodeListenersSync() { + try { + realm.syncExec(fireNodeListeners); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void refreshVariables() { + realm.asyncExec(clearValueCache); + fireNodeListeners(); + } + + public void refreshVariablesSync() { + try { + realm.syncExec(clearValueCache); + } catch (InterruptedException e) { + e.printStackTrace(); + } + fireNodeListenersSync(); + } + + @Override + public String getNode(String path) throws NodeManagerException { + checkThreadAccess(); + throw new UnsupportedOperationException(); + } + + @Override + public String getChild(String node, String name) + throws NodeManagerException { + checkThreadAccess(); + return null; + } + + @Override + public String getProperty(String node, String name) + throws NodeManagerException { + checkThreadAccess(); + if(node.equals(ROOT)) + return name; + else + return null; + } + + @Override + public List getChildren(String node) throws NodeManagerException { + checkThreadAccess(); + return Collections.emptyList(); + } + + @Override + public List getProperties(String node) throws NodeManagerException { + checkThreadAccess(); + if(!node.equals(ROOT)) + return Collections.emptyList(); + + Set variables = realm.getConnection().getVariables(); + return new ArrayList(variables); + + } + + @Override + public Datatype getDatatype(String node) throws NodeManagerException { + checkThreadAccess(); + try { + Datatype type = getDatatypeForValue(getSCLValue(node)); + return type; + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public Object getValue(String node, Binding binding) throws NodeManagerException { + checkThreadAccess(); + return getSCLValue(node); + } + + + private Type getType(String name) { + return realm.getConnection().getVariableType(name); + } + + private Datatype getDatatypeForValue(Object value) throws DatabaseException { + if(value instanceof Double) return Datatypes.DOUBLE; + if(value instanceof Float) return Datatypes.FLOAT; + if(value instanceof Integer) return Datatypes.INTEGER; + if(value instanceof Long) return Datatypes.LONG; + if(value instanceof String) return Datatypes.STRING; + if(value instanceof Boolean) return Datatypes.BOOLEAN; + + if (value instanceof List) return null; + + if (value instanceof Object) return null; + + if (value == null) return null; + + else throw new DatabaseException("No Datatype for value " + value); + } + + @Override + public void setValue(String node, Object value, Binding binding) + throws NodeManagerException { + checkThreadAccess(); + valueCache.put(node, value); + realm.getConnection().setVariable(node, getType(node), value); + realm.getNodeManager().valueCache.put(node, value); + refreshVariables(); + } + + public void setValue(String node, Type type, Object value) + throws NodeManagerException { + + checkThreadAccess(); + valueCache.put(node, value); + realm.getConnection().setVariable(node, type, value); + + NodeSupport support = SCLSessionManager.getOrCreateNodeSupport(realm.getId()); + support.structureCache.put(ROOT, null); + support.valueCache.put(node, null); + + realm.getNodeManager().valueCache.put(node, value); + realm.getNodeManager(). + refreshVariables(); + } + + static final Set COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component); + + @Override + public Set getClassifications(String node) throws NodeManagerException { + checkThreadAccess(); + if(node.equals(ROOT)) + return COMPONENT_CLASS; + else + return Collections.emptySet(); + } + + private Object getSCLValue(String node) throws NodeManagerException { + Object value = valueCache.get(node); + if(value == null) { + value = realm.getConnection().getVariableValue(node); + valueCache.put(node, value); + } + return value; + } + + private void checkThreadAccess() throws NodeManagerException { + if(Thread.currentThread() != realm.getThread()) + throw new NotInRealmException(); + } + + @Override + public String getPropertyURI(String parent, String property) { + return ModelingResources.URIs.SCLCommandSession_hasValue; + } + + public void clear() { + valueCache.clear(); + listeners.clear(); + } +}