2

クラスにクラス (ボクセル) の配列があります。次のメソッドを使用して、配列への追加と配列からの削除を行います。memento パターンは、各メソッドのアクションを保存するために使用されるため、いつでも元に戻す/やり直すことができます。

    public void AddVoxel(int x, int y, int z)
    {
        int index = z * width * height + y * width + x;

        frames[currentFrame].Voxels[index] = new Voxel();

        // Undo/Redo history
        undoRedoHistories[currentFrame].Do(new AddMemento(index));
    }

    public void RemoveVoxel(int x, int y, int z)
    {
        int index = z * width * height + y * width + x;

        // Undo/Redo history
        undoRedoHistories[currentFrame].Do(new RemoveMemento(index, frames[currentFrame].Voxels[index]));

        frames[currentFrame].Voxels[index] = null;      // Does not update 'voxelSelected' reference
    }

別のクラスで、上記のクラスが保持するボクセルの配列内の特定のボクセルへの参照が必要です。

private Voxel voxelSelected = null;

参照型として、この値が「指す」配列の部分がボクセルを保持するか、null であるかを自動的に認識できるようにしたいと考えています。これは、元に戻すコマンドを使用する場合に重要です。これは、ボクセルが配列から削除されてヌルになる、またはその逆になる可能性があるためです。

配列からボクセルを取得するには、次のメソッドを使用します。

public Voxel GetVoxel(int x, int y, int z)
{
    return frames[currentFrame].Voxels[z * width * height + y * width + x];
}

次に、ボクセルへの参照を次のように設定します。

public void SetVoxelSelected(ref Voxel voxel)
{
    voxelSelected = voxel;
}

    voxelMeshEditor.AddVoxel(0, 0, 0);

    var voxel = voxelMeshEditor.GetVoxel(0, 0, 0);  // Copies rather than references?

    SetVoxelSelected(ref voxel);

    Console.WriteLine(voxelSelected == null); // False

    voxelMeshEditor.RemoveVoxel(0, 0, 0);

    Console.WriteLine(voxelSelected == null); // False (Incorrect intended behaviour)

配列が更新されると voxelSelected 値が自動的に更新されるように、配列内のボクセルを正しく参照するにはどうすればよいですか。

4

3 に答える 3

2

配列が更新されると voxelSelected 値が自動的に更新されるように、配列内のボクセルを正しく参照するにはどうすればよいですか。

を保存するのVoxelではなく、ボクセルを取得するために必要な座標を保存します。

それ以外の

Voxel voxelSelected;
public void SetVoxelSelected(ref Voxel voxel) { voxelSelected = voxel; }

持ってる

int selectedX, selectedY, selectedZ
public void SetVoxelSelected (int x, int y, int z) { selectedX = x; ... }
public Voxel GetVoxelSelected() { return voxelMeshEditor.GetVoxel(x, y, z) }

与える

SetVoxelSelected(0, 0, 0);                     //Set selected
Console.WriteLine(GetVoxelSelected() == null); // False, CORRECT !
voxelMeshEditor.RemoveVoxel(0, 0, 0);          //REMOVE
Console.WriteLine(GetVoxelSelected() == null); // True
于 2012-10-10T12:09:51.133 に答える
1

次のラッパーを使用してみてください。

public class VoxelReference
{
    private readonly Voxel[] m_array;
    private readonly int m_index;

    public Voxel Target
    {
        get { return m_array[m_index]; }
    }

    public VoxelReference(Voxel[] array, int index)
    {
        m_array = array;
        m_index = index;
    }

    public static explicit operator Voxel(VoxelReference reference)
    {
        return reference.Target;
    }
}

そして、Voxelの代わりにVoxelReferenceのインスタンスをどこにでも渡します。次に、次の方法で使用できます。((Voxel)voxelReference)またはvoxelReference.Target

もちろん、上記のクラスをTのジェネリックに変更するか、インデックスの代わりに座標を格納することをお勧めします。

public class ArrayElementReference<T>
{
    private readonly T[] m_array;
    private readonly int m_index;

    public T Target
    {
        get { return m_array[m_index]; }
    }

    public ArrayElementReference(T[] array, int index)
    {
        m_array = array;
        m_index = index;
    }

    public static explicit operator T(ArrayElementReference<T> reference)
    {
        return reference.Target;
    }
}
于 2012-10-10T12:24:12.120 に答える
0

が型の場合 Voxelは、reference既にその型への直接参照があり、提供されたコードで提示する方法でそれを行っています。

適切なプロパティとそれに割り当てられた値のみを保持するいくつかの構造を使用Undo/Redoして、簡単に達成できることに注意してください。value typesLightweightUndo/Redo

この場合、不変性があると、物事がずっと簡単になります。

しかし、当然のことながら、これがあなたの特定のケースで便利な選択になるかどうかはわかりません.

あなたの例では:

var voxel = voxelMeshEditor.GetVoxel(0, 0, 0);  // Copy REFERENCE, and NOT value

SetVoxelSelected(ref voxel);   //Set selctede vortex reference

Console.WriteLine(voxelSelected == null); // False, CORRECT !

voxelMeshEditor.RemoveVoxel(0, 0, 0); //REMOVE

Console.WriteLine(voxelSelected == null); 
/* Selected vortex still pointing to the memroy location it was pointing before. 
   The fact is that memory location is not more in array, doesn't matter. 
   So CORRECT ! */
于 2012-10-10T11:57:08.797 に答える