package org.simantics.scl.runtime; import org.simantics.scl.runtime.reporting.SCLReportingHandler; import gnu.trove.map.hash.THashMap; public class SCLContext extends THashMap { private static ThreadLocal CONTEXT = new ThreadLocal(); private static ThreadLocal OLD_CONTEXT = new ThreadLocal(); private static class OldContextNode { final SCLContext context; final OldContextNode next; public OldContextNode(SCLContext context, OldContextNode next) { this.context = context; this.next = next; } } public static SCLContext getCurrent() { SCLContext context = CONTEXT.get(); if(context == null) { context = new SCLContext(); CONTEXT.set(context); } return context; } public static void push(SCLContext newContext) { SCLContext oldContext = CONTEXT.get(); if(oldContext != null) OLD_CONTEXT.set(new OldContextNode(oldContext, OLD_CONTEXT.get())); CONTEXT.set(newContext); } /** * Creates a new context based on some properties of the current context. * The new context is safe for use in parallel threads. */ public static SCLContext createDerivedContext() { SCLContext newContext = new SCLContext(); SCLContext baseContext = CONTEXT.get(); if(baseContext != null) { Object reportingHandler = baseContext.get(SCLReportingHandler.REPORTING_HANDLER); if(reportingHandler != null) newContext.put(SCLReportingHandler.REPORTING_HANDLER, reportingHandler); } return newContext; } public static void pop() { OldContextNode node = OLD_CONTEXT.get(); if(node == null) CONTEXT.set(null); else { CONTEXT.set(node.context); OLD_CONTEXT.set(node.next); } } /* @Override public Object get(Object key) { Object result = super.get(key); System.out.println(this + ": " + key + " -> " + result); return result; } @Override public Object put(String key, Object value) { System.out.println(this + ": " + key + " <- " + value); return super.put(key, value); }*/ }