1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.gltrace.state.transforms; 18 19 import com.android.ide.eclipse.gltrace.state.IGLProperty; 20 21 /** 22 * A PropertyChangeTransform object provides the ability to alter the value of a 23 * single GL State variable. An optional predicate provides the ability to perform 24 * the change only if the predicate succeeds. 25 */ 26 public class PropertyChangeTransform implements IStateTransform { 27 private final IGLPropertyAccessor mAccessor; 28 private final Object mNewValue; 29 private final IPredicate mPredicate; 30 private Object mOldValue; 31 32 /** 33 * Construct a state transform that will extract the property using the accessor, 34 * and modify its value to the provided value. 35 */ 36 PropertyChangeTransform(IGLPropertyAccessor accessor, Object newValue) { 37 this(accessor, newValue, null); 38 } 39 40 /** 41 * Construct a state transform that will extract the property using the accessor, 42 * check if the predicate function accepts the current value, and if so modify its 43 * value to the provided value. 44 */ 45 public PropertyChangeTransform(IGLPropertyAccessor accessor, Object newValue, 46 IPredicate predicate) { 47 mAccessor = accessor; 48 mNewValue = newValue; 49 mPredicate = predicate; 50 mOldValue = null; 51 } 52 53 /** Apply the state transformation on the given OpenGL state. */ 54 @Override 55 public void apply(IGLProperty state) { 56 IGLProperty property = mAccessor.getProperty(state); 57 58 assert mOldValue == null : "Transform cannot be applied multiple times"; 59 if (mPredicate != null) { 60 // if predicate is not null, then first check if the current value 61 // passes the predicate function. 62 if (!mPredicate.apply(property.getValue())) { 63 return; 64 } 65 } 66 67 if (property != null) { 68 mOldValue = property.getValue(); 69 property.setValue(mNewValue); 70 } else { 71 throw new RuntimeException("No such property: " + mAccessor.getPath()); 72 } 73 } 74 75 /** 76 * Reverses the effect of this state transform. It restores the property's value to the same 77 * state as it was before this transformation was applied. If this transform was never 78 * {@link #apply(IGLProperty)}'ed, then performing a revert has no effect. 79 */ 80 @Override 81 public void revert(IGLProperty state) { 82 if (mOldValue != null) { 83 IGLProperty property = mAccessor.getProperty(state); 84 property.setValue(mOldValue); 85 mOldValue = null; 86 } 87 } 88 89 /** Gets the property that will be affected by applying this transformation. */ 90 @Override 91 public IGLProperty getChangedProperty(IGLProperty state) { 92 if (mPredicate != null) { 93 Object value = mOldValue == null ? mNewValue : mOldValue; 94 if (!mPredicate.apply(value)) { 95 // if the value doesn't match the predicate, then this property 96 // is not altered. 97 return null; 98 } 99 } 100 101 return mAccessor.getProperty(state); 102 } 103 } 104