自動勉強会 vol.2 共同編集・Undo回
参加方法
複雑GUI会のDiscordに入っておいてください。
聞き専の方は入ったらミュートに設定してください
Scrapboxの登録リンクを踏んで編集可能にします
課題
共同編集テキストエディタ? (大変そう)
何でもいいので逆操作コマンド型とスナップショット型を軽く実装してみるとか?

目次
Undo
逆操作コマンド、順操作側を冪等にする?
操作がstoreへのmutation的なときに、冪等にしておくとちょっと便利なパターンがある(後から一発でアンドゥしたい「オブジェクトの移動」なんかをまとめられるけど小手先のテクニックかも)

更新操作自体を全体的に冪等にしたい派

テキスト編集のアンドゥ
JSON構造のundo
jsondiffpatchの生成したdiff見ると、base変わった場合簡単に対応しなくなりそう.. と感じた

プロパティの書き込みを監視してクライアントでUndo登録してる

ベクターのアンドゥ
JSONのアンドゥ、任意のオブジェクトのアンドゥとして考えられる
ラスターのアンドゥ

画素データ自体を保存するのか、それともスナップショットを起点に編集パラメーター(ブラシ位置等)を逐次保存するのか
ブラシのパラメータとストロークを両方保存しておけば画素データまるごと持たなくてもいいよね
ストローク保持してるなら、ブラシのパラメータ変えて再度描けるよね
スナップショットと差分の間の子
undoした時はスナップショットからの差分を全部再生しないといけない...重くならない?
どれくらいならセーフ??
昔の
絵茶だと、最初から全再生する実装もあったらしい...undoに1分待つとか
すごい時代だ...

共同編集 + Undo
MagicalDraw 自分の操作がサーバーに送信される前ならアンドゥできる
minordaimyo作のお絵描きチャット"えんぴつチャット"でのundo(スナップショット)
めちゃくちゃズームできる。すごい

> 描画開始時刻以降に、描画範囲と重なる別の描画が存在するかどうかを調べる。なければundo
できないものの割り切り
キャンバス全域に斜めに線を引くと他の人のundoできなくなったりする?

yes。でも、お絵かきチャットはみんな「自分の場所」で描くので、矩形領域で衝突判定するのは合理的
共同編集Undoは運用で回避が大事

領域の衝突判定は総当たりで十分
CRDTならサーバに送信したあとでもundoできる?

関係ありそうだけど、英語だからちゃんと中身見れてない... なURL

automergeの5000倍早い実装を書いたと書いてある
diamond-types からリンクされている
> The Braid Protocol is an extension to HTTP that generalizes it from a state transfer to a state synchronization protocol.
> Braid adds these features to HTTP:
> 1. Versioning to HTTP resources
> 2. Subscriptions to GET requests
> 3. Patches to Range Requests
> 4. Merge-Types to specify OT or CRDT behavior
Undo+Redoの永続化
下位互換がとても辛そう


成果物そのものに対するマイグレーション処理と同じように、コマンドに対するマイグレーション処理とかも実装しないと……(面倒)

オブジェクト選択をUndo対象にするか否か
しない派だったけどblenderがする派で意外と便利だったから鞍替えした

Blender、3Dカーソルの位置はUndo対象にならないのよね……(テキストの共同編集でもカーソルは各個人が持ってるのを見ながら)
選択は個々人の状態なので共同編集と組み合わせるのは難しいかもしれない
Figmaがする派だけど、場合によってはCtrl+Zを何回も押さないと戻せないのが大変…

グループ内の要素を選択するために何度もクリックして選択を潜っていく事があるので
RDBMSのスナップショットとトランザクションログの話も一回しっかり勉強しないとなあ……
ゲームのリプレイでも精度が確保できないから無敵にするみたいな話がTLで流れてた
作ったもの紹介コーナー
URLとスクリーンショットを張っていってください
昔作ったオンラインマインドマップの共同編集&UNDO
nodeごとのsnapshot
復帰不能な競合あるか判定して無理そうなら履歴クリア
ツリーの開閉も複数クライアントで同期されている
(中国語) あるサイトのUserScriptとして書いたテーブルエディター
snapshot式作りで(完全線形な)undoがあった
自作のお絵描きチャット"えんぴつチャット"。多人数でのUndo/Redoに対応。
領域ベースUNDOがラスタ特有という感じで面白い

差分ベースの共同編集&Undo実装

ObjectのProperty毎にクライアントでUndoを記録
ModelのPropertyが変更されるとUndo記録する仕組みを持っている
ObjectがなくなったらUndoを破棄
ドラッグなんかの連続処理は終了時にまとめてCommit
モデルのプロパティの変更を監視してそれぞれでアンドゥを構築
VS Code custom editor で undo / redo

操作が終わったタイミングでJSONを全dumpするだけの超雑実装…
extension側と相互通信
extension側にアンドゥのデータを持っておく
別tabもundoできる
Live Shareで共同編集できるかは未検証