/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.ide.eclipse.gltrace.state.transforms; import com.android.ide.eclipse.gltrace.state.IGLProperty; /** * A PropertyChangeTransform object provides the ability to alter the value of a * single GL State variable. An optional predicate provides the ability to perform * the change only if the predicate succeeds. */ public class PropertyChangeTransform implements IStateTransform { private final IGLPropertyAccessor mAccessor; private final Object mNewValue; private final IPredicate mPredicate; private Object mOldValue; /** * Construct a state transform that will extract the property using the accessor, * and modify its value to the provided value. */ PropertyChangeTransform(IGLPropertyAccessor accessor, Object newValue) { this(accessor, newValue, null); } /** * Construct a state transform that will extract the property using the accessor, * check if the predicate function accepts the current value, and if so modify its * value to the provided value. */ public PropertyChangeTransform(IGLPropertyAccessor accessor, Object newValue, IPredicate predicate) { mAccessor = accessor; mNewValue = newValue; mPredicate = predicate; mOldValue = null; } /** Apply the state transformation on the given OpenGL state. */ @Override public void apply(IGLProperty state) { IGLProperty property = mAccessor.getProperty(state); assert mOldValue == null : "Transform cannot be applied multiple times"; if (mPredicate != null) { // if predicate is not null, then first check if the current value // passes the predicate function. if (!mPredicate.apply(property.getValue())) { return; } } if (property != null) { mOldValue = property.getValue(); property.setValue(mNewValue); } else { throw new RuntimeException("No such property: " + mAccessor.getPath()); } } /** * Reverses the effect of this state transform. It restores the property's value to the same * state as it was before this transformation was applied. If this transform was never * {@link #apply(IGLProperty)}'ed, then performing a revert has no effect. */ @Override public void revert(IGLProperty state) { if (mOldValue != null) { IGLProperty property = mAccessor.getProperty(state); property.setValue(mOldValue); mOldValue = null; } } /** Gets the property that will be affected by applying this transformation. */ @Override public IGLProperty getChangedProperty(IGLProperty state) { if (mPredicate != null) { Object value = mOldValue == null ? mNewValue : mOldValue; if (!mPredicate.apply(value)) { // if the value doesn't match the predicate, then this property // is not altered. return null; } } return mAccessor.getProperty(state); } }