blob: 276f6f49bf648db7615b54c854d0451e924fb10e [file] [log] [blame]
/*
* 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);
}
}