/* --------------------------------------------------------- * * __________ D E L T A S C R I P T * * (_________() * * / === / - A fast, dynamic scripting language * * | == | - Version 4.13.11.0 * * / === / - Developed by Adam R. Nelson * * | = = | - 2011-2013 * * / === / - Distributed under GNU LGPL v3 * * (________() - http://github.com/ar-nelson/deltascript * * * * --------------------------------------------------------- */ package com.sector91.delta.script; import java.io.File; import java.util.EnumSet; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Random; import com.sector91.delta.script.module.ModuleLoader; import com.sector91.delta.script.objects.DS_Object; import com.sector91.delta.script.objects.DS_RootScope; import com.sector91.delta.script.objects.DS_Scope; import com.sector91.delta.script.objects.DS_Tag; import com.sector91.delta.script.objects.geom.DeltaScriptGeometry; public class DScriptContext implements Cloneable { public static final File DEFAULT_CWD = new File(".").getAbsoluteFile(); public static final int DEFAULT_INT_TYPE = NumberTypes.LONG_INT; public static final int DEFAULT_FLOAT_TYPE = NumberTypes.SHORT_FLOAT; public static final Random DEFAULT_RANDOM = new Random(); private final DS_RootScope rootScope; private int defaultIntType = DEFAULT_INT_TYPE; private int defaultFloatType = DEFAULT_FLOAT_TYPE; private File currentWorkingDirectory = DEFAULT_CWD; private final EnumSet<Permission> permissions = EnumSet.of( Permission.LOAD_SCRIPT_FILES, Permission.LOAD_RESOURCES, Permission.LOAD_MODULES, Permission.WRITE_CONSOLE, Permission.READ_CONSOLE); private final Map<Class<?>, Converter<?, ?>> conversions = new HashMap<Class<?>, Converter<?, ?>>(); private Random random; private DeltaScriptGeometry geom; private ModuleLoader moduleLoader; private static final ThreadLocal<LinkedList<DScriptContext>> contextStack = new ThreadLocal<LinkedList<DScriptContext>>() { @Override protected LinkedList<DScriptContext> initialValue() {return new LinkedList<DScriptContext>();} }; public static DScriptContext get() {return contextStack.get().peek();} public static DScriptContext pop() {return contextStack.get().pop();} public static Random getContextRandom() { final DScriptContext context = contextStack.get().peek(); if (context == null) return DEFAULT_RANDOM; else return context.getRandom(); } public static DeltaScriptGeometry getContextGeometry() { final DScriptContext context = contextStack.get().peek(); if (context == null) return DeltaScriptGeometry.GEOM; else return context.getGeometry(); } public static void push(DScriptContext newContext) {contextStack.get().push(newContext);} public DScriptContext() { rootScope = new DS_RootScope(); rootScope.setContext(this); random = DEFAULT_RANDOM; geom = DeltaScriptGeometry.GEOM; } private DScriptContext(DS_RootScope rootScope, int intType, int floatType, File cwd, ModuleLoader loader, Random random, DeltaScriptGeometry geom, Map<Class<?>, Converter<?, ?>> conversions, EnumSet<Permission> permissions) { this.rootScope = rootScope.clone(); this.rootScope.setContext(this); this.defaultIntType = intType; this.defaultFloatType = floatType; this.currentWorkingDirectory = cwd; this.moduleLoader = loader; this.random = random; this.geom = geom; this.conversions.putAll(conversions); this.permissions.clear(); this.permissions.addAll(permissions); } public int getDefaultIntType() {return defaultIntType;} public void setDefaultIntType(int defaultIntType) { if (defaultIntType != NumberTypes.SHORT_INT && defaultIntType != NumberTypes.LONG_INT && defaultIntType != NumberTypes.REAL_INT) throw new IllegalArgumentException(defaultIntType + " is not a valid int type."); this.defaultIntType = defaultIntType; } public int getDefaultFloatType() {return defaultFloatType;} public void setDefaultFloatType(int defaultFloatType) { if (defaultFloatType != NumberTypes.SHORT_FLOAT && defaultFloatType != NumberTypes.LONG_FLOAT && defaultFloatType != NumberTypes.REAL_DECIMAL) throw new IllegalArgumentException(defaultFloatType + " is not a valid float type."); this.defaultFloatType = defaultFloatType; } public ModuleLoader getModuleLoader() {return moduleLoader;} public void setModuleLoader(ModuleLoader moduleLoader) {this.moduleLoader = moduleLoader;} public DeltaScriptGeometry getGeometry() {return geom;} public void setGeometry(DeltaScriptGeometry geom) {this.geom = geom;} public Random getRandom() {return random;} public void setRandom(Random random) {this.random = random;} public File getCurrentWorkingDirectory() {return currentWorkingDirectory;} public void setCurrentWorkingDirectory(File currentWorkingDirectory) {this.currentWorkingDirectory = currentWorkingDirectory;} public DS_RootScope getRootScope() {return rootScope;} public void addGlobalBinding(DS_Tag tag, DS_Object value) throws DScriptErr {rootScope.addGlobalBinding(tag, value);} public DS_Scope createScope() {return rootScope.createSubscope();} public DS_Scope createScope(int expectedSize) {return rootScope.createSubscope(expectedSize);} public boolean isPermitted(Permission p) {return permissions.contains(p);} public void permit(Permission p) {permissions.add(p);} public void deny(Permission p) {permissions.remove(p);} public <T> void addConversion(Class<T> classToConvert, Converter<T, ?> converter) {conversions.put(classToConvert, converter);} public void removeConversion(Class<?> classToConvert) {conversions.remove(classToConvert);} Map<Class<?>, Converter<?, ?>> getConversions() {return conversions;} @Override protected DScriptContext clone() { return new DScriptContext(rootScope, defaultIntType, defaultFloatType, currentWorkingDirectory, moduleLoader, random, geom, conversions, permissions); } }