diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 834a6019..8d695821 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -26,13 +26,13 @@ jobs:
TOKEN: "${{secrets.ALLREP_TOKEN}}"
CI: "true"
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-java@v3
with:
- java-version: 11
+ java-version: 17
distribution: zulu
################################################################################
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 12cd94d2..4f82f21f 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -30,7 +30,7 @@
-
+
diff --git a/build.gradle.kts b/build.gradle.kts
index c3c905d3..dfa54924 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -23,8 +23,8 @@ plugins {
eclipse
}
dependencies {
- implementation("org.modelingvalue:immutable-collections:3.1.0-BRANCHED")
- implementation("org.modelingvalue:mvg-json:3.1.0-BRANCHED")
+ implementation("org.modelingvalue:immutable-collections:4.0.0-BRANCHED")
+ implementation("org.modelingvalue:mvg-json:4.0.0-BRANCHED")
}
publishing {
publications {
diff --git a/gradle.properties b/gradle.properties
index a311c8b8..3f2a56ce 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -16,5 +16,5 @@
# suppress inspection "UnusedProperty" for whole file
group = org.modelingvalue
artifact = dclare
-version = 3.1.0
-version_java = 11
+version = 4.0.0
+version_java = 17
diff --git a/src/main/java/org/modelingvalue/dclare/AbstractDerivationTransaction.java b/src/main/java/org/modelingvalue/dclare/AbstractDerivationTransaction.java
index 18fae080..29fe4d31 100644
--- a/src/main/java/org/modelingvalue/dclare/AbstractDerivationTransaction.java
+++ b/src/main/java/org/modelingvalue/dclare/AbstractDerivationTransaction.java
@@ -59,7 +59,12 @@ public R derive(Supplier action, State state, ConstantState memoization)
}
@SuppressWarnings("rawtypes")
- protected boolean doDerive(O object, Getable getable) {
+ protected boolean doDeriveGet(O object, Getable getable, T nonDerived) {
+ return doDeriveSet(object, getable);
+ }
+
+ @SuppressWarnings("rawtypes")
+ protected boolean doDeriveSet(O object, Getable getable) {
return object instanceof Mutable && getable instanceof Observed && DERIVE.get();
}
@@ -81,7 +86,7 @@ protected T current(O object, Getable getable) {
@SuppressWarnings("rawtypes")
private T derive(O object, Getable getable, T nonDerived) {
- if (doDerive(object, getable)) {
+ if (doDeriveGet(object, getable, nonDerived)) {
Observed observed = (Observed) getable;
ConstantState mem = memoization(object);
Constant constant = observed.constant();
@@ -103,7 +108,7 @@ private T derive(O object, Getable getable, T nonDerived) {
}
INDENT.run(INDENT.get() + 1, () -> DERIVED.run(newDerived, () -> {
int i = 0;
- Set observers = ((Mutable) object).dAllDerivers(observed).toSet();
+ Set observers = ((Mutable) object).dAllDerivers(observed).asSet();
for (Observer observer : observers.filter(Observer::anonymous)) {
runDeriver((Mutable) object, observed, observer, ++i);
}
@@ -127,7 +132,7 @@ private T derive(O object, Getable getable, T nonDerived) {
}
@SuppressWarnings({"rawtypes", "unchecked"})
- private void runDeriver(Mutable mutable, Observed observed, Observer observer, int i) {
+ protected void runDeriver(Mutable mutable, Observed observed, Observer observer, int i) {
if (isTraceDerivation(mutable, observed)) {
runNonDeriving(() -> System.err.println(tracePre(mutable) + String.format(">>%d> ", i) + mutable + "." + observer + "()"));
}
@@ -161,12 +166,12 @@ public void runNonDeriving(Runnable action) {
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public T set(O object, Setable setable, T post) {
- if (doDerive(object, setable)) {
+ if (doDeriveSet(object, setable)) {
ConstantState mem = memoization(object);
Constant constant = setable.constant();
T pre = mem.isSet(this, object, constant) ? mem.get(this, object, constant) : getNonDerived(object, setable);
T result = match(mem, setable, pre, post);
- mem.set(this, object, constant, result, true);
+ setInMemoization(mem, object, setable, result);
if (isTraceDerivation(object, setable)) {
runNonDeriving(() -> {
Pair deriver = DERIVER.get();
@@ -175,7 +180,7 @@ public T set(O object, Setable setable, T post) {
}
if (setable.containment()) {
Setable. diff(pre, result, added -> {
- mem.set(this, added, Mutable.D_PARENT_CONTAINING.constant(), Pair.of((Mutable) object, (Setable) setable), true);
+ setInMemoization(mem, added, Mutable.D_PARENT_CONTAINING, Pair.of((Mutable) object, (Setable) setable));
}, removed -> {
});
}
@@ -188,27 +193,27 @@ Setable. diff(pre, result, added -> {
}
private T match(ConstantState mem, Setable setable, T pre, T post) {
- List posts = setable.collection(post).filter(Newable.class).distinct().toList();
+ List posts = setable.collection(post).filter(Newable.class).distinct().asList();
if (!posts.isEmpty()) {
- List pres = setable.collection(pre).filter(Newable.class).exclude(posts::contains).distinct().toList();
+ List pres = setable.collection(pre).filter(Newable.class).exclude(posts::contains).distinct().asList();
if (!pres.isEmpty()) {
for (Newable po : posts) {
- Construction poInit = Newable.D_INITIAL_CONSTRUCTION.get(po);
+ Construction poInit = Mutable.D_INITIAL_CONSTRUCTION.get(po);
if (poInit.isDerived() && mem.isSet(this, po, Newable.D_ALL_DERIVATIONS.constant())) {
for (Newable pr : pres) {
- Construction preInit = Newable.D_INITIAL_CONSTRUCTION.get(pr);
+ Construction preInit = Mutable.D_INITIAL_CONSTRUCTION.get(pr);
if (preInit.isDirect() && po.dNewableType().equals(pr.dNewableType()) && Objects.equals(po.dIdentity(), pr.dIdentity())) {
pres = pres.remove(pr);
post = replace(post, po, pr);
- mem.set(this, pr, Newable.D_ALL_DERIVATIONS.constant(), mem.get(this, po, Newable.D_ALL_DERIVATIONS.constant()), true);
+ setInMemoization(mem, pr, Mutable.D_ALL_DERIVATIONS, mem.get(this, po, Newable.D_ALL_DERIVATIONS.constant()));
}
}
} else if (poInit.isDirect()) {
for (Newable pr : pres) {
- Construction preInit = Newable.D_INITIAL_CONSTRUCTION.get(pr);
+ Construction preInit = Mutable.D_INITIAL_CONSTRUCTION.get(pr);
if (preInit.isDerived() && mem.isSet(this, pr, Newable.D_ALL_DERIVATIONS.constant()) && po.dNewableType().equals(pr.dNewableType()) && Objects.equals(po.dIdentity(), pr.dIdentity())) {
pres = pres.remove(pr);
- mem.set(this, po, Newable.D_ALL_DERIVATIONS.constant(), mem.get(this, pr, Newable.D_ALL_DERIVATIONS.constant()), true);
+ setInMemoization(mem, po, Mutable.D_ALL_DERIVATIONS, mem.get(this, pr, Newable.D_ALL_DERIVATIONS.constant()));
}
}
}
@@ -239,11 +244,15 @@ public O construct(Reason reason, Supplier supplier) {
Pair deriver = DERIVER.get();
O result = supplier.get();
Construction cons = Construction.of(deriver.a(), deriver.b(), reason);
- memoization(deriver.a()).set(this, result, Newable.D_ALL_DERIVATIONS.constant(), Newable.D_ALL_DERIVATIONS.getDefault(result).add(cons), false);
- Newable.D_INITIAL_CONSTRUCTION.force(result, cons);
+ setInMemoization(memoization(deriver.a()), result, Newable.D_ALL_DERIVATIONS, Newable.D_ALL_DERIVATIONS.getDefault(result).add(cons));
+ Mutable.D_INITIAL_CONSTRUCTION.force(result, cons);
return result;
}
+ protected void setInMemoization(ConstantState mem, O object, Setable setable, T result) {
+ mem.set(this, object, setable.constant(), result, true);
+ }
+
protected ConstantState memoization(O object) {
return object instanceof Mutable ? ((Mutable) object).dMemoization(this) : memoization();
}
@@ -254,7 +263,7 @@ public ConstantState memoization() {
@SuppressWarnings("rawtypes")
protected boolean isTraceDerivation(O object, Setable setable) {
- return !setable.isPlumbing() && universeTransaction().getConfig().isTraceDerivation();
+ return (setable == null || !setable.isPlumbing()) && universeTransaction().getConfig().isTraceDerivation();
}
private String tracePre(O object) {
diff --git a/src/main/java/org/modelingvalue/dclare/Action.java b/src/main/java/org/modelingvalue/dclare/Action.java
index 5d7cf49e..e0eaeaa0 100644
--- a/src/main/java/org/modelingvalue/dclare/Action.java
+++ b/src/main/java/org/modelingvalue/dclare/Action.java
@@ -24,7 +24,7 @@ public static Action of(Object id) {
}, Priority.one);
}
- public static Action of(Object id, Consumer action, LeafModifier... modifiers) {
+ public static Action of(Object id, Consumer action, LeafModifier>... modifiers) {
return new Action<>(id, action, modifiers);
}
@@ -33,13 +33,13 @@ public static Action of(Object id, Consumer action, Le
private final boolean preserved;
private final boolean read;
- protected Action(Object id, Consumer action, LeafModifier... modifiers) {
+ protected Action(Object id, Consumer action, LeafModifier>... modifiers) {
super(id, modifiers);
this.action = action;
- Direction dir = FeatureModifier.ofClass(Direction.class, modifiers);
+ Direction dir = getModifier(Direction.class);
this.direction = dir == null ? Direction.DEFAULT : dir;
- this.preserved = LeafModifier.preserved.in(modifiers);
- this.read = LeafModifier.read.in(modifiers);
+ this.preserved = hasModifier(LeafModifier.preserved);
+ this.read = hasModifier(LeafModifier.read);
}
@Override
@@ -69,7 +69,7 @@ public ActionTransaction newTransaction(UniverseTransaction universeTransaction)
return new ActionTransaction(universeTransaction);
}
- protected Direction direction() {
+ public Direction direction() {
return direction;
}
diff --git a/src/main/java/org/modelingvalue/dclare/ActionTransaction.java b/src/main/java/org/modelingvalue/dclare/ActionTransaction.java
index ba5e4b0d..5c21fdb6 100644
--- a/src/main/java/org/modelingvalue/dclare/ActionTransaction.java
+++ b/src/main/java/org/modelingvalue/dclare/ActionTransaction.java
@@ -33,12 +33,9 @@
import org.modelingvalue.dclare.ex.TransactionException;
public class ActionTransaction extends LeafTransaction implements StateMergeHandler {
-
- private static final BiFunction HIGHEST = (b, a) -> b == null || b.number() < a.number() ? a : b;
-
- private final CurrentState currentState = new CurrentState();
- private State preState;
- private State postState;
+ private final CurrentState currentState = new CurrentState();
+ private State preState;
+ private State postState;
protected ActionTransaction(UniverseTransaction universeTransaction) {
super(universeTransaction);
@@ -53,7 +50,7 @@ protected void run(State pre, UniverseTransaction universeTransaction) {
((Action) action()).run(mutable());
}
- @SuppressWarnings({"rawtypes", "unchecked"})
+ @SuppressWarnings("rawtypes")
@Override
protected final State run(State pre) {
TraceTimer.traceBegin(traceId());
@@ -64,11 +61,9 @@ protected final State run(State pre) {
run(pre, universeTransaction());
if (universeTransaction().getConfig().isTraceActions()) {
postState = currentState.merge();
- Map