Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

アウトライン解析ウィンドウのツリービューの設定処理の高速化 #1648

Merged
merged 3 commits into from
May 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 44 additions & 41 deletions sakura_core/outline/CDlgFuncList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,58 +425,58 @@ void CDlgFuncList::SetData()
m_bDummyLParamMode = false;
m_vecDummylParams.clear();

//2002.02.08 hor 隠しといてアイテム削除→あとで表示
::ShowWindow( hwndList, SW_HIDE );
::ShowWindow( hwndTree, SW_HIDE );
::SendMessage(hwndList, WM_SETREDRAW, (WPARAM)FALSE, 0);
::SendMessage(hwndTree, WM_SETREDRAW, (WPARAM)FALSE, 0);
ListView_DeleteAllItems( hwndList );
TreeView_DeleteAllItems( hwndTree );
::ShowWindow( GetItemHwnd(IDC_BUTTON_SETTING), SW_HIDE );
const HTREEITEM hInsertAfter = (m_nSortType == SORTTYPE_DEFAULT_DESC) ? TVI_FIRST : TVI_LAST;

SetDocLineFuncList();
if( OUTLINE_C_CPP == m_nListType || OUTLINE_CPP == m_nListType ){ /* C++メソッドリスト */
m_nViewType = VIEWTYPE_TREE;
SetTreeJava( GetHwnd(), TRUE ); // Jan. 04, 2002 genta Java Method Treeに統合
SetTreeJava( GetHwnd(), hInsertAfter, TRUE ); // Jan. 04, 2002 genta Java Method Treeに統合
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

結局、引数を増やすんです?

「引数を渡さないのは非効率なのは自明」だけど、実害は出てないと理解しました。

紛らわしいので引数追加はrevert(と同じになるようにコミットを積む)が良さそうに思います。

目下、自分が気にしているのはあとココだけです。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

引数を増やさないで同じ処理を行うとなると下記の手段が考えられます。

  1. CDlgFuncList クラスにメンバー変数 HTREEITEM m_hInsertAfter を追加してそれ経由で情報を渡す
  2. SetTreeSetTreeJavam_nSortType の値を元に hInsertAfter ローカル変数を初期化する記述を重複して書く

関連する実装について説明します。

hInsertAfter 引数は SetTreeSetTreeJava の中で呼び出す TreeView_InsertItem マクロの第2引数に渡される TV_INSERTSTRUCT 構造体の hInsertAfter メンバーに設定しています。

元の実装では SetTree では TVI_FIRSTTV_INSERTSTRUCT::hInsertAfter に設定されていました。そして SetTreeJava では TVI_LASTTV_INSERTSTRUCT::hInsertAfter に設定されていました。

このPRの実装では m_nSortType の値によって TVI_FIRSTTVI_LAST のどちらを設定するかを変える事で、後で SortTree の呼び出しを省けようにしています。なお SortTree の呼び出しを省いているのは順序が デフォルトデフォルト(降順) の場合のみです。それらについてはツリービューへの追加順序を調整すれば後でソートしないでも問題ないだろうと判断しました。

https://docs.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tvinsertstructa

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ちょっと分からなかったのですが「PRの実現に必要な変更」なのであれば、そう言って貰えれば良いです。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

どちらかというと必要な変更だと思ってます。こうする事で SortTree の呼び出しを省いて高速化できるので。

::SetWindowText( GetHwnd(), LS(STR_DLGFNCLST_TITLE_CPP) );
}
else if( OUTLINE_FILE == m_nListType ){ //@@@ 2002.04.01 YAZAKI アウトライン解析にルールファイル導入
m_nViewType = VIEWTYPE_TREE;
SetTree();
SetTree(hInsertAfter);
::SetWindowText( GetHwnd(), LS(STR_DLGFNCLST_TITLE_RULE) );
}
else if( OUTLINE_WZTXT == m_nListType ){ //@@@ 2003.05.20 zenryaku 階層付テキストアウトライン解析
m_nViewType = VIEWTYPE_TREE;
SetTree();
SetTree(hInsertAfter);
::SetWindowText( GetHwnd(), LS(STR_DLGFNCLST_TITLE_WZ) ); // 2003.06.22 Moca 名前変更
}
else if( OUTLINE_HTML == m_nListType ){ //@@@ 2003.05.20 zenryaku HTMLアウトライン解析
m_nViewType = VIEWTYPE_TREE;
SetTree();
SetTree(hInsertAfter);
::SetWindowText( GetHwnd(), L"HTML" );
}
else if( OUTLINE_TEX == m_nListType ){ //@@@ 2003.07.20 naoh TeXアウトライン解析
m_nViewType = VIEWTYPE_TREE;
SetTree();
SetTree(hInsertAfter);
::SetWindowText( GetHwnd(), L"TeX" );
}
else if( OUTLINE_TEXT == m_nListType ){ /* テキスト・トピックリスト */
m_nViewType = VIEWTYPE_TREE;
SetTree(); //@@@ 2002.04.01 YAZAKI テキストトピックツリーも、汎用SetTreeを呼ぶように変更。
SetTree(hInsertAfter); //@@@ 2002.04.01 YAZAKI テキストトピックツリーも、汎用SetTreeを呼ぶように変更。
::SetWindowText( GetHwnd(), LS(STR_DLGFNCLST_TITLE_TEXT) );
}
else if( OUTLINE_JAVA == m_nListType ){ /* Javaメソッドツリー */
m_nViewType = VIEWTYPE_TREE;
SetTreeJava( GetHwnd(), TRUE );
SetTreeJava( GetHwnd(), hInsertAfter, TRUE );
::SetWindowText( GetHwnd(), LS(STR_DLGFNCLST_TITLE_JAVA) );
}
// 2007.02.08 genta Python追加
else if( OUTLINE_PYTHON == m_nListType ){ /* Python メソッドツリー */
m_nViewType = VIEWTYPE_TREE;
SetTree( true );
SetTree( hInsertAfter, true );
::SetWindowText( GetHwnd(), LS(STR_DLGFNCLST_TITLE_PYTHON) );
}
else if( OUTLINE_COBOL == m_nListType ){ /* COBOL アウトライン */
m_nViewType = VIEWTYPE_TREE;
SetTreeJava( GetHwnd(), FALSE );
SetTreeJava( GetHwnd(), hInsertAfter, FALSE );
::SetWindowText( GetHwnd(), LS(STR_DLGFNCLST_TITLE_COBOL) );
}
else if( OUTLINE_VB == m_nListType ){ /* VisualBasic アウトライン */
Expand All @@ -486,7 +486,7 @@ void CDlgFuncList::SetData()
}
else if( OUTLINE_XML == m_nListType ){ // XMLツリー
m_nViewType = VIEWTYPE_TREE;
SetTree();
SetTree(hInsertAfter);
::SetWindowText( GetHwnd(), L"XML" );
}
else if ( OUTLINE_FILETREE == m_nListType ){
Expand All @@ -496,17 +496,17 @@ void CDlgFuncList::SetData()
}
else if( OUTLINE_TREE == m_nListType ){ /* 汎用ツリー */
m_nViewType = VIEWTYPE_TREE;
SetTree();
SetTree(hInsertAfter);
::SetWindowText( GetHwnd(), L"" );
}
else if( OUTLINE_TREE_TAGJUMP == m_nListType ){ /* 汎用ツリー(タグジャンプ付き) */
m_nViewType = VIEWTYPE_TREE;
SetTree( true );
SetTree( hInsertAfter, true );
::SetWindowText( GetHwnd(), L"" );
}
else if( OUTLINE_CLSTREE == m_nListType ){ /* 汎用クラスツリー */
m_nViewType = VIEWTYPE_TREE;
SetTreeJava( GetHwnd(), TRUE );
SetTreeJava( GetHwnd(), hInsertAfter, TRUE );
::SetWindowText( GetHwnd(), L"" );
}
else{
Expand Down Expand Up @@ -674,12 +674,6 @@ void CDlgFuncList::SetData()
ListView_SetExtendedListViewStyle( hwndList, dwExStyle );
}

// 選択状態更新
int nFuncInfoIndex = -1;
if( GetFuncInfoIndex( m_nCurLine, m_nCurCol, &nFuncInfoIndex ) ){
SetItemSelection( nFuncInfoIndex, true );
}

/* アウトライン ダイアログを自動的に閉じる */
::CheckDlgButton( GetHwnd(), IDC_CHECK_bAutoCloseDlgFuncList, m_pShareData->m_Common.m_sOutline.m_bAutoCloseDlgFuncList );
/* アウトライン ブックマーク一覧で空行を無視する */
Expand All @@ -700,13 +694,6 @@ void CDlgFuncList::SetData()
::EnableWindow( GetItemHwnd( IDC_CHECK_bFunclistSetFocusOnJump ), TRUE );
}

//2002.02.08 hor
//(IDC_LIST_FLもIDC_TREE_FLも常に存在していて、m_nViewTypeによって、どちらを表示するかを選んでいる)
HWND hwndShow = (VIEWTYPE_LIST == m_nViewType)? hwndList: hwndTree;
::ShowWindow( hwndShow, SW_SHOW );
if( ::GetForegroundWindow() == MyGetAncestor( GetHwnd(), GA_ROOT ) && IsChild( GetHwnd(), GetFocus()) )
::SetFocus( hwndShow );

//2002.02.08 hor
//空行をどう扱うかのチェックボックスはブックマーク一覧のときだけ表示する
if(OUTLINE_BOOKMARK == m_nListType){
Expand Down Expand Up @@ -743,8 +730,8 @@ void CDlgFuncList::SetData()
Combo_AddString( hWnd_Combo_Sort , LS(STR_DLGFNCLST_SORTTYPE2_2)); // SORTTYPE_ZTOA
Combo_SetCurSel( hWnd_Combo_Sort , m_nSortType );
::ShowWindow( GetItemHwnd( IDC_STATIC_nSortType ), SW_SHOW );
// 2002.11.10 Moca 追加 ソートする
SortTree(GetItemHwnd( IDC_TREE_FL),TVI_ROOT);
if (m_nSortType != SORTTYPE_DEFAULT && m_nSortType != SORTTYPE_DEFAULT_DESC)
SortTree(hwndTree, TVI_ROOT);
}else if( m_nListType == OUTLINE_FILETREE ){
::ShowWindow( GetItemHwnd(IDC_COMBO_nSortType), SW_HIDE );
::ShowWindow( GetItemHwnd(IDC_STATIC_nSortType), SW_HIDE );
Expand All @@ -756,6 +743,22 @@ void CDlgFuncList::SetData()
//ListView_SortItems( hwndList, CompareFunc_Asc, (LPARAM)this ); // 2005.04.05 zenryaku ソート状態を保持
SortListView( hwndList, m_nSortCol ); // 2005.04.23 genta 関数化(ヘッダ書き換えのため)
}

//2002.02.08 hor
//(IDC_LIST_FLもIDC_TREE_FLも常に存在していて、m_nViewTypeによって、どちらを表示するかを選んでいる)
HWND hwndShow = (VIEWTYPE_LIST == m_nViewType) ? hwndList : hwndTree;
::ShowWindow(hwndTree, SW_HIDE);
::ShowWindow(hwndList, SW_HIDE);
::ShowWindow(hwndShow, SW_SHOW);
::SendMessage(hwndList, WM_SETREDRAW, (WPARAM)TRUE, 0);
::SendMessage(hwndTree, WM_SETREDRAW, (WPARAM)TRUE, 0);
// 選択状態更新
int nFuncInfoIndex = -1;
if (GetFuncInfoIndex(m_nCurLine, m_nCurCol, &nFuncInfoIndex)) {
SetItemSelection(nFuncInfoIndex, true);
}
if (::GetForegroundWindow() == MyGetAncestor(GetHwnd(), GA_ROOT) && IsChild(GetHwnd(), GetFocus()))
::SetFocus(hwndShow);
}

bool CDlgFuncList::GetTreeFileFullName(HWND hwndTree, HTREEITEM target, std::wstring* pPath, int* pnItem)
Expand Down Expand Up @@ -890,7 +893,7 @@ int CDlgFuncList::GetData( void )
@date 2002.01.04 genta C++ツリーを統合
@date 2020.09.12 選択処理をGetFuncInfoIndex,SetItemSelectionへ移動
*/
void CDlgFuncList::SetTreeJava( HWND hwndDlg, BOOL bAddClass )
void CDlgFuncList::SetTreeJava( HWND hwndDlg, HTREEITEM hInsertAfter, BOOL bAddClass )
{
int i;
const CFuncInfo* pcFuncInfo;
Expand Down Expand Up @@ -1061,7 +1064,7 @@ void CDlgFuncList::SetTreeJava( HWND hwndDlg, BOOL bAddClass )
strClassName += m_pcFuncInfoArr->GetAppendText(FL_OBJ_CLASS);
}
tvis.hParent = htiParent;
tvis.hInsertAfter = TVI_LAST;
tvis.hInsertAfter = hInsertAfter;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM;
tvis.item.pszText = const_cast<WCHAR*>(strClassName.c_str());
// 2016.03.06 item.lParamは登録順の連番に変更
Expand Down Expand Up @@ -1098,7 +1101,7 @@ void CDlgFuncList::SetTreeJava( HWND hwndDlg, BOOL bAddClass )

::ZeroMemory( &tvg, sizeof(tvg));
tvg.hParent = TVI_ROOT;
tvg.hInsertAfter = TVI_LAST;
tvg.hInsertAfter = hInsertAfter;
tvg.item.mask = TVIF_TEXT | TVIF_PARAM;
//tvg.item.pszText = const_cast<WCHAR*>(L"グローバル");
tvg.item.pszText = const_cast<WCHAR*>(sGlobal.c_str());
Expand All @@ -1125,7 +1128,7 @@ void CDlgFuncList::SetTreeJava( HWND hwndDlg, BOOL bAddClass )

/* 該当クラス名のアイテムの子として、メソッドのアイテムを登録 */
tvis.hParent = htiClass;
tvis.hInsertAfter = TVI_LAST;
tvis.hInsertAfter = hInsertAfter;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM;
tvis.item.pszText = const_cast<WCHAR*>(strFuncName.c_str());
tvis.item.lParam = nlParamCount;
Expand Down Expand Up @@ -1379,7 +1382,7 @@ void CDlgFuncList::SetListVB (void)
@date 2014.06.06 Moca 他ファイルへのタグジャンプ機能を追加
@date 2020.09.12 選択処理をGetFuncInfoIndex,SetItemSelectionへ移動
*/
void CDlgFuncList::SetTree(bool tagjump, bool nolabel)
void CDlgFuncList::SetTree(HTREEITEM hInsertAfter, bool tagjump, bool nolabel)
{
HWND hwndTree = GetItemHwnd( IDC_TREE_FL );

Expand Down Expand Up @@ -1418,8 +1421,7 @@ void CDlgFuncList::SetTree(bool tagjump, bool nolabel)
HTREEITEM hItem;
TV_INSERTSTRUCT cTVInsertStruct;
cTVInsertStruct.hParent = phParentStack[ nStackPointer ];
// 2016.04.24 TVI_LASTは要素数が多いとすごく遅い。TVI_FIRSTを使い後でソートしなおす
cTVInsertStruct.hInsertAfter = TVI_FIRST;
cTVInsertStruct.hInsertAfter = hInsertAfter;
cTVInsertStruct.item.mask = TVIF_TEXT | TVIF_PARAM;
cTVInsertStruct.item.pszText = pcFuncInfo->m_cmemFuncName.GetStringPtr();
cTVInsertStruct.item.lParam = i; // あとでこの数値(=m_pcFuncInfoArrの何番目のアイテムか)を見て、目的地にジャンプするぜ!!。
Expand Down Expand Up @@ -2342,7 +2344,10 @@ BOOL CDlgFuncList::OnCbnSelEndOk( HWND hwndCtl, int wID )
type->m_nOutlineSortType = m_nSortType;
SetTypeConfig( CTypeConfig(m_nDocType), *type );
delete type;
SortTree(GetItemHwnd(IDC_TREE_FL),TVI_ROOT);
HWND hWndTree = GetItemHwnd(IDC_TREE_FL);
::SendMessageAny(hWndTree, WM_SETREDRAW, (WPARAM)FALSE, 0);
SortTree(hWndTree,TVI_ROOT);
::SendMessageAny(hWndTree, WM_SETREDRAW, (WPARAM)TRUE, 0);
}
return TRUE;
}
Expand Down Expand Up @@ -2404,9 +2409,7 @@ void CDlgFuncList::SortTree(HWND hWndTree,HTREEITEM htiParent)
size = m_nTreeItemCount;
}
data.m_vecText.resize(size);
::SendMessageAny(hWndTree, WM_SETREDRAW, (WPARAM)FALSE, 0);
SortTree_Sub(hWndTree, htiParent, data, m_nSortType);
::SendMessageAny(hWndTree, WM_SETREDRAW, (WPARAM)TRUE, 0);
}

bool CDlgFuncList::TagJumpTimer( const WCHAR* pFile, CMyPoint point, bool bCheckAutoClose )
Expand Down
4 changes: 2 additions & 2 deletions sakura_core/outline/CDlgFuncList.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ class CDlgFuncList final : public CDialog
|| 実装ヘルパ関数
*/
BOOL OnJump( bool bCheckAutoClose = true, bool bFileJump = true ); // bCheckAutoClose:「このダイアログを自動的に閉じる」をチェックするかどうか
void SetTreeJava(HWND hwndDlg, BOOL bAddClass); /* ツリーコントロールの初期化:Javaメソッドツリー */
void SetTree(bool tagjump = false, bool nolabel = false); /* ツリーコントロールの初期化:汎用品 */
void SetTreeJava(HWND hwndDlg, HTREEITEM hInsertAfter, BOOL bAddClass); /* ツリーコントロールの初期化:Javaメソッドツリー */
void SetTree(HTREEITEM hInsertAfter, bool tagjump = false, bool nolabel = false); /* ツリーコントロールの初期化:汎用品 */
void SetTreeFile(); // ツリーコントロールの初期化:ファイルツリー
void SetListVB( void ); /* リストビューコントロールの初期化:VisualBasic */ // Jul 10, 2003 little YOSHI
void SetDocLineFuncList();
Expand Down