/// <summary> /// Implements operational transforms as per http://cooffice.ntu.edu.sg/otfaq/ 2.15 /// It take a remote operation, that was indented to be applied to a document that hadn't yet had the local operation /// applied, and translates it to one that maintains the intent when used one a document that did have the local operation applied. /// </summary> /// <param name="remoteOperation">The remote operation we want to transform</param> /// <param name="localOperation">The local operation we want to transform using</param> /// <returns></returns> public static OperationBase Transform(OperationBase remoteOperation, OperationBase localOperation) { switch (remoteOperation) { case InsertOperation remoteInsert: switch (localOperation) { case InsertOperation localInsert: return(TransformInsertInsert(remoteInsert, localInsert)); case DeleteOperation localDelete: return(TransformInsertDelete(remoteInsert, localDelete)); case IdentityOperation localIdentity: return(remoteOperation); default: throw new InvalidOperationException(); } case DeleteOperation remoteDelete: switch (localOperation) { case InsertOperation localInsert: return(TransformDeleteInsert(remoteDelete, localInsert)); case DeleteOperation localDelete: return(TransformDeleteDelete(remoteDelete, localDelete)); case IdentityOperation localIdentity: return(remoteOperation); default: throw new InvalidOperationException(); } case IdentityOperation remoteIdentity: return(remoteOperation); default: throw new InvalidOperationException(); } }
public bool IdenticalOperation(OperationBase other) { if (other == null) { return(false); } if (GetType() != other.GetType()) { return(false); } return(Position == other.Position && Text == other.Text); }
/// <summary> /// Create a new applied operation against a site with no prior transformations /// </summary> /// <param name="operation"></param> internal AppliedOperation(OperationBase operation) => Operation = operation;