Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
57c31c2
C3 linearization for multiple inheritance
Gattag Jul 13, 2023
34d9dde
java 17 toList -> asList
WimBast Aug 17, 2023
9531712
move to version 4.0.0
tombrus Aug 18, 2023
958222a
[no-ci] updated by mvgplugin
Aug 19, 2023
b740857
Merge remote-tracking branch 'origin/MPS2022' into develop
tombrus Aug 19, 2023
31ab86c
Merge remote-tracking branch 'origin/develop' into develop
tombrus Aug 19, 2023
b29e943
Bump actions/checkout from 3 to 4
dependabot[bot] Sep 5, 2023
8912d6d
change OnsShot to use a pool of pools (still contains some tracing so…
tombrus Sep 5, 2023
b1c9a5a
Merge pull request #40 from ModelingValueGroup/dependabot/github_acti…
tombrus Sep 5, 2023
eaa30c6
change OnsShot to use a pool of pools (still contains some tracing so…
tombrus Sep 6, 2023
b423b13
Merge remote-tracking branch 'origin/develop' into develop
tombrus Sep 6, 2023
a247c41
take care that the user gets a clearer error on a potential NPE probl…
tombrus Sep 11, 2023
531e216
fix #41 : add simple cycle-in-parent-chain detection (+some suppress…
tombrus Sep 14, 2023
10bc99a
[no-ci] updated by mvgplugin
Sep 14, 2023
7092add
fix #41 : i.s.o. throwing we now try to continue after a parent cylce
tombrus Sep 19, 2023
7b6e282
prevent stack-overflow by comparing transaction number with current
WimBast Sep 25, 2023
84997f4
getter for preState in ImperativeTransaction
WimBast Sep 28, 2023
f18d66b
use preState from state as preState in Imperative transaction
WimBast Sep 28, 2023
110c58d
Newable -> Mutable
WimBast Sep 29, 2023
193c85a
fix #42: make SetableModifier an interface
tombrus Oct 2, 2023
284775f
[no-ci] updated by mvgplugin
Oct 2, 2023
33a3c2f
we switched to java17, right?
tombrus Oct 2, 2023
0220fe9
needed some extra tracing facilities in OneShot, lets keep it in for …
tombrus Oct 5, 2023
dbe7137
unsupported oper except fix
WimBast Oct 27, 2023
a717c2f
pre post state
WimBast Oct 30, 2023
4e1b544
minor update for exception message
tombrus Oct 31, 2023
182dcd4
Merge remote-tracking branch 'origin/develop' into develop
tombrus Oct 31, 2023
854c601
direction for setables
WimBast Nov 6, 2023
2681cc7
set of modifiers
WimBast Nov 6, 2023
498512f
lazy
WimBast Nov 6, 2023
4d5e4ff
do not activate lazy observers
WimBast Nov 6, 2023
c8b5f1e
no checking of lazy setables
WimBast Nov 6, 2023
eaf95a9
prepare lazy evaluation
WimBast Nov 6, 2023
6697a65
lazy derivation
WimBast Nov 6, 2023
1caa19e
Merge pull request #37 from Gattag/type-wrapper
WimBast Nov 6, 2023
ce4bd81
[no-ci] updated by mvgplugin
Nov 6, 2023
885f76b
toList -> asList
WimBast Nov 7, 2023
5cba241
derive lazy
WimBast Nov 8, 2023
589434f
prepare for release 4.0.0
tombrus Nov 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

################################################################################
Expand Down
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ public <R> R derive(Supplier<R> action, State state, ConstantState memoization)
}

@SuppressWarnings("rawtypes")
protected <O, T> boolean doDerive(O object, Getable<O, T> getable) {
protected <O, T> boolean doDeriveGet(O object, Getable<O, T> getable, T nonDerived) {
return doDeriveSet(object, getable);
}

@SuppressWarnings("rawtypes")
protected <O, T> boolean doDeriveSet(O object, Getable<O, T> getable) {
return object instanceof Mutable && getable instanceof Observed && DERIVE.get();
}

Expand All @@ -81,7 +86,7 @@ protected <O, T> T current(O object, Getable<O, T> getable) {

@SuppressWarnings("rawtypes")
private <O, T> T derive(O object, Getable<O, T> getable, T nonDerived) {
if (doDerive(object, getable)) {
if (doDeriveGet(object, getable, nonDerived)) {
Observed<O, T> observed = (Observed<O, T>) getable;
ConstantState mem = memoization(object);
Constant<O, T> constant = observed.constant();
Expand All @@ -103,7 +108,7 @@ private <O, T> T derive(O object, Getable<O, T> getable, T nonDerived) {
}
INDENT.run(INDENT.get() + 1, () -> DERIVED.run(newDerived, () -> {
int i = 0;
Set<Observer> observers = ((Mutable) object).dAllDerivers(observed).toSet();
Set<Observer> observers = ((Mutable) object).dAllDerivers(observed).asSet();
for (Observer observer : observers.filter(Observer::anonymous)) {
runDeriver((Mutable) object, observed, observer, ++i);
}
Expand All @@ -127,7 +132,7 @@ private <O, T> T derive(O object, Getable<O, T> 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 + "()"));
}
Expand Down Expand Up @@ -161,12 +166,12 @@ public void runNonDeriving(Runnable action) {
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public <O, T> T set(O object, Setable<O, T> setable, T post) {
if (doDerive(object, setable)) {
if (doDeriveSet(object, setable)) {
ConstantState mem = memoization(object);
Constant<O, T> 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<Mutable, Observer> deriver = DERIVER.get();
Expand All @@ -175,7 +180,7 @@ public <O, T> T set(O object, Setable<O, T> setable, T post) {
}
if (setable.containment()) {
Setable.<T, Mutable> diff(pre, result, added -> {
mem.set(this, added, Mutable.D_PARENT_CONTAINING.constant(), Pair.of((Mutable) object, (Setable<Mutable, ?>) setable), true);
setInMemoization(mem, added, Mutable.D_PARENT_CONTAINING, Pair.of((Mutable) object, (Setable<Mutable, ?>) setable));
}, removed -> {
});
}
Expand All @@ -188,27 +193,27 @@ Setable.<T, Mutable> diff(pre, result, added -> {
}

private <T, O> T match(ConstantState mem, Setable<O, T> setable, T pre, T post) {
List<Newable> posts = setable.collection(post).filter(Newable.class).distinct().toList();
List<Newable> posts = setable.collection(post).filter(Newable.class).distinct().asList();
if (!posts.isEmpty()) {
List<Newable> pres = setable.collection(pre).filter(Newable.class).exclude(posts::contains).distinct().toList();
List<Newable> 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()));
}
}
}
Expand Down Expand Up @@ -239,11 +244,15 @@ public <O extends Mutable> O construct(Reason reason, Supplier<O> supplier) {
Pair<Mutable, Observer> 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 <T, O> void setInMemoization(ConstantState mem, O object, Setable<O, T> setable, T result) {
mem.set(this, object, setable.constant(), result, true);
}

protected <O> ConstantState memoization(O object) {
return object instanceof Mutable ? ((Mutable) object).dMemoization(this) : memoization();
}
Expand All @@ -254,7 +263,7 @@ public <O> ConstantState memoization() {

@SuppressWarnings("rawtypes")
protected <O> boolean isTraceDerivation(O object, Setable setable) {
return !setable.isPlumbing() && universeTransaction().getConfig().isTraceDerivation();
return (setable == null || !setable.isPlumbing()) && universeTransaction().getConfig().isTraceDerivation();
}

private <O> String tracePre(O object) {
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/modelingvalue/dclare/Action.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static <M extends Mutable> Action<M> of(Object id) {
}, Priority.one);
}

public static <M extends Mutable> Action<M> of(Object id, Consumer<M> action, LeafModifier... modifiers) {
public static <M extends Mutable> Action<M> of(Object id, Consumer<M> action, LeafModifier<?>... modifiers) {
return new Action<>(id, action, modifiers);
}

Expand All @@ -33,13 +33,13 @@ public static <M extends Mutable> Action<M> of(Object id, Consumer<M> action, Le
private final boolean preserved;
private final boolean read;

protected Action(Object id, Consumer<O> action, LeafModifier... modifiers) {
protected Action(Object id, Consumer<O> 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
Expand Down Expand Up @@ -69,7 +69,7 @@ public ActionTransaction newTransaction(UniverseTransaction universeTransaction)
return new ActionTransaction(universeTransaction);
}

protected Direction direction() {
public Direction direction() {
return direction;
}

Expand Down
38 changes: 17 additions & 21 deletions src/main/java/org/modelingvalue/dclare/ActionTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,9 @@
import org.modelingvalue.dclare.ex.TransactionException;

public class ActionTransaction extends LeafTransaction implements StateMergeHandler {

private static final BiFunction<TransactionId, TransactionId, TransactionId> 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);
Expand All @@ -53,7 +50,7 @@ protected void run(State pre, UniverseTransaction universeTransaction) {
((Action<Mutable>) action()).run(mutable());
}

@SuppressWarnings({"rawtypes", "unchecked"})
@SuppressWarnings("rawtypes")
@Override
protected final State run(State pre) {
TraceTimer.traceBegin(traceId());
Expand All @@ -64,11 +61,9 @@ protected final State run(State pre) {
run(pre, universeTransaction());
if (universeTransaction().getConfig().isTraceActions()) {
postState = currentState.merge();
Map<Object, Map<Setable, Pair<Object, Object>>> diff = preState.diff(postState, o -> o instanceof Mutable, s -> s instanceof Observed && !s.isPlumbing()).toMap(e -> e);
Map<Object, Map<Setable, Pair<Object, Object>>> diff = preState.diff(postState, o -> o instanceof Mutable, s -> s instanceof Observed /* && !s.isPlumbing() */).asMap(e -> e);
if (!diff.isEmpty()) {
runNonObserving(() -> {
System.err.println(DclareTrace.getLineStart("DCLARE", this) + mutable() + "." + action() + " (" + postState.shortDiffString(diff, mutable()) + ")");
});
runNonObserving(() -> System.err.println(DclareTrace.getLineStart("DCLARE", this) + mutable() + "." + action() + " (" + postState.shortDiffString(diff, mutable()) + ")"));
}
} else {
postState = currentState.result();
Expand Down Expand Up @@ -156,6 +151,10 @@ protected <T, O> void set(O object, Setable<O, T> property, T pre, T post) {
}
}

protected void setState(State state) {
currentState.set(state);
}

@SuppressWarnings({"rawtypes", "unchecked", "RedundantSuppression"})
@Override
protected <O, T> void changed(O object, Setable<O, T> setable, T preValue, T postValue) {
Expand All @@ -178,22 +177,21 @@ private <O, T> void trigger(O object, Observed<O, T> observed) {
if (!action().equals(observer) || !source.equals(target)) {
trigger(target, observer, observer.initPriority());
if (universeTransaction().getConfig().isTraceMutable()) {
runNonObserving(() -> {
System.err.println(DclareTrace.getLineStart("DCLARE", this) + mutable() + "." + action() + " (TRIGGER " + target + "." + observer + ")");
});
runNonObserving(() -> System.err.println(DclareTrace.getLineStart("DCLARE", this) + mutable() + "." + action() + " (TRIGGER " + target + "." + observer + ")"));
}
}
}
}
}

@SuppressWarnings("rawtypes")
private final <O, T> void setChanged(O object, Setable<O, T> setable, T postValue) {
private <O, T> void setChanged(O object, Setable<O, T> setable, T postValue) {
TransactionId txid = action().preserved() ? universeTransaction().setPreserved(object, setable, postValue, action()) : current().transactionId();
for (Mutable changed = (Mutable) object; changed != null && !(changed instanceof Universe); changed = dParent(changed)) {
TransactionId old = set(changed, Mutable.D_CHANGE_ID, HIGHEST, txid);
if (old != null && old.number() >= txid.number()) {
TransactionId old = current(changed, Mutable.D_CHANGE_ID);
if (old != null && txid.number() <= old.number()) {
break;
} else {
set(changed, Mutable.D_CHANGE_ID, txid);
}
}
}
Expand All @@ -203,7 +201,6 @@ private final class CurrentState extends Concurrent<State> {
protected State merge(State base, State[] branches, int length) {
return base.merge(ActionTransaction.this, branches, length);
}

}

@SuppressWarnings("rawtypes")
Expand Down Expand Up @@ -239,9 +236,8 @@ protected String getCurrentTypeForTrace() {
return "AC";
}

@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "unused"})
public void retrigger(Priority prio) {
trigger(mutable(), (Action<Mutable>) action(), prio);
}

}
18 changes: 9 additions & 9 deletions src/main/java/org/modelingvalue/dclare/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,41 +31,41 @@ public class Constant<O, T> extends Setable<O, T> {

public static final Context<Pair<Object, Constant<?, ?>>> DERIVED = Context.of(null);

public static <C, V> Constant<C, V> of(Object id, V def, SetableModifier... modifiers) {
public static <C, V> Constant<C, V> of(Object id, V def, SetableModifier<?>... modifiers) {
return new Constant<>(id, o -> def, null, null, null, null, modifiers);
}

public static <C, V> Constant<C, V> of(Object id, V def, QuadConsumer<LeafTransaction, C, V, V> changed, SetableModifier... modifiers) {
public static <C, V> Constant<C, V> of(Object id, V def, QuadConsumer<LeafTransaction, C, V, V> changed, SetableModifier<?>... modifiers) {
return new Constant<>(id, o -> def, null, null, null, changed, modifiers);
}

public static <C, V> Constant<C, V> of(Object id, Function<C, V> deriver, SetableModifier... modifiers) {
public static <C, V> Constant<C, V> of(Object id, Function<C, V> deriver, SetableModifier<?>... modifiers) {
return new Constant<>(id, null, null, null, deriver, null, modifiers);
}

public static <C, V> Constant<C, V> of(Object id, V def, Function<C, V> deriver, SetableModifier... modifiers) {
public static <C, V> Constant<C, V> of(Object id, V def, Function<C, V> deriver, SetableModifier<?>... modifiers) {
return new Constant<>(id, o -> def, null, null, deriver, null, modifiers);
}

public static <C, V> Constant<C, V> of(Object id, Function<C, V> deriver, QuadConsumer<LeafTransaction, C, V, V> changed, SetableModifier... modifiers) {
public static <C, V> Constant<C, V> of(Object id, Function<C, V> deriver, QuadConsumer<LeafTransaction, C, V, V> changed, SetableModifier<?>... modifiers) {
return new Constant<>(id, null, null, null, deriver, changed, modifiers);
}

public static <C, V> Constant<C, V> of(Object id, V def, Supplier<Setable<?, ?>> opposite, Function<C, V> deriver, SetableModifier... modifiers) {
public static <C, V> Constant<C, V> of(Object id, V def, Supplier<Setable<?, ?>> opposite, Function<C, V> deriver, SetableModifier<?>... modifiers) {
return new Constant<>(id, o -> def, opposite, null, deriver, null, modifiers);
}

public static <C, V> Constant<C, V> of(Object id, V def, Supplier<Setable<?, ?>> opposite, Supplier<Setable<C, Set<?>>> scope, Function<C, V> deriver, SetableModifier... modifiers) {
public static <C, V> Constant<C, V> of(Object id, V def, Supplier<Setable<?, ?>> opposite, Supplier<Setable<C, Set<?>>> scope, Function<C, V> deriver, SetableModifier<?>... modifiers) {
return new Constant<>(id, o -> def, opposite, scope, deriver, null, modifiers);
}

private final Function<O, T> deriver;
private final boolean durable;

protected Constant(Object id, Function<O, T> def, Supplier<Setable<?, ?>> opposite, Supplier<Setable<O, Set<?>>> scope, Function<O, T> deriver, QuadConsumer<LeafTransaction, O, T, T> changed, SetableModifier... modifiers) {
protected Constant(Object id, Function<O, T> def, Supplier<Setable<?, ?>> opposite, Supplier<Setable<O, Set<?>>> scope, Function<O, T> deriver, QuadConsumer<LeafTransaction, O, T, T> changed, SetableModifier<?>... modifiers) {
super(id, def, opposite, scope, changed, modifiers);
this.deriver = deriver;
this.durable = SetableModifier.durable.in(modifiers);
this.durable = hasModifier(CoreSetableModifier.durable);
}

public Function<O, T> deriver() {
Expand Down
Loading