package org.simantics.scenegraph.loader; import java.util.Set; import org.simantics.Simantics; import org.simantics.db.Disposable; import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.common.primitiverequest.PossibleResource; import org.simantics.db.common.procedure.adapter.ListenerSupport; import org.simantics.db.common.request.TernaryRead; import org.simantics.db.common.request.UnaryRead; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.ResourceVariable; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.VariableRepository; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.ParentNode; import org.simantics.utils.datastructures.Pair; import gnu.trove.set.hash.THashSet; public class ScenegraphLoaderProcess implements Disposable, ListenerSupport { final private String name; final Class loaderClass; protected INode root; private boolean disposed = false; final protected Set registeredURIs = new THashSet(); public ScenegraphLoaderProcess(String name) { this(null, ScenegraphLoader.class, name); } public ScenegraphLoaderProcess(INode root, String name) { this(root, ScenegraphLoader.class, name); } public ScenegraphLoaderProcess(INode root, Class loaderClass, String name) { this.root = root; this.loaderClass = loaderClass; this.name = name; //System.out.println("NEW ScenegraphLoaderProcess(" + name + "): " + this); //new Exception("NEW ScenegraphLoaderProcess(" + name + "): " + this).printStackTrace(); } public INode getRoot() { return root; } @Override public String toString() { return name; } protected void initialize(RequestProcessor processor, Variable configuration) throws DatabaseException { } final public > N load(final String curi, final Resource runtime) throws DatabaseException { return load(Simantics.getSession(), curi, runtime); } final public > N load(RequestProcessor processor, final String curi, final Resource runtime) throws DatabaseException { Resource resource = processor.sync(new PossibleResource(curi)); if(resource == null) throw new IllegalArgumentException("The given URI is invalid: " + curi); return load(processor, resource, runtime); } final public > N load(Resource configuration, Resource runtime) throws DatabaseException { return load(Simantics.getSession(), configuration, runtime); } final public > N load(RequestProcessor processor, Resource configuration, Resource runtime) throws DatabaseException { N root = (N)getRoot(); return load(processor, getVariable(processor, this, configuration, runtime, root)); } final public Variable getVariable(RequestProcessor processor, String curi, Resource runtime) throws DatabaseException { Resource resource = processor.sync(new PossibleResource(curi)); if(resource == null) throw new IllegalArgumentException("The given URI is invalid: " + curi); return getVariable(processor, this, resource, runtime, root); } final static public Variable getVariable(RequestProcessor processor, final ScenegraphLoaderProcess process, final Resource configuration, final Resource runtime, final INode root) throws DatabaseException { assert(root != null); Pair result = processor.sync(new TernaryRead>(root, runtime, configuration) { @Override public Pair perform(ReadGraph graph) throws DatabaseException { Variable conf = graph.sync(new ResourceVariable(parameter3)); Variable result = new ScenegraphVariable(conf, parameter3, parameter2, parameter); return Pair.make(result, result.getURI(graph)); } }); VariableRepository.register(result.second, result.first); if(process != null) process.registeredURIs.add(result.second); return result.first; } final public > N load(RequestProcessor processor, final Variable configuration) throws DatabaseException { initialize(processor, configuration); N root = (N)getRoot(); load(processor, configuration, root); return root; } Class getLoaderClass() { return (Class)ScenegraphLoader.class; } protected ScenegraphLoader getLoader(RequestProcessor processor, Variable configuration) throws DatabaseException { return processor.sync(new UnaryRead(configuration) { @Override public ScenegraphLoader perform(ReadGraph graph) throws DatabaseException { return parameter.adapt(graph, getLoaderClass()); } }); } @SuppressWarnings("unchecked") final private INode load(RequestProcessor processor, Variable configuration, ParentNode current) throws DatabaseException { ScenegraphLoader loader = getLoader(processor, configuration); INode node = loader.create(processor, this, current, configuration); if(node instanceof ParentNode) { for(Variable child : ScenegraphLoaderUtils.getChildren(processor, configuration)) { load(processor, child, (ParentNode)node); } } return node; } @Override public void exception(Throwable t) { Logger.defaultLogError(t); } @Override public boolean isDisposed() { return disposed; } @Override public void dispose() { //System.out.println("DISPOSE ScenegraphLoaderProcess(" + name + "): " + this); //new Exception("DISPOSED ScenegraphLoaderProcess(" + name + "): " + this).printStackTrace(); disposed = true; } }