/** * Sets a binding for a special dynamic variable in this Environment. This is not for end-users, * and will throw an AssertionError in case of conflict. * * @param varname the name of the dynamic variable to be bound * @param value a value to bind to the variable * @return this Environment, in fluid style */ public Environment setupDynamic(String varname, Object value) { if (dynamicFrame.get(varname) != null) { throw new AssertionError( String.format("Trying to bind dynamic variable '%s' but it is already bound", varname)); } if (lexicalFrame != null && lexicalFrame.get(varname) != null) { throw new AssertionError( String.format( "Trying to bind dynamic variable '%s' but it is already bound lexically", varname)); } if (globalFrame.get(varname) != null) { throw new AssertionError( String.format( "Trying to bind dynamic variable '%s' but it is already bound globally", varname)); } try { dynamicFrame.put(this, varname, value); } catch (MutabilityException e) { // End users don't have access to setupDynamic, and it is an implementation error // if we encounter a mutability exception. throw new AssertionError( Printer.format( "Trying to bind dynamic variable '%s' in frozen environment %r", varname, this), e); } return this; }
/** * Gets a binding from the current frame or if not found its parent. * * @param varname the name of the variable to be bound * @return the value bound to variable */ public Object get(String varname) { if (bindings.containsKey(varname)) { return bindings.get(varname); } if (parent != null) { return parent.get(varname); } return null; }
protected boolean sameForm(RBTerm other, Frame lr, Frame rl) { if (!(other.getClass() == this.getClass())) return false; else { RBVariable binding = (RBVariable) lr.get(this); if (binding == null) { lr.put(this, other); } else if (!binding.equals(other)) { return false; } binding = (RBVariable) rl.get(other); if (binding == null) { rl.put(other, this); return true; } else { return this.equals(binding); } } }
/** * @return the value from the environment whose name is "varname". * @throws NoSuchVariableException if the variable is not defined in the Environment. */ public Object lookup(String varname) throws NoSuchVariableException { // Which Frame to lookup first doesn't matter because update prevents clashes. if (lexicalFrame != null) { Object lexicalValue = lexicalFrame.get(varname); if (lexicalValue != null) { return lexicalValue; } } Object globalValue = globalFrame.get(varname); Object dynamicValue = dynamicFrame.get(varname); if (globalValue == null && dynamicValue == null) { throw new NoSuchVariableException(varname); } if (knownGlobalVariables != null) { knownGlobalVariables.add(varname); } if (globalValue != null) { return globalValue; } return dynamicValue; }
public Frame unify(RBTerm other, Frame f) { // System.err.println("** entering unify " + this + " to: " + other); if (other instanceof RBIgnoredVariable) return f; RBTerm val = f.get(this); if (val == null) { other = other.substitute(f); if (equals(other)) return f; else if (other.freefor(this)) { return bind(other, f); } else return null; } else return val.unify(other, f); }
/** * Modifies a binding in the current Frame of this Environment, as would an {@link * AssignmentStatement}. Does not try to modify an inherited binding. This will shadow any * inherited binding, which may be an error that you want to guard against before calling this * function. * * @param varname the name of the variable to be bound * @param value the value to bind to the variable * @return this Environment, in fluid style */ public Environment update(String varname, Object value) throws EvalException { Preconditions.checkNotNull(value, "update(value == null)"); // prevents clashes between static and dynamic variables. if (dynamicFrame.get(varname) != null) { throw new EvalException( null, String.format("Trying to update special read-only global variable '%s'", varname)); } if (isKnownGlobalVariable(varname)) { throw new EvalException( null, String.format("Trying to update read-only global variable '%s'", varname)); } try { currentFrame().put(this, varname, Preconditions.checkNotNull(value)); } catch (MutabilityException e) { // Note that since at this time we don't accept the global keyword, and don't have closures, // end users should never be able to mutate a frozen Environment, and a MutabilityException // is therefore a failed assertion for Bazel. However, it is possible to shadow a binding // imported from a parent Environment by updating the current Environment, which will not // trigger a MutabilityException. throw new AssertionError( Printer.format("Can't update %s to %r in frozen environment", varname, value), e); } return this; }
/** Intenal use. Call {@link #checkValidity()} and if path is not valid recomputes it. */ protected void updatePath() { checkValidity(); if (!pathIsValid) { path.clear(); int nbSteps = 30; if (keyFrameList.isEmpty()) return; if (!valuesAreValid) updateModifiedFrameValues(); if (keyFrameList.get(0) == keyFrameList.get(keyFrameList.size() - 1)) // TODO experimenting really path.add( new Frame( keyFrameList.get(0).position(), keyFrameList.get(0).orientation(), keyFrameList.get(0).magnitude())); else { KeyFrame[] kf = new KeyFrame[4]; kf[0] = keyFrameList.get(0); kf[1] = kf[0]; int index = 1; kf[2] = (index < keyFrameList.size()) ? keyFrameList.get(index) : null; index++; kf[3] = (index < keyFrameList.size()) ? keyFrameList.get(index) : null; while (kf[2] != null) { Vec pdiff = Vec.subtract(kf[2].position(), kf[1].position()); Vec pvec1 = Vec.add(Vec.multiply(pdiff, 3.0f), Vec.multiply(kf[1].tgP(), (-2.0f))); pvec1 = Vec.subtract(pvec1, kf[2].tgP()); Vec pvec2 = Vec.add(Vec.multiply(pdiff, (-2.0f)), kf[1].tgP()); pvec2 = Vec.add(pvec2, kf[2].tgP()); for (int step = 0; step < nbSteps; ++step) { Frame frame = new Frame(); float alpha = step / (float) nbSteps; frame.setPosition( Vec.add( kf[1].position(), Vec.multiply( Vec.add( kf[1].tgP(), Vec.multiply(Vec.add(pvec1, Vec.multiply(pvec2, alpha)), alpha)), alpha))); if (gScene.is3D()) { frame.setOrientation( Quat.squad( (Quat) kf[1].orientation(), ((KeyFrame3D) kf[1]).tgQ(), ((KeyFrame3D) kf[2]).tgQ(), (Quat) kf[2].orientation(), alpha)); } else { // linear interpolation float start = kf[1].orientation().angle(); float stop = kf[2].orientation().angle(); frame.setOrientation(new Rot(start + (stop - start) * alpha)); } frame.setMagnitude(Util.lerp(kf[1].magnitude(), kf[2].magnitude(), alpha)); path.add(frame.get()); } // Shift kf[0] = kf[1]; kf[1] = kf[2]; kf[2] = kf[3]; index++; kf[3] = (index < keyFrameList.size()) ? keyFrameList.get(index) : null; } // Add last KeyFrame path.add(new Frame(kf[1].position(), kf[1].orientation(), kf[1].magnitude())); } pathIsValid = true; } }