aboutsummaryrefslogtreecommitdiffstats
path: root/store/src/main/java/org/eclipse/viatra/solver/data/query/internal/RelationUpdateListenerEntry.java
blob: 55aed7c85f583ef6902d8b9ab9a13d2e4a89f0b5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package org.eclipse.viatra.solver.data.query.internal;

import java.util.Arrays;
import java.util.Objects;

import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
import org.eclipse.viatra.solver.data.model.Tuple;
import org.eclipse.viatra.solver.data.query.view.RelationView;

public class RelationUpdateListenerEntry<D> {
	final RelationView<D> key;
	final ITuple filter;
	final IQueryRuntimeContextListener listener;
	
	public RelationUpdateListenerEntry(RelationView<D> key, ITuple filter, IQueryRuntimeContextListener listener) {
		super();
		this.key = key;
		this.filter = filter;
		this.listener = listener;
	}
	
	public void processChange(Tuple tuple, D oldValue, D newValue) {
		Object[] oldTuple = isMatching(key.getWrappedKey().transform(tuple, oldValue), filter);
		Object[] newTuple = isMatching(key.getWrappedKey().transform(tuple, newValue), filter);
		
		if(!Arrays.equals(oldTuple, newTuple)) {
			if(oldTuple != null) {
				listener.update(key, Tuples.flatTupleOf(oldTuple), false);
			}
			if(newTuple != null) {
				listener.update(key, Tuples.flatTupleOf(newTuple), true);
			}
		}
	}
	
	private Object[] isMatching(Object[] tuple, ITuple filter) {
		for(int i = 0; i<filter.getSize(); i++) {
			final Object filterObject = filter.get(i);
			if(filterObject != null && !filterObject.equals(tuple[i])) {
				return null;
			}
		}
		return tuple;
	}

	@Override
	public int hashCode() {
		return Objects.hash(filter, key, listener);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof RelationUpdateListenerEntry))
			return false;
		RelationUpdateListenerEntry<?> other = (RelationUpdateListenerEntry<?>) obj;
		return Objects.equals(filter, other.filter) && Objects.equals(key, other.key)
				&& Objects.equals(listener, other.listener);
	}
}