blob: c6a0e924317866abb511a73f004ef7c4aa596904 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004-2008 Gabor Bergmann and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Gabor Bergmann - initial API and implementation
*******************************************************************************/
package org.eclipse.viatra2.gtasm.patternmatcher.incremental.adapters;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.viatra2.framework.IFramework;
import org.eclipse.viatra2.framework.IMachineSetChangedListener;
import org.eclipse.viatra2.framework.properties.IViatraPropertyChangedListener;
import org.eclipse.viatra2.framework.properties.IViatraPropertyProvider;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.IncrementalPMPropertyProvider;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.matcher.ReteEngine;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Receiver;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Supplier;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.remote.Address;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.simple.SimpleReteBuilder;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.RuntimeAnnotation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.RuntimeAnnotationElement;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Machine;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPattern;
public class MachineListener implements IMachineSetChangedListener// Disconnectable
{
WeakReference<IFramework> fw;
ReteEngine<GTPattern> engine = null;
Set<Machine> sensitiveMachines;
int reteThreads;
// public MachineListener(ReteEngine engine) {
public MachineListener(IFramework framework) {
this.fw = new WeakReference<IFramework>(framework);
this.sensitiveMachines = new HashSet<Machine>();
IViatraPropertyProvider provider = framework.getProperties()
.getProvider(IncrementalPMPropertyProvider.VIATRA_INCREMENTAL_PROVIDER_ID);
String threadStr = provider.getProperty(IncrementalPMPropertyProvider.PROP_THREADS);
setThreads(threadStr);
provider.addListener(new IViatraPropertyChangedListener() {
public void propertyChanged(String providerID, String propertyID, String oldVal, String newVal) {
if (providerID.equals(IncrementalPMPropertyProvider.VIATRA_INCREMENTAL_PROVIDER_ID) &&
propertyID.equals(IncrementalPMPropertyProvider.PROP_THREADS))
setThreads(newVal);
}
});
framework.addMachineSetListener(this);
for (Object machine : framework.getMachines())
if (machine instanceof Machine)
processMachine((Machine)machine);
// engine.addDisconnectable(this);
}
private void setThreads(String threadStr) {
// reteThreads option can only be influenced until the engine is created
if (engine == null) {
Integer threads = IncrementalPMPropertyProvider.interpretThreads(threadStr);
reteThreads = threads==null? 0 : threads;
}
}
// public void disconnect() {
// fw.removeMachineSetListener(this); //<-- problematic b/c it is called in
// chain with machineRemoved()
// machineRemoved() -> engine.reset() -> disconnect() --> causes
// ConcurrentModificationException
// }
public void registerPattern(GTPattern gtPattern) {
sensitiveMachines.add(gtPattern.getNamespace());
}
public void machineAdded(Object machine) {
// reteThreads option can only be influenced until the engine is created
if (engine == null && machine instanceof Machine) {
processMachine((Machine)machine);
}
}
private void processMachine(Machine machine) {
for (Object annot: machine.getRuntimeAnnotations())
{
RuntimeAnnotation runtimeAnnotation = (RuntimeAnnotation) annot;
if ("@incremental".equals(runtimeAnnotation.getAnnotationName().toLowerCase()))
for (Object el : runtimeAnnotation.getElements()) {
RuntimeAnnotationElement runtimeAnnotationElement = (RuntimeAnnotationElement)el;
String key = runtimeAnnotationElement.getKey().toLowerCase();
if ("parallel".equals(key) || "threads".equals(key) ) {
String value = runtimeAnnotationElement.getValue();
Integer threads = IncrementalPMPropertyProvider.interpretThreads(value);
if (threads != null) fw.get().getProperties().setRuntimeProperty(
IncrementalPMPropertyProvider.VIATRA_INCREMENTAL_PROVIDER_ID,
IncrementalPMPropertyProvider.PROP_THREADS,
value);
}
}
}
}
public void machineRemoved(Object machine) {
// if our machine is removed, reset all RETEEngines
if (sensitiveMachines.contains(machine)) {
sensitiveMachines.remove(machine);
if (engine !=null) engine.reset();
//initBuilder();
}
}
private void initEngine() {
IFramework framework = fw.get();
VPMGTASMContext context = new VPMGTASMContext(framework);
this.engine = new ReteEngine<GTPattern>(context, reteThreads);
ReteContainerGTASMBuildable buildable = new ReteContainerGTASMBuildable(engine, engine.getReteNet().getHeadContainer());// prerequisite: network, boundary
engine.setBuilder(new SimpleReteBuilder<Address<? extends Supplier>, Address<? extends Receiver>>(buildable, context)); // this.fw = engine.getFramework();
}
public ReteEngine<GTPattern> getEngine() {
if (engine ==null) initEngine();
return engine;
}
public void kill() {
if (engine !=null) engine.killEngine();
fw = null;
sensitiveMachines = null;
}
}