/*
* Copyright 2003-2014 JetBrains s.r.o.
*
* 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 jetbrains.mps.extapi.persistence;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.persistence.DataSource;
import org.jetbrains.mps.openapi.persistence.DataSourceListener;
/**
* Trivial {@link org.jetbrains.mps.openapi.persistence.DataSourceListener} implementation that tracks
* source's timestamp and triggers model reload
* @author Artem Tikhomirov
*/
public class ModelSourceChangeTracker implements DataSourceListener {
protected final ReloadCallback myCallback;
private long mySourceTimestamp = -1;
public ModelSourceChangeTracker(@NotNull ReloadCallback callback) {
myCallback = callback;
}
public void attach(@NotNull SModel model) {
model.getSource().addListener(this);
// perhaps, caller shall initialize timestamp according to own needs. Done here as this is the way it was in ReloadableSModelBase
updateTimestamp(model.getSource());
}
public void detach(@NotNull SModel model) {
model.getSource().removeListener(this);
}
public long getTimestamp() {
return mySourceTimestamp;
}
// the reason why these methods take DataSource is that I didn't want to keep SModel, although this is not necessarily the best approach
// and keeping the model we are attached to might be reasonable
public void updateTimestamp(@NotNull DataSource dataSource) {
mySourceTimestamp = dataSource.getTimestamp();
}
public boolean needsReloading(@NotNull DataSource dataSource) {
return dataSource.getTimestamp() != mySourceTimestamp;
}
@Override
public void changed(DataSource source) {
if (needsReloading(source)) {
myCallback.reloadFromDiskSafe();
}
}
public interface ReloadCallback {
/*
* Shall resolve storage/memory conflicts if any.
*/
void reloadFromDiskSafe();
}
}