/* --------------------------------------------------------- *
* __________ 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);
}
}