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