「終点がgoodsonのノード対は最大区間を除き端点共有不可」という規則がある.goodsonというのは子ども枠の中で親の結婚点から下りる垂線の直下にある人名枠,つまり結婚枠の吊り位置に当たるノードだ.「終点がgoodsonのノード対」では連結線の終端がこの垂線上にあるため,端点共有すると共有連結線が垂線を横断する形になって,誤読の可能性が高くなる.上の規則はそれを防止するための対策だが,「最大区間を除き」という条件があるために判定が結構厄介なものになっている.端点共有束全体を「最大区間」の連結線を持つ1個のノード対とみなすことでこの図式はかなりわかり易くなる.
実際,一部ではそのように扱っているところもあるはずだが,それを徹底すれば共有端点ノード対と一般のノード対が一つのチャンネルを共用するということも可能になるはずだ.これは多少なりともチャンネル数の削減に効果があると考えられるので実装したいと思うが,ここでは一旦保留して先に進むことにする※.現在確認されている障害は「一時的にSTOPを抑制する@20201028」で止めてあったものだが.このオプションをフィックスする時点で再考することにする.
※勘違いしている.現状でもそうなっている.
以下のコンパイルオプションを現状でフィックスする.
- DEBUG:一時的にCheckSamePointをパス@20201206 1箇所
- 増設スロットの繋ぎ変えはnodl_floatに@20201205 1箇所
- ノード対削除後に端点共有束を調整しない 2箇所
- 長さゼロのノード対は端点共有対象としない 2箇所
さて,いよいよPAIRLIST::Removeを廃止するときが来た.それをやるとどんないいことあるの,だって?もちろんあるよ.これをやると少なくともリストクラスに関しては削除に関する操作が完全に統合されたことになる.つまり,いつでもどこでもdeleteするだけでオブジェクトを削除できるようになる.必要なのはdeleteElementとdataCountDownという2つの関数を整備するだけだ.つまり,オブジェクト削除というクリティカルな操作の完全な一般化が実現したということになる.⇒PAIRLIST::Removeは9箇所から参照されている.⇒修正完了した.
端点共有では増設スロット(EXTRASLOT)を使って接続チェーンを構成している.EXTRASLOTはMARGBOXでも「SymmetricActionでブロック移動実行時に使われるリストを一時的に接続する」ために使われているはずだ.どういう使われ方をしているのか見ておくことにしよう.MARGBOX::SymmetricActionでは対象結婚枠のEXTRASLOTに以下のようなリストを接続している.
nlist<Bobject> *list = new (this, MARGBOXsEXTRA) nlist<Bobject>;
ただし,このオブジェクトはごく短命で,この行に続くわずか2, 3ステップで削除されてしまう.
int count1 = MoveParentGroup(treeview, tribe, list);
originate(CPoint(delta, 0));
int count2 = RestoreParentGroup(list);
delete list;
MoveParentGroupはBobjectの関数で「該ノードを親参照している外部系列ノードの親参照を付け替える」ということをやっているらしい.RestoreParentGroupはその逆操作だ.通常あるオブジェクトを移動すると,そのオブジェクトを「親参照」している描画要素はすべて移動することになるが,ここでは外部系列内描画要素に影響を与えない方法で単体移動※しようとしているものと解される.nlistのリスト要素はREFLINKでそこからオブジェクトを間接参照するようになっているので,このリストの構築は既存システム要素の構成には影響しない.※⇒系列内の下流ノードは結婚枠とともに移動する.
MARGBOXはPAIRBOXの端点共有のシナリオにはまったく登場しないので,EXTRASLOTの取り合いのようなことは起こらないと考えてよいだろう.また,このnlist<Bobject>のEXTRASLOTやスロットゼロには何も接続されていないから,このリストの削除も単純な単体オブジェクトの削除として完結する.nodule.hの「増設スロットの使用例」という説明では「SymmetricActionでブロック移動実行時に使われるリストを一時的に接続する」と解説している.
2020/12/03のログには懸案事項として9件をリストアップしている.うち,(1)OnListremove,removingを廃止,(3)dataCountDownの一般化,blackflagの廃止,(4)nodl_floatを終了処理に含める,(9)ReferenceList(参照チェックリスト)の廃止の4項目は大体終わっているので,(2)CallSetCouplingPtrを始末する,終末期のフェーズというのを見てみることにしよう.いや,その前に「PAIRLIST:Removeを廃止する@20201207」をフィックスしてしまおう.このオプションは13箇所に出てくる.⇒対処した.ここで一度バックアップを取っておく.
実際のところ,「CallSetCouplingPtrの始末」はほとんど付いている.アプリ終了でCallSetCouplingPtrの入口に入った時点でアクティブなオブジェクトは32個しか残っていない.メモリ上の不定サイズオブジェクトを管理するfreeblockにもオブジェクトは残っていない.ゴミ箱には10,008個の廃棄オブジェクトが入っているが,ThrowCanを呼べば空っぽにできる.この状態はファイルをクローズして新規ファイルをオープンする前の状態に等しい.⇒実際そうなっていることを確認してみよう.いや,その前にまだカウントが少し合っていないところがある.
NODEREFLISTは1366個生成されているが,ゴミ箱には1363個しか入っていない.Nringの中には見当たらないので,3個紛失してしまっている.また,ゴミ箱に入っているfreeblockが42個しかないというのも解せない.freeblockはトータルで10,040個も使われているのでいくらリサイクルされているとは言っても少な過ぎるような気がする.
いや,ちょっと勘違いしている.10,040というのは生成されたすべてのオブジェクトの総数だ.このサンプルには画像などは全く含まれていないので,freeblockオブジェクト数が32というのは妥当な数だ.参照リスト生成数とゴミ箱の中の個数が一致しないのはリサイクルされているからではないか?⇒確かにそのようだ.3個リサイクルされている.しかし,これらはいつゴミ箱に入ったのだろう?リサイクルされているNODEREFLISTのSNUMは#15, #11, #9といずれも若い番号だ.
アプリを起動した後,最初にCloseFamilyBaseの中で以下の3つのNODEREFLISTが削除されている.①TITLELINK ,②TREEVIEW,③TITLEBOX .いずれのオブジェクトも参照されていない.しかし,参照リストが生成されているということは,そこに来るまでの間にはどこかから参照されていたのだろう.アプリではファイルをオープンする前に必ずクローズを実行しているため,一度も使われていない状態でもCloseFamilyBaseが掛かってくる場合がある.
このタイミングで③TITLEBOXが存在するというのはかなり疑問だ.①TITLELINK と②TREEVIEWはコアシステムに含まれるので,これらが存在すること自体は正当だが,参照が存在するということは何かしらアクティブな動作が発生したことを意味するのでやや疑問だ.フェーズの境界がかなりあいまいになっているので,少し整理してみよう.
- GROUNDZERO 0: 更地 アプリ開始時→ゴミ箱/コア系図木の構築
- INITIALSTATE 1: 初期状態/ファイルクローズ状態 ファイルのオープン→データベースへの接続
- INITIALIZING 2: 初期化処理中/系図木の変化→系図データのロード
- INITIALIZED 3: 初期化完了
- TOPOLOGICALSORT 4: 系統並び替えの開始
- CLEARTABLE 5: 個人/結婚リンクテーブル初期化
︙ - DRAWSTAGE 28: 系図木描画準備完了
- ENDOFAPPLICATION -1: アプリケーションの終了
- CHAOTICSTATE = INITIALIZED 初期化中/UNDO処理中フェーズではエラーを無視