リファクタリングーイベント追加
まず考えるべきことは、「変更前の値」の情報をどこで発生させるかです。これについては、素直に考えるとレジスタの値を変更する瞬間がよいでしょう。RegisterValueChangedイベントで行います。今回に限らず、変更前の値と変更後の値が取得できれば便利です。変更前の値をこのイベントで外部に通知するためには、まずRegisterValueChangedEventArgsクラスをこれから掲載するコードへ変更します。
Public Class RegisterValueChangedEventArgs Inherits EventArgs 'どのレジスタの値が変更されたのか表します Private m_name As RegisterName Public Property Name() As RegisterName Get Return m_name End Get Set(ByVal value As RegisterName) m_name = value End Set End Property '現在どのビット数の値を扱っているのかわかった方がいいです Private m_bit As Byte Public Property BitCount() As Byte Get Return m_bit End Get Set(ByVal value As Byte) m_bit = value End Set End Property '更新を容易にするための情報 Private m_gruop As RegisterGruop Public Property Gruop() As RegisterGruop Get Return Me.m_gruop End Get Set(ByVal value As RegisterGruop) Me.m_gruop = value End Set End Property '変更後の値 Private m_after As Register Public Property AfterValue() As Register Get Return m_after End Get Set(ByVal value As Register) m_after = value End Set End Property '変更前の値 Private m_before As Register Public Property BeforeValue() As Register Get Return m_before End Get Set(ByVal value As Register) m_before = value End Set End Property '値が変更されたレジスタの名前、レジスタのビット数、値を指定してインスタンスを生成します。 Sub New(ByVal group As RegisterGruop, ByVal target As RegisterName, ByVal bitCount As Byte, ByVal after As Register, ByVal befor As Register) Me.m_gruop = group Me.m_name = target Me.m_bit = bitCount Me.m_after = after Me.m_before = befor End Sub End Class
このコードをコーディング後、[ソリューションのリビルド]を実行して下さい。すると、エラーが6個表示されます。このエラー情報をもとにリファクタリングを進めます。
'Public Sub New(group As RegisterGruop, target As RegisterName, bitCount As Byte, after As Register, befor As Register)' のパラメータ 'befor' に対して引数が指定されていません。 'Value' は 'VirtualCPU.RegisterValueChangedEventArgs' のメンバではありません。
簡単なほうから解決します。Valueについてエラーが表示された原因は、RegisterValueChangedEventArgsクラスのAfterValueプロパティに名前が変更されたからです。原因が分かれば対処は簡単です。ValueをAfterValueに変更して下さい。これでエラーは後一つになるはずです。
最後の引数のエラーはRegisterValueChangedEventArgsクラスのコンストラクタの引数が増えたことが原因です。変更前の数値が指定できるように下記の実装例を参考に変更して下さい。
'レジスタの値が変更されたことを通知する Private Sub OnRegisterValueChanged(ByVal gruop As RegisterGruop, _ ByVal name As RegisterName, ByVal bitCount As Byte, _ ByVal aftor As Register, ByVal befor As Register) Dim e As RegisterValueChangedEventArgs = New RegisterValueChangedEventArgs(gruop, name, bitCount, aftor, befor) RaiseEvent RegisterValueChanged(Me, e) End Sub
これで最後のエラーは解決しました。[ソリューションのリビルド]を実行して下さい。すると新たなエラーが16個も表示されるはずです。これは、各レジスタ系プロパティのSetメソッド内で、変更前の値をイベント用メソッドに渡していないのが原因です。このエラーの解決も簡単です。筆者の実装例を参考に修正して下さい。
Public Property EAX() As UInteger Get Return Me.m_eax.ValueU32 End Get Private Set(ByVal value As UInteger) Dim tmp As Register = Me.m_eax Me.m_eax.ValueU32 = value Me.OnRegisterValueChanged(RegisterGruop.A, RegisterName.EAX, 32, Me.m_eax, tmp) End Set End Property
このプログラムがしていることは、変更する前に現在値を退避しておき、それをイベント用メソッドに渡しています。こうすることにより、変更前の値と変更後の値をメソッドに渡せます。 この要領で全てのレジスタプロパティを修正して下さい。これでエラーが出なくなります。
