package org.simantics.pythonlink; import java.util.List; import java.util.concurrent.TimeUnit; import org.simantics.db.layer0.variable.NodeSupport; import org.simantics.db.layer0.variable.StandardGraphChildVariable; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.VariableNode; import org.simantics.pythonlink.PythonContext.Listener; import org.simantics.pythonlink.variable.PythonNode; import org.simantics.pythonlink.variable.PythonNodeManager; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function; import org.simantics.scl.runtime.tuple.Tuple0; import org.simantics.simulator.variable.NodeManager; import org.simantics.simulator.variable.exceptions.NodeManagerException; public class Python { private static final String PYTHON_CONTEXT = "Simantics/Python/Python"; public static PythonContext openPythonContext() { return new PythonContext(); } public static Variable getPythonContextVariable(PythonContext context) { NodeManager nodeManager = new PythonNodeManager(context); PythonNode root; try { root = nodeManager.getNode("/"); } catch (NodeManagerException e) { // Should not happen throw new RuntimeException("Getting root Python node failed"); } final NodeSupport support = new NodeSupport(nodeManager, 0, TimeUnit.NANOSECONDS); context.addListener(new Listener() { @Override public void updated(String variableName) { try { PythonNode root = nodeManager.getNode("/"); if (variableName != null) { PythonNode node = nodeManager.getNode(variableName); if (node != null) support.valueCache.removeListening(node); support.structureCache.removeListening(root); } else { List props = nodeManager.getProperties(root); for (PythonNode p : props) support.valueCache.removeListening(p); support.structureCache.removeListening(root); } support.valueCache.clearExpired(); support.structureCache.clearExpired(); } catch (NodeManagerException e) { e.printStackTrace(); } } @Override public void closed() { } }); return new StandardGraphChildVariable(null, new VariableNode(support, root), null); } @SuppressWarnings( { "unchecked", "rawtypes" } ) public static Object runPythonF(Function f) { SCLContext sclContext = SCLContext.getCurrent(); Object oldContext = sclContext.get(PYTHON_CONTEXT); try (PythonContext newContext = openPythonContext()) { sclContext.put(PYTHON_CONTEXT, newContext); return f.apply(Tuple0.INSTANCE); } finally { sclContext.put(PYTHON_CONTEXT, oldContext); } } @SuppressWarnings( { "unchecked", "rawtypes" } ) public static Object runWithPythonContextF(PythonContext context, Function f) { SCLContext sclContext = SCLContext.getCurrent(); Object oldContext = sclContext.get(PYTHON_CONTEXT); try { sclContext.put(PYTHON_CONTEXT, context); return f.apply(Tuple0.INSTANCE); } finally { sclContext.put(PYTHON_CONTEXT, oldContext); } } }