]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLRealm.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / SCLRealm.java
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLRealm.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLRealm.java
new file mode 100644 (file)
index 0000000..99ac161
--- /dev/null
@@ -0,0 +1,221 @@
+package org.simantics.modeling.scl;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+import java.io.IOException;\r
+import java.util.Map;\r
+import java.util.concurrent.ExecutorService;\r
+import java.util.concurrent.LinkedBlockingQueue;\r
+import java.util.concurrent.Semaphore;\r
+import java.util.concurrent.ThreadFactory;\r
+import java.util.concurrent.ThreadPoolExecutor;\r
+import java.util.concurrent.TimeUnit;\r
+\r
+import org.simantics.Logger;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;\r
+import org.simantics.modeling.SCLTypeUtils;\r
+import org.simantics.scl.compiler.commands.CommandSession;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.runtime.SCLContext;\r
+import org.simantics.scl.runtime.function.Function;\r
+import org.simantics.scl.runtime.tuple.Tuple0;\r
+import org.simantics.simulator.variable.NodeManager;\r
+import org.simantics.simulator.variable.Realm;\r
+\r
+public class SCLRealm implements Realm {\r
+    public static final String SCL = "scl";\r
+    \r
+    THashMap<String,Type> contextTypes = new THashMap<String,Type>();\r
+    \r
+    CommandSession connection;\r
+    String id;\r
+    Thread executorThread;\r
+    ExecutorService executor = new ThreadPoolExecutor(0, 1, 60, TimeUnit.SECONDS,\r
+            new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {\r
+        @Override\r
+        public Thread newThread(Runnable r) {\r
+            executorThread = new Thread(r);\r
+            return executorThread;\r
+        }\r
+    });\r
+    \r
+    Semaphore beginSyncExec = new Semaphore(0);\r
+    Semaphore endSyncExec = new Semaphore(0);\r
+    \r
+    SCLNodeManager nodeManager;\r
+    \r
+    Runnable scheduleSyncExec = new Runnable() {\r
+        @Override\r
+        public void run() {\r
+            beginSyncExec.release();\r
+            try {\r
+                endSyncExec.acquire();\r
+            } catch (InterruptedException e) {\r
+            }\r
+        }\r
+    };\r
+    \r
+    SCLRealm(CommandSession connection, String id) {\r
+        this.connection = connection;\r
+        this.id = id;\r
+        this.nodeManager = new SCLNodeManager(this);\r
+    }\r
+\r
+    public String getId() {\r
+        return id;\r
+    }\r
+    \r
+    public CommandSession getConnection() {\r
+        return connection;\r
+    }\r
+    \r
+    public Thread getThread() {\r
+        return executorThread;\r
+    }\r
+    \r
+    @SuppressWarnings({ "rawtypes", "unchecked" })\r
+    public Object syncExec(Function fun) throws InterruptedException {\r
+        executor.execute(scheduleSyncExec);\r
+        \r
+        SCLContext context = SCLContext.getCurrent();\r
+        CommandSession oldConnection = (CommandSession)context.put(SCL, connection);\r
+        \r
+        try {\r
+            beginSyncExec.acquire();\r
+            Thread oldThread = executorThread;\r
+            executorThread = Thread.currentThread();\r
+            try {\r
+                return fun.apply(Tuple0.INSTANCE);\r
+            } finally {\r
+                executorThread = oldThread;\r
+                endSyncExec.release();\r
+            }\r
+        } finally {\r
+            context.put(SCL, oldConnection);\r
+        }\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    public void asyncExec(final Function fun) {\r
+        executor.execute(new Runnable() {\r
+            @SuppressWarnings("unchecked")\r
+            @Override\r
+            public void run() {\r
+                SCLContext context = SCLContext.getCurrent();\r
+                context.put(SCL, connection);\r
+                fun.apply(Tuple0.INSTANCE);\r
+            }\r
+        });\r
+    }\r
+\r
+    @Override\r
+    public void syncExec(Runnable runnable) throws InterruptedException {\r
+       \r
+        if(executorThread == Thread.currentThread()) {\r
+            try {\r
+                runnable.run();\r
+            } catch (Throwable t) {\r
+               Logger.defaultLogError(t);\r
+            } finally {\r
+            }\r
+            return;\r
+        }\r
+\r
+       executor.execute(scheduleSyncExec);\r
+        \r
+        beginSyncExec.acquire();\r
+        Thread oldThread = executorThread;\r
+        executorThread = Thread.currentThread();\r
+        try {\r
+            runnable.run();\r
+        } catch (Throwable t) {\r
+               Logger.defaultLogError(t);\r
+        } finally {\r
+            executorThread = oldThread;\r
+            endSyncExec.release();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void asyncExec(Runnable runnable) {\r
+\r
+       if(executorThread == Thread.currentThread()) {\r
+            try {\r
+                runnable.run();\r
+            } catch (Throwable t) {\r
+               Logger.defaultLogError(t);\r
+            } finally {\r
+            }\r
+            return;\r
+        }\r
+       \r
+        executor.execute(runnable);\r
+    }\r
+    \r
+    public void refreshVariables() {\r
+        nodeManager.refreshVariables();\r
+    }\r
+    \r
+    public void refreshVariablesSync() {\r
+        nodeManager.refreshVariablesSync();\r
+    }\r
+\r
+    public void close() {\r
+        SCLSessionManager.CONNECTIONS.remove(id);\r
+        executor.shutdown();\r
+        try {\r
+            executor.awaitTermination(500L, TimeUnit.MILLISECONDS);\r
+        } catch (InterruptedException e) {\r
+        }\r
+        //connection.close();\r
+    }\r
+\r
+    public NodeManager<String> getNodeManager() {\r
+        return nodeManager;\r
+    }\r
+    \r
+    private SCLState getState() {\r
+       SCLState state = new SCLState();\r
+       for(String key : connection.getVariables()) {\r
+               Object value = connection.getVariableValue(key);\r
+               try {\r
+                       Binding b = Bindings.getBinding(value.getClass());\r
+                       state.values.put(key, new Variant(b, value));\r
+               } catch (Exception e) {\r
+               }\r
+       }\r
+       return state;\r
+    }\r
+    \r
+    public void applyState(byte[] blob) {\r
+       try {\r
+                       SCLState state = (SCLState)SCLState.BINDING.serializer().deserialize(blob);\r
+               for(Map.Entry<String,Variant> entry : state.values.entrySet()) {\r
+                       String key = entry.getKey();\r
+                       Variant value = entry.getValue();\r
+                       Type type = SCLTypeUtils.getType(value.type());\r
+                       if (type.getClassId() != Type.VAR_ID) {\r
+                           // do not add the property if type cannot be inferred\r
+                           connection.setVariable(key, type, value.getValue());\r
+                       }\r
+               }\r
+               } catch (RuntimeSerializerConstructionException e) {\r
+               } catch (IOException e) {\r
+               }\r
+    }\r
+    \r
+    public byte[] serialize() {\r
+       SCLState state = getState();\r
+       try {\r
+                       return SCLState.BINDING.serializer().serialize(state);\r
+               } catch (RuntimeSerializerConstructionException e) {\r
+                       return null;\r
+               } catch (IOException e) {\r
+                       return null;\r
+               }\r
+    }\r
+    \r
+}\r