public SynchronizationContext(Synchronization synchronization, SynchronizationDirection direction, ChangePropagationMode changePropagation) : base(synchronization) { Direction = direction; ChangePropagation = changePropagation; Inconsistencies = new ObservableSet <IInconsistency>(); }
protected void PerformNoChangePropagation(TLeft left, TRight right, SynchronizationDirection direction, ISynchronizationContext context) { switch (direction) { case SynchronizationDirection.CheckOnly: var leftValue = leftGetter(left); var rightValue = rightGetter(right); if (!EqualityComparer <TValue> .Default.Equals(leftValue, rightValue)) { context.Inconsistencies.Add(new PropertyInequality <TLeft, TRight, TValue>(left, leftSetter, leftValue, right, rightSetter, rightValue)); } break; case SynchronizationDirection.LeftToRight: case SynchronizationDirection.LeftToRightForced: rightSetter(right, leftGetter(left)); break; case SynchronizationDirection.LeftWins: var val1 = leftGetter(left); if (val1 != null) { rightSetter(right, val1); } else { leftSetter(left, rightGetter(right)); } break; case SynchronizationDirection.RightToLeft: case SynchronizationDirection.RightToLeftForced: leftSetter(left, rightGetter(right)); break; case SynchronizationDirection.RightWins: var val2 = rightGetter(right); if (val2 != null) { leftSetter(left, val2); } else { rightSetter(right, leftGetter(left)); } break; default: throw new InvalidOperationException(); } }
public Dependency(ISynchronizationJob <TLeft, TRight> inner, SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, INotifyValue <bool> tracker) { Inner = inner; Computation = computation; Direction = direction; Tracker = tracker; if (tracker.Value) { Current = Inner.Perform(Computation, Direction, Computation.SynchronizationContext); } Tracker.ValueChanged += Tracker_ValueChanged; }
protected void PerformNoChangePropagation(TLeft left, TRight right, SynchronizationDirection direction) { switch (direction) { case SynchronizationDirection.LeftToRight: case SynchronizationDirection.LeftToRightForced: rightSetter(right, leftGetter(left)); break; case SynchronizationDirection.LeftWins: var val1 = leftGetter(left); if (val1 != null) { rightSetter(right, val1); } else { leftSetter(left, rightGetter(right)); } break; case SynchronizationDirection.RightToLeft: case SynchronizationDirection.RightToLeftForced: leftSetter(left, rightGetter(right)); break; case SynchronizationDirection.RightWins: var val2 = rightGetter(right); if (val2 != null) { leftSetter(left, val2); } else { rightSetter(right, leftGetter(left)); } break; default: throw new InvalidOperationException(); } }
public virtual IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context) { if (direction.IsRightToLeft()) { return(Perform(computation.Opposite.Input, computation.Input, context)); } else { return(null); } }
public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context) { var left = computation.Input; var right = computation.Opposite.Input; switch (context.ChangePropagation) { case NMF.Transformations.ChangePropagationMode.None: PerformNoChangePropagation(left, right, direction); return(null); case NMF.Transformations.ChangePropagationMode.OneWay: return(PerformOneWay(left, right, context)); case NMF.Transformations.ChangePropagationMode.TwoWay: return(PerformTwoWay(left, right, context)); default: throw new InvalidOperationException(); } }
public ISynchronizationContext Synchronize <TLeft, TRight>(SynchronizationRule <TLeft, TRight> startRule, ref TLeft left, ref TRight right, SynchronizationDirection direction, ChangePropagationMode changePropagation) where TLeft : class where TRight : class { if (startRule == null) { throw new ArgumentNullException("startRule"); } Initialize(); var context = new SynchronizationContext(this, direction, changePropagation); switch (direction) { case SynchronizationDirection.LeftToRight: case SynchronizationDirection.LeftToRightForced: case SynchronizationDirection.LeftWins: var c1 = TransformationRunner.Transform(new object[] { left }, right != null ? new Axiom(right) : null, startRule.LeftToRight, context); right = c1.Output as TRight; break; case SynchronizationDirection.RightToLeft: case SynchronizationDirection.RightToLeftForced: case SynchronizationDirection.RightWins: var c2 = TransformationRunner.Transform(new object[] { right }, left != null ? new Axiom(left) : null, startRule.RightToLeft, context); left = c2.Output as TLeft; break; case SynchronizationDirection.CheckOnly: if (left == null) { throw new ArgumentException("Passed model must not be null when running in check-only mode", nameof(left)); } if (right == null) { throw new ArgumentException("Passed model must not be null when running in check-only mode", nameof(right)); } TransformationRunner.Transform(new object[] { left }, new Axiom(right), startRule.LeftToRight, context); break; default: throw new ArgumentOutOfRangeException("direction"); } return(context); }
public ISynchronizationContext Synchronize <TLeft, TRight>(SynchronizationRule <TLeft, TRight> startRule, ref TLeft left, ref TRight right, SynchronizationDirection direction, ChangePropagationMode changePropagation) where TLeft : class where TRight : class { if (startRule == null) { throw new ArgumentNullException("startRule"); } Initialize(); var context = new SynchronizationContext(this, direction, changePropagation); switch (direction) { case SynchronizationDirection.LeftToRight: case SynchronizationDirection.LeftToRightForced: case SynchronizationDirection.LeftWins: var c1 = TransformationRunner.Transform(new object[] { left }, new object[] { right }, startRule.LeftToRight, context); right = c1.Output as TRight; break; case SynchronizationDirection.RightToLeft: case SynchronizationDirection.RightToLeftForced: case SynchronizationDirection.RightWins: var c2 = TransformationRunner.Transform(new object[] { right }, new object[] { left }, startRule.RightToLeft, context); left = c2.Output as TLeft; break; default: throw new ArgumentOutOfRangeException("direction"); } return(context); }
internal void Synchronize(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context) { var dependencies = computation.Dependencies; foreach (var job in SynchronizationJobs.Where(j => !j.IsEarly)) { var dependency = job.Perform(computation, direction, context); if (dependency != null) { dependencies.Add(dependency); } } }
private void CallRTLTransformationForInput(SynchronizationComputation <TRight, TLeft> syncComputation, SynchronizationDirection direction, TDepRight input, TDepLeft context, Action <TLeft, TDepLeft> leftSetter, Action <TRight, TDepRight> rightSetter) { var left = syncComputation.Opposite.Input; if (input != null) { if (leftSetter == null) { return; } var comp = syncComputation.TransformationContext.CallTransformation(childRule.RightToLeft, new object[] { input }, new object[] { context }); if (comp == null) { return; } if (!comp.IsDelayed) { leftSetter(left, comp.Output as TDepLeft); } else { comp.OutputInitialized += (o, e) => leftSetter(left, comp.Output as TDepLeft); }; } else { if (direction == SynchronizationDirection.RightWins) { CallLTRTransformationForInput(syncComputation.Opposite, SynchronizationDirection.RightWins, context, input, leftSetter, rightSetter); } else if (direction == SynchronizationDirection.RightToLeftForced) { if (leftSetter == null) { return; } leftSetter(left, null); } } }
public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context) { if (Action != null) { return(Action(computation.Input, computation.Opposite.Input, direction, context)); } else { return(null); } }
public SynchronizationContext(Synchronization synchronization, SynchronizationDirection direction, ChangePropagationMode changePropagation) : base(synchronization) { this.direction = direction; this.changePropagation = changePropagation; }
public static bool IsRightToLeft(this SynchronizationDirection direction) { return(direction == SynchronizationDirection.RightToLeft || direction == SynchronizationDirection.RightToLeftForced || direction == SynchronizationDirection.RightWins); }
public static bool IsLeftToRight(this SynchronizationDirection direction) { return(direction == SynchronizationDirection.LeftToRight || direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.LeftWins); }
public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context) { switch (context.ChangePropagation) { case ChangePropagationMode.None: return(null); case ChangePropagationMode.OneWay: if (direction != SynchronizationDirection.LeftToRight && direction != SynchronizationDirection.LeftToRightForced && direction != SynchronizationDirection.LeftWins) { return(null); } break; case ChangePropagationMode.TwoWay: break; default: throw new InvalidOperationException("The change propagation mode is invalid."); } var instantiationMonitor = Predicate.Observe(computation.Input); var monitor = new Monitor(instantiationMonitor, computation); monitor.StartMonitoring(); return(monitor); }
internal void CallRTLTransformationForInput(SynchronizationComputation <TRight, TLeft> syncComputation, SynchronizationDirection direction, TDepRight input, TDepLeft context, Action <TLeft, TDepLeft> leftSetter, Action <TRight, TDepRight> rightSetter) { if (direction == SynchronizationDirection.CheckOnly) { // two-way change propagation is handled through dependency if (syncComputation.SynchronizationContext.ChangePropagation == ChangePropagationMode.None) { Match(syncComputation.Opposite, leftGetter(syncComputation.Opposite.Input), input); } return; } var left = syncComputation.Opposite.Input; if (input != null) { if (leftSetter == null) { return; } var comp = syncComputation.TransformationContext.CallTransformation(childRule.RightToLeft, new object[] { input }, new object[] { context }); if (comp == null) { return; } if (!comp.IsDelayed) { leftSetter(left, comp.Output as TDepLeft); } else { comp.OutputInitialized += (o, e) => leftSetter(left, comp.Output as TDepLeft); }; } else { if (direction == SynchronizationDirection.RightWins) { CallLTRTransformationForInput(syncComputation.Opposite, SynchronizationDirection.RightWins, context, input, leftSetter, rightSetter); } else if (direction == SynchronizationDirection.RightToLeftForced) { if (leftSetter == null) { return; } leftSetter(left, null); } } }
public ISynchronizationContext SynchronizeMany <TLeft, TRight>(SynchronizationRule <TLeft, TRight> startRule, ICollection <TLeft> lefts, ICollection <TRight> rights, SynchronizationDirection direction, ChangePropagationMode changePropagation) where TLeft : class where TRight : class { if (startRule == null) { throw new ArgumentNullException("startRule"); } var context = new SynchronizationContext(this, direction, changePropagation); switch (direction) { case SynchronizationDirection.LeftToRight: var c1 = TransformationRunner.TransformMany(lefts.Select(l => new object[] { l }), rights, startRule.LeftToRight, context); rights.Clear(); rights.AddRange(c1.Select(c => c.Output as TRight)); break; case SynchronizationDirection.RightToLeft: var c2 = TransformationRunner.TransformMany(rights.Select(r => new object[] { r }), lefts, startRule.RightToLeft, context); lefts.Clear(); lefts.AddRange(c2.Select(c => c.Output as TLeft)); break; default: throw new ArgumentOutOfRangeException("direction"); } return(context); }
public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context) { return(new Dependency(Inner, computation, direction, CreateTracker(computation))); }
public ISynchronizationContext Synchronize <TLeft, TRight>(ref TLeft left, ref TRight right, SynchronizationDirection direction, ChangePropagationMode changePropagation) where TLeft : class where TRight : class { return(Synchronize <TLeft, TRight>(GetSynchronizationRuleForSignature(typeof(TLeft), typeof(TRight)) as SynchronizationRule <TLeft, TRight>, ref left, ref right, direction, changePropagation)); }
private void TestFsm2Pn(SynchronizationDirection direction, ChangePropagationMode changePropagartion, bool initializeFsm, bool initializePn) { Assert.IsTrue(initializeFsm | initializePn); var fsm = this.fsm; var pn = this.pn; if (initializeFsm) { FillStateMachine(); } if (initializePn) { FillPetriNet(); } fsm2pn.Initialize(); var context = fsm2pn.Synchronize(fsm2pn.SynchronizationRule <FSM2PN.AutomataToNet>(), ref fsm, ref pn, direction, changePropagartion); var isLeftToRight = direction == SynchronizationDirection.LeftToRight || direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.LeftWins; var isForced = direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.RightToLeftForced; var isJoined = direction == SynchronizationDirection.LeftWins || direction == SynchronizationDirection.RightWins; Fsm.State s1; Pn.Place p1; if (initializeFsm && initializePn) { if (isForced) { if (isLeftToRight) { s1 = AssertOriginalFsm(fsm, context); } else { s1 = AssertPetriNetLikeFsm(fsm, context); } } else if (isJoined || !isLeftToRight) { s1 = AssertJoinedFsm(fsm, context); } else { s1 = AssertOriginalFsm(fsm, context); } } else if (!initializeFsm) { if (!isLeftToRight || isJoined) { s1 = AssertPetriNetLikeFsm(fsm, context); } else { s1 = AssertEmptyFsm(fsm); } } else if (!initializePn) { if (isForced && !isLeftToRight) { s1 = AssertEmptyFsm(fsm); } else { s1 = AssertOriginalFsm(fsm, context); } } else { s1 = null; Assert.Fail(); } if (initializeFsm && initializePn) { if (isForced) { if (!isLeftToRight) { p1 = AssertOriginalPetriNet(pn, context, s1); } else { p1 = AssertFsmLikePetriNet(pn, context, s1); } } else if (isJoined || isLeftToRight) { p1 = AssertJoinedPetriNet(pn, context, s1); } else { p1 = AssertOriginalPetriNet(pn, context, s1); } } else if (!initializePn) { if (isLeftToRight || isJoined) { p1 = AssertFsmLikePetriNet(pn, context, s1); } else { p1 = AssertEmptyPetriNet(pn); } } else if (!initializeFsm) { if (isForced && isLeftToRight) { p1 = AssertEmptyPetriNet(pn); } else { p1 = AssertOriginalPetriNet(pn, context, s1); } } else { p1 = null; Assert.Fail(); } if (changePropagartion == ChangePropagationMode.TwoWay || (changePropagartion == ChangePropagationMode.OneWay && isLeftToRight)) { AssertOneWayUpdatesFsmToPetriNet(s1, p1); } if (changePropagartion == ChangePropagationMode.TwoWay || (changePropagartion == ChangePropagationMode.OneWay && !isLeftToRight)) { AssertOneWayUpdatesPetriNetToFsm(p1, s1); } }
private void TestFsm2Pn(SynchronizationDirection direction, ChangePropagationMode changePropagartion, bool initializeFsm, bool initializePn) { Assert.IsTrue(initializeFsm | initializePn); var fsm = this.fsm; var pn = this.pn; if (initializeFsm) FillStateMachine(); if (initializePn) FillPetriNet(); fsm2pn.Initialize(); var context = fsm2pn.Synchronize(fsm2pn.SynchronizationRule<FSM2PN.AutomataToNet>(), ref fsm, ref pn, direction, changePropagartion); var isLeftToRight = direction == SynchronizationDirection.LeftToRight || direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.LeftWins; var isForced = direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.RightToLeftForced; var isJoined = direction == SynchronizationDirection.LeftWins || direction == SynchronizationDirection.RightWins; Fsm.State s1; Pn.Place p1; if (initializeFsm && initializePn) { if (isForced) { if (isLeftToRight) { s1 = AssertOriginalFsm(fsm, context); } else { s1 = AssertPetriNetLikeFsm(fsm, context); } } else if (isJoined || !isLeftToRight) { s1 = AssertJoinedFsm(fsm, context); } else { s1 = AssertOriginalFsm(fsm, context); } } else if (!initializeFsm) { if (!isLeftToRight || isJoined) { s1 = AssertPetriNetLikeFsm(fsm, context); } else { s1 = AssertEmptyFsm(fsm); } } else if (!initializePn) { if (isForced && !isLeftToRight) { s1 = AssertEmptyFsm(fsm); } else { s1 = AssertOriginalFsm(fsm, context); } } else { s1 = null; Assert.Fail(); } if (initializeFsm && initializePn) { if (isForced) { if (!isLeftToRight) { p1 = AssertOriginalPetriNet(pn, context, s1); } else { p1 = AssertFsmLikePetriNet(pn, context, s1); } } else if (isJoined || isLeftToRight) { p1 = AssertJoinedPetriNet(pn, context, s1); } else { p1 = AssertOriginalPetriNet(pn, context, s1); } } else if (!initializePn) { if (isLeftToRight || isJoined) { p1 = AssertFsmLikePetriNet(pn, context, s1); } else { p1 = AssertEmptyPetriNet(pn); } } else if (!initializeFsm) { if (isForced && isLeftToRight) { p1 = AssertEmptyPetriNet(pn); } else { p1 = AssertOriginalPetriNet(pn, context, s1); } } else { p1 = null; Assert.Fail(); } if (changePropagartion == ChangePropagationMode.TwoWay || (changePropagartion == ChangePropagationMode.OneWay && isLeftToRight)) { AssertOneWayUpdatesFsmToPetriNet(s1, p1); } if (changePropagartion == ChangePropagationMode.TwoWay || (changePropagartion == ChangePropagationMode.OneWay && !isLeftToRight)) { AssertOneWayUpdatesPetriNetToFsm(p1, s1); } }