少し先を急ぎ過ぎているのではないか?

どうも少し先を急ぎ過ぎているのではないかという気がする.危ない橋を渡っているのではないか?昨日は一度もバックアップを取らなかった.それだけ夢中になっていたのかもしれないが,壊滅的な状況になっている.昨日の修正を一度捨てて前日のバックアップまで戻るか?このまま泥沼の中を匍匐前進するか?状況はかなり悪いが,修正を少し戻して状況を観察してみることにしよう.もし,どうしてもダメなら退却するしかない.その前にいまの不良が前日版(ZELKOVA 2020-11-20)ですでに起きていたものかどうかを確認しておこう.

現在の環境設定は「_DEBUGマクロ未定義」と「FORMALVERSION」いずれもOFFのDebugモードだ.「完全被参照リスト管理を実行する」はONになっている.⇒いや,参照リスト管理そのもので障害が起きているので,これは止めておこう.⇒やはり元凶は昨日のnodl_floatの修正だ.これを戻せば取り敢えず動作する.明らかに何か読み損なっていたに違いない.ここでは現行論理は正しく現行仕様を反映していると考えるしかない.つまり,間違えていたのはこのわたしだ.

一番腑に落ちないのは,なぜこの修正が参照リスト管理にまで影響を及ぼすのか?という点だ.nodl_floatでは参照リスト管理に関わるスロットREFERISTはまったく操作していない…いずれにしても修正が間違っていたことに変わりはないのでここでは撤退以外の選択はない.一応この版はそれなりに動作しているので安定版として保全しておいた方がよいのではないか?もう少し整理を進めると整った状態になるとは思われるが,その前にまたドツボにハマる可能性もある.一旦休止して,仮修正をフィックスしておこう.いや,これは安定版と呼ぶにはほど遠い.画面はすでに表示されているが,停止している.非参照カウントの残留などが無数に出てくる.⇒この障害は前日版でも起きている.

▲ZTシステム構成図7.ZELを基準ノード=202 NODULEで開いて終了のとき,被参照カウントの残留と残留参照元を検出が多発する 

NAMEBOX #1828への参照として,#1819NAMEBOX[22]と#15158GENEBOX[18]が残っている.NAMEBOX[22]はNAMEsSAMEGENE:samegene 同一世代人名枠チェーン次ノード人名枠への参照,GENEBOX[18]はGENEBOXsBOTTOM:bottom1  同一世代人名枠チェーン末尾人名枠への参照だ.おそらくこのノードはsamegeneチェーンの末尾ノードなのだろう.この世代枠が特定できて,かつこのチェーンが壊れていなければチェーンをたぐることで始末することができる.この世代枠はどこが管理しているのだろう?

系列枠だろうか?⇒このノードのsamegeneはすでに空になっている.この障害はTREEVIEW::EraseTreeViewで起きている.ここでは描画オブジェクトの草刈りをやっているので細かいオペラ―ションはまったく無視されているはずだ.しかし,個別ノードがデストラクタで正しく対応していれば,それ(秩序だった解体)も不可能ではないはずなのだが… 少なくともNAMEBOX::Disposeではそれらしきことをやっていないので,まずそれを組み込んでみることにする.

samegeneは処理されず,デストラクタ出口のCleanSlotでクリアされている.NAMEBOX::CleanSansyoにはsamegeneをクリアしているところはあるが,チェーン管理はしていない.GENEBOX::CleanSansyoでは始末を付けている.同一世代人名枠チェーンは基本世代枠リストが管理している.baselistはTOPOLOGYの所有でTRIBELISTが管理している.TRIBELIST::CleanSansyoは実行されてはいるが,NAMEBOXに関しては何もやっていない.いや,やっている.実際この中でGENEBOX:CleanSansyoが実行されている.

このノード#1828が関係する世代枠は#15158だが,GENEBOX:CleanSansyoでは人名枠の世代から割り出した#15182が検査対象となり,ヒットしないため素通りになっている.⇒いや,この処理はDisposeの中でも実行されている.getSameGeneBoxで世代枠を取り出している.どこかで世代枠の付け替えが発生しているように思われる.問題ノードのデストラクタではすでにsamegeneは空になっている.どこかで強制的に参照解除してしまったのだろう.これは参照クリアをやっているところでチェーンを維持していないために起こっているものと思われる.少なくともGENEBOXは要素の追加と削除手続きを持たなくてはならない.GENELISTにはAddSameChainという関数がある.RemoveSameChainを追加しておこう.

どうも世代関係で間違えているようだ.世代枠リストをダンプしようとすると,GENEBOX::getLocationでエラーが発生する.いや,これは検査のロジック的間違いだ.というか,TRIBEBOX::getPotentialが間違っているのではないか?始系列の場合はつねに0を返しているが,どう考えてもこれはおかしい.また,KeitoMinとPotentialはつねに同じ絶対値を持つことになっているのでどちらかに統一してもよいのではないか?以下のように定義されているのだが…

Potential 基準ノードの物理世代番号,potential 優先ノードの常用世代番号=優先ノードと基準ノードの世代差

Potentialは(系統内の)すべての系列で共通なのだから,同じ値が返されなくてはおかしい.TRIBEBOX::getPotentialで「場合分けしない@20180912」というコメントが付いているのは,このことではないだろうか?もしかすると仮修正をフィックスする段階で誤って逆の論理を残してしまった可能性もある.しかし,ここをいじると,動かなくなる.⇒暫定的にGENEBOX::getLocationの検査ブロックだけを外して走らせるようにした.これで見ると,GENEBOX#15158の常用世代番号は-6ということになる.NAMEBOX#1828の世代は-4とされるので,合っていない.どちらが悪いのか?#1828はCARDTABLE(0) だ.

どうも訳が分からなくなってきた.基本世代枠リストには13世代分の世代枠が登録されているが,実際の図面では9世代しかない.基準ノードの位置は物理世代番号では4に当たる.この意味でCARDTABLE(0)の世代が-4というのは間違っていない.物理世代番号で0~3までの4世代のGENEBOXは空,最下層の12世代も同世代人名枠ゼロになっている.描画上の問題は起きていないので,このような状態でも描画は可能であるようだが,どこで調整しているのだろう?人名枠のgetGenerationは正しい値を返しているようなので,世代枠の世代取得関数が間違っているかないし古いのではないかと思われる.

image

基本世代枠にはノード対リストがリンクされているはずなので,内容をチェックしてみよう.ノード対リストの世代番号もダンプされる世代枠の番号とまったく同じだ.というか,多分ノード対リストは所属する世代枠から世代番号を取得しているのではないかと思う.中身が空の世代枠が存在することはやむを得ないとしても,同世代人名枠の人数と画面に表示された人名枠の個数が合っていない.

同世代人名枠数M≧表示されているカード数Nであるとすると,まず,Mがゼロの世代が5つ,ゼロでない世代が8に対し,実際の画面では9世代にカードが表示されている.カード数を上から拾うと,

N=4, 4, 15, 21, 24, 11, 6, 6 となる.一方ダンプでは,ゼロの世代を除いてM=2, 3, 9, 20, 15, 9, 5, 4 のようになってまったく一致しない,というか,表示されているカードより同世代人名数の方が少ないというのが理解できない.画面上に表示されているカードは重複を除いて80だ.Mの合計は67,Nの合計は91.多重が11あるのでそれを引くと80となり,表示されているカード数と一致する.ただし,コンソールには多重14という数字が出ている.この数字にも疑問がある.画面上のカードに世代番号を表示してみよう.

基準ノードの世代番号は-2,物理世代番号は4と表示されている.CARDTABLE(0)では世代番号-6,物理世代番号0でこれらの値は(それなりに)正しい.つまり,getLocationは画面上の物理世代番号を返し,getGenerationは基本世代枠リストと一致する(常用)世代番号を返している.どこで不一致が生じているのか?基本的には動作しているので,一部の世代関数のバージョンが古いことが考えられる…

原因は分かった.系列枠がすでにパージされてしまっているからだ.TREEVIEW::EraseTreeViewは描画要素を根こそぎ刈り倒して更地にしてしまうので,系列枠が存続していることを期待できない.系列枠が存在しないと基準ノードと系列優先ノードの世代差(ポテンシャル)が分からなくなってしまうためだ.物理世代番号を使うことはできないのだろうか?getLocationは最初にgetGenerationで常用世代番号を取得したあと,GEN2DEVで物理世代番号に変換しているだけだ.

すでに「解体モード」に入っているため秩序正しく分解してゆくのが難しいことは分かる.しかし,ここまで来た以上そこまでやってしまいたい…常用世代番号ないし物理世代番号をどこかに格納しておけば,それを取り出すだけになる.Bobject::COORDINATEには2という値が入っている.ABSOLUTEが1でRELATIVEが2だ.TREEVIEW:EraseTreeViewの冒頭,草刈りの前に値を切り替えている.

これを遅延させて,更地になってから切り替えるようにすることはできるだろう.絶対座標系への転換のタイミングですべての世代計算を「絶対世代番号」に切り替えればよいのではないだろうか?それしか方法はないと思う.Bobjectクラスは描画要素の一般クラスなので世代関係のパラメータは一切持っていない.世代が関係するのはNAMEBOX, MARGBOX, GENEBOX, PAIRBOXなどだが,すべてBobjectの派生クラスなのでBobjectにgenerationというメンバーを追加してやるのが早そうだ.それしかないのではないだろうか?BobjectにGetGenerationという仮想関数を追加し,変換時にはこれを使って各クラスオブジェクトの値を取り出したあと,絶対座標系に切り替えればよい.

絶対座標系に切り替わったあとは,個別の世代関数はGetGenerationを呼び出して格納した値を取り出すという段取りになる.つまり,GetGenerationという関数は座標系モードに従って,値の取り出し方を切り替えるという関数だ.一度バックアップを取ってから始めることにしよう.修正はそれほど大掛かりなものにはならないと思う.絶対世代番号という用語はすでに使われている.なんと呼べばよいか?暫定的に確定世代番号としてみよう.GetGenerationの設置を義務付けるためにBobjectでは純粋仮想関数としておくことにする.⇒常用世代番号を使うつもりだったが,一つ問題が出てきた.

PAIRBOXは物理世代番号しか使っていない.物理世代番号に切り替えるのは難しくないが,ほとんどの場面では常用世代番号を使っている.これをすべて物理世代番号に切り替えるというのもかなり大変だ.物理世代番号 = 常用世代番号+系統ポテンシャル という関係なのでもう一つ系統ポテンシャルという値が必要になる.系統ポテンシャルは系統ごとに異なるので一つだけ保持するという訳にはゆかない.⇒物理世代番号というのがもっとも合理的かつおそらくそれしかないと思われるが,書き換えが大変だ.ともかくそれをやってみよう.

仮想関数GetGenerationをBobjectのすべての派生クラスに配置するまでは簡単にできた.物理世代番号の取得はBobject::setabsoluteに次の1行を追加するだけだ.

_generation = GetGeneration(); // 物理世代番号を取得して保存

座標系の切り替えは以下のポイントで実施している.

  1. TREEVIEW::InitTreeView → RELATIVE
  2. COUPLING::EraseFamilyTree → RELATIVE
  3. TREEVIEW::EraseTreeView → RELATIVE
  4. COUPLING::InitLinkTable → RELATIVE
  5. COUPLING::TopologicalSort
  6. Bobject::MakeAbsolute → RELATIVE → ABSOLUTE

MARGBOX::getGenerationで停止した. (PHASE > GODOWNSTREAM)では「系列枠不在」という理由で止まった.つまり,この結婚枠は系列枠に所属していない.なぜこのようなものがあるのだろう?なんとこの結婚枠はCOUPLINGに直接接続している!(結婚枠は通常結婚リンクに接続している)隠蔽リストに乗っているようにも見えるが,hideflagはゼロ.YリストではTREEVIEWに直接接続している.Yが4という値を持っているので,隠蔽リスト上にあることは間違いない.ゴミと見て間違いないが,なぜこんなものがこんなところにあるのか?は追求されなくてはならない.

さて,ここまではできたが,その後が…

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA