Bug-org 813445 Sort out around flags of nsGUIEvent.h
初回投稿日時: 2012-12-18 23:56:01
カテゴリ: Mozilla Core Mozilla20 バグ修正
SNS:
Tweet (list)
nsEvent::flagsは、uint32_tとして定義され、ビットマスクでその意味が定義されていました。しかし、その種類は多く、また大半はその意味がどこにも書かれておらず、さらに酷いことに、一部のフラグは他でも使い回されているという有様でした。そこで、これを整理しようというのがこのバグです。
当初考えていたのは、各フラグの意味をコメントで明確にし、ビット演算することなく、ヘルパーメソッドを大量にnsEventに定義して、イージーミスを回避することだけをひとつめの目標としていました。しかし、えむけいさんの提案で、C++のビットフィールドを用いた本格的なリファクタリングになってしまいました。
まず、mozilla::widget::EventFlagsという構造体を定義し、この中に1ビットのboolメンバを持たせ、各メンバにコメントでその意味を明確に説明するように修正しました。
フラグの参照側はbool変数をテストするだけですので、ビット演算によるイージーミスは無くなります(現に、修正中にイージーミスをひとつ発見しました)。
次に、nsEventDispatcherが、nsEventListenerManagerに登録されているイベントリスナを呼び出すコード部分では、イベントの処理状況を示すフラグとして、NS_EVENT_FLAG_BUBBLE、NS_EVENT_FLAG_CAPTURE、NS_EVENT_FLAG_SYSTEM_EVENTをメソッドのパラメータにセットし、フェイズやイベントグループをnsEventListenerManager側で判断できるようにしていました。しかし、これらの状態をそもそもnsEvent::mFlagsに持っていますので、nsEventListenerManagerがこれを参照するようにすることで、nsEventDispatcherまわりの単純化に成功しています。
さらに、nsEventListenerManagerにイベントリスナを登録する際にリスナの情報を指定する際に、そしてnsEventListenerManagerがこれを保存するのに、NS_EVENT_FLAG_BUBBLE、NS_EVENT_FLAG_CAPTURE、NS_EVENT_FLAG_SYSTEM_EVENT、NS_PRIV_EVENT_UNTRUSTED_PERMITTED、NS_PRIV_EVENT_FLAG_SCRIPTが利用されていましたが、mozilla::dom::EventListenerFlagsという、ビットフィールドを利用した構造体を利用することで、nsGUIEvent.hからも、nsEventからも独立した情報として処理するように修正しました。
ただ、GCCではビットマスクによる実装よりも、ビットフィールドによる実装の方が若干遅い様で、極端なベンチマークを行うと、パッチ適用後はパフォーマンスが落ちていました。VCでは逆に若干の高速化が見られたのですが。ただ、どちらにしろ、Tpテストでは検出できない程度の話ですので、そのまま投入されています。