using System;
using System.Collections.Generic;
using Substrate.Core;
using Substrate.NBT;
namespace Substrate
{
///
/// Functions for reading and modifying a bounded-size collection of Alpha-compatible block data.
///
/// An is a wrapper around existing pieces of data. Although it
/// holds references to data, it does not "own" the data in the same way that a does. An
/// simply overlays a higher-level interface on top of existing data.
public class AlphaBlockCollection : IBoundedAlphaBlockCollection
{
private readonly int _xdim;
private readonly int _ydim;
private readonly int _zdim;
private XZYByteArray _blocks;
private XZYNibbleArray _data;
private XZYNibbleArray _blockLight;
private XZYNibbleArray _skyLight;
private ZXByteArray _heightMap;
private TagNodeList _tileEntities;
private BlockLight _lightManager;
private BlockFluid _fluidManager;
private BlockTileEntities _tileEntityManager;
private bool _dirty = false;
private bool _autoLight = true;
private bool _autoFluid = false;
public delegate AlphaBlockCollection NeighborLookupHandler (int relx, int rely, int relz);
public event NeighborLookupHandler ResolveNeighbor
{
add
{
_lightManager.ResolveNeighbor += delegate(int relx, int rely, int relz) {
return value(relx, rely, relz);
};
_fluidManager.ResolveNeighbor += delegate(int relx, int rely, int relz)
{
return value(relx, rely, relz);
};
}
remove
{
_lightManager = new BlockLight(this);
_fluidManager = new BlockFluid(this);
}
}
public event BlockCoordinateHandler TranslateCoordinates
{
add { _tileEntityManager.TranslateCoordinates += value; }
remove { _tileEntityManager.TranslateCoordinates -= value; }
}
///
/// Gets or sets a value indicating whether changes to blocks will trigger automatic lighting updates.
///
/// Automatic updates to lighting may spill into neighboring objects, if they can
/// be resolved.
public bool AutoLight
{
get { return _autoLight; }
set { _autoLight = value; }
}
///
/// Gets or sets a value indicating whether changes to blocks will trigger automatic fluid updates.
///
/// Automatic updates to fluid may cascade through neighboring objects and beyond,
/// if they can be resolved.
public bool AutoFluid
{
get { return _autoFluid; }
set { _autoFluid = value; }
}
///
/// Gets or sets a value indicating whether this needs to be saved.
///
/// If this is backed by a reference conainer type, set this property to false
/// to prevent any modifications from being saved. The next update will set this property true again, however.
public bool IsDirty
{
get { return _dirty; }
set { _dirty = value; }
}
///
/// Creates a new overlay on top of Alpha-specific units of data.
///
/// An array of Block IDs.
/// An array of data nibbles.
/// An array of block light nibbles.
/// An array of sky light nibbles.
/// An array of height map values.
/// A list of tile entities corresponding to blocks in this collection.
public AlphaBlockCollection (
XZYByteArray blocks,
XZYNibbleArray data,
XZYNibbleArray blockLight,
XZYNibbleArray skyLight,
ZXByteArray heightMap,
TagNodeList tileEntities)
{
_blocks = blocks;
_data = data;
_blockLight = blockLight;
_skyLight = skyLight;
_heightMap = heightMap;
_tileEntities = tileEntities;
_xdim = _blocks.XDim;
_ydim = _blocks.YDim;
_zdim = _blocks.ZDim;
_lightManager = new BlockLight(this);
_fluidManager = new BlockFluid(this);
_tileEntityManager = new BlockTileEntities(_blocks, _tileEntities);
}
///
/// Returns a new object from local coordinates relative to this collection.
///
/// Local X-coordinate of block.
/// Local Y-coordinate of block.
/// Local Z-coordiante of block.
/// A new object representing context-independent data of a single block.
/// Context-independent data excludes data such as lighting. object actually contain a copy
/// of the data they represent, so changes to the will not affect this container, and vice-versa.
public Block GetBlock (int x, int y, int z)
{
return new Block(this, x, y, z);
}
///
/// Returns a new object from local coordaintes relative to this collection.
///
/// Local X-coordinate of block.
/// Local Y-coordinate of block.
/// Local Z-coordinate of block.
/// A new object representing context-dependent data of a single block.
/// Context-depdendent data includes all data associated with this block. Since a represents
/// a view of a block within this container, any updates to data in the container will be reflected in the ,
/// and vice-versa for updates to the .
public BlockRef GetBlockRef (int x, int y, int z)
{
return new BlockRef(this, x, y, z);
}
///
/// Updates a block in this collection with values from a object.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// A object to copy block data from.
public void SetBlock (int x, int y, int z, Block block)
{
SetID(x, y, z, block.ID);
SetData(x, y, z, block.Data);
SetTileEntity(x, y, z, block.GetTileEntity().Copy());
}
#region IBlockCollection Members
///
/// Gets the length of this collection's X-dimension.
///
public int XDim
{
get { return _xdim; }
}
///
/// Gets the length of this collection's Y-dimension.
///
public int YDim
{
get { return _ydim; }
}
///
/// Gets the length of this collection's Z-dimension.
///
public int ZDim
{
get { return _zdim; }
}
///
/// Returns an object compatible with the interface from local coordinates relative to this collection.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible object.
///
IBlock IBlockCollection.GetBlock (int x, int y, int z)
{
return GetBlock(x, y, z);
}
///
/// Returns a reference object compatible with the interface from local coordinates relative to this collection.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible reference object.
///
IBlock IBlockCollection.GetBlockRef (int x, int y, int z)
{
return GetBlockRef(x, y, z);
}
///
/// Updates a block in this collection with values from an object.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An object to copy block data from.
public void SetBlock (int x, int y, int z, IBlock block)
{
SetID(x, y, z, block.ID);
}
///
/// Gets information on the type of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// A object containing information of a block's type.
public BlockInfo GetInfo (int x, int y, int z)
{
return BlockInfo.BlockTable[_blocks[x, y, z]];
}
internal BlockInfo GetInfo (int index)
{
return BlockInfo.BlockTable[_blocks[index]];
}
///
/// Gets the ID (type) of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The ID (type) of the specified block.
public int GetID (int x, int y, int z)
{
return _blocks[x, y, z];
}
internal int GetID (int index)
{
return _blocks[index];
}
///
/// Sets the ID (type) of a block at the given local coordinates, maintaining consistency of data.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The new ID of the block.
/// Depending on the options set for this , this method can be very
/// heavy-handed in the amount of work it does to maintain consistency of tile entities, lighting, fluid, etc.
/// for the affected block and possibly many other indirectly-affected blocks in the collection or neighboring
/// collections. If many SetID calls are expected to be made, some of this auto-reconciliation behavior should
/// be disabled, and the data should be rebuilt at the -level at the end.
public void SetID (int x, int y, int z, int id)
{
int oldid = _blocks[x, y, z];
if (oldid == id) {
return;
}
// Update value
_blocks[x, y, z] = (byte)id;
// Update tile entities
BlockInfo info1 = BlockInfo.BlockTable[oldid];
BlockInfo info2 = BlockInfo.BlockTable[id];
BlockInfoEx einfo1 = info1 as BlockInfoEx;
BlockInfoEx einfo2 = info2 as BlockInfoEx;
if (einfo1 != einfo2) {
if (einfo1 != null) {
ClearTileEntity(x, y, z);
}
if (einfo2 != null) {
CreateTileEntity(x, y, z);
}
}
// Light consistency
if (_autoLight) {
if (info1.ObscuresLight != info2.ObscuresLight) {
_lightManager.UpdateHeightMap(x, y, z);
}
if (info1.Luminance != info2.Luminance || info1.Opacity != info2.Opacity || info1.TransmitsLight != info2.TransmitsLight) {
UpdateBlockLight(x, y, z);
}
if (info1.Opacity != info2.Opacity || info1.TransmitsLight != info2.TransmitsLight) {
UpdateSkyLight(x, y, z);
}
}
// Fluid consistency
if (_autoFluid) {
if (info1.State == BlockState.FLUID || info2.State == BlockState.FLUID) {
UpdateFluid(x, y, z);
}
}
_dirty = true;
}
internal void SetID (int index, int id)
{
int yzdim = _ydim * _zdim;
int x = index / yzdim;
int zy = index - (x * yzdim);
int z = zy / _ydim;
int y = zy - (z * _ydim);
SetID(x, y, z, id);
}
///
/// Returns a count of all blocks in this with the given ID (type).
///
/// The ID of blocks to count.
/// A count of all matching blocks.
public int CountByID (int id)
{
int c = 0;
for (int i = 0; i < _blocks.Length; i++) {
if (_blocks[i] == id) {
c++;
}
}
return c;
}
#endregion
#region IDataBlockContainer Members
///
/// Returns an object compatible with the interface from local coordinates relative to this collection.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible object.
///
IDataBlock IDataBlockCollection.GetBlock (int x, int y, int z)
{
return GetBlock(x, y, z);
}
///
/// Returns a reference object compatible with the interface from local coordinates relative to this collection.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible reference object.
///
IDataBlock IDataBlockCollection.GetBlockRef (int x, int y, int z)
{
return GetBlockRef(x, y, z);
}
///
/// Updates a block in this collection with values from an object.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An object to copy block data from.
public void SetBlock (int x, int y, int z, IDataBlock block)
{
SetID(x, y, z, block.ID);
SetData(x, y, z, block.Data);
}
///
/// Gets the data value of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The data value of the specified block.
public int GetData (int x, int y, int z)
{
return _data[x, y, z];
}
internal int GetData (int index)
{
return _data[index];
}
///
/// Sets the data value of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The new data value of the block.
public void SetData (int x, int y, int z, int data)
{
if (_data[x, y, z] != data) {
_data[x, y, z] = (byte)data;
_dirty = true;
}
/*if (BlockManager.EnforceDataLimits && BlockInfo.BlockTable[_blocks[index]] != null) {
if (!BlockInfo.BlockTable[_blocks[index]].TestData(data)) {
return false;
}
}*/
}
internal void SetData (int index, int data)
{
if (_data[index] != data) {
_data[index] = (byte)data;
_dirty = true;
}
}
///
/// Returns a count of all blocks in this matching the given ID (type) and data value.
///
/// The ID of blocks to count.
/// The data value of blocks to count.
/// A count of all matching blocks.
public int CountByData (int id, int data)
{
int c = 0;
for (int i = 0; i < _blocks.Length; i++) {
if (_blocks[i] == id && _data[i] == data) {
c++;
}
}
return c;
}
#endregion
#region ILitBlockCollection Members
///
/// Not Implemented.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible object.
///
ILitBlock ILitBlockCollection.GetBlock (int x, int y, int z)
{
throw new NotImplementedException();
}
///
/// Returns a reference object compatible with the interface from local coordinates relative to this collection.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible reference object.
///
ILitBlock ILitBlockCollection.GetBlockRef (int x, int y, int z)
{
return GetBlockRef(x, y, z);
}
///
/// Updates a block in this collection with values from an object.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An object to copy block data from.
public void SetBlock (int x, int y, int z, ILitBlock block)
{
SetID(x, y, z, block.ID);
SetBlockLight(x, y, z, block.BlockLight);
SetSkyLight(x, y, z, block.SkyLight);
}
///
/// Gets the block-source light value of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The block-source light value of the specified block.
public int GetBlockLight (int x, int y, int z)
{
return _blockLight[x, y, z];
}
internal int GetBlockLight (int index)
{
return _blockLight[index];
}
///
/// Gets the sky-source light value of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The sky-source light value of the specified block.
public int GetSkyLight (int x, int y, int z)
{
return _skyLight[x, y, z];
}
internal int GetSkyLight (int index)
{
return _skyLight[index];
}
///
/// Sets the blocks-source light value of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The new block-source light value of the block.
public void SetBlockLight (int x, int y, int z, int light)
{
if (_blockLight[x, y, z] != light) {
_blockLight[x, y, z] = (byte)light;
_dirty = true;
}
}
internal void SetBlockLight (int index, int light)
{
if (_blockLight[index] != light) {
_blockLight[index] = (byte)light;
_dirty = true;
}
}
///
/// Sets the sky-source light value of a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The new sky-source light value of the block.
public void SetSkyLight (int x, int y, int z, int light)
{
if (_skyLight[x, y, z] != light) {
_skyLight[x, y, z] = (byte)light;
_dirty = true;
}
}
internal void SetSkyLight (int index, int light)
{
if (_skyLight[index] != light) {
_skyLight[index] = (byte)light;
_dirty = true;
}
}
///
/// Gets the lowest Y-coordinate of a block at which sky-source light remains unfiltered.
///
/// Local X-coordinate of a map location.
/// Local Z-coordinate of a map location.
/// The height-map value of a map location for calculating sky-source lighting.
public int GetHeight (int x, int z)
{
return _heightMap[x, z];
}
///
/// Sets the lowest Y-coordinate of a block at which sky-source light remains unfiltered.
///
/// Local X-coordinate of a map location.
/// Local Z-coordinate of a map location.
/// The new height-map value of the given map location.
public void SetHeight (int x, int z, int height)
{
_heightMap[x, z] = (byte)height;
}
///
/// Updates the block-source lighting of a block at the given local coordinates to maintain light consistency.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The lighting of the block will be updated to be consistent with the lighting in neighboring blocks.
/// If the block is itself a light source, many nearby blocks may be updated to maintain consistent lighting. These
/// updates may also touch neighboring objects, if they can be resolved.
/// This function assumes that the entire and neighboring s
/// already have consistent lighting, with the exception of the block being updated. If this assumption is violated,
/// lighting may fail to converge correctly.
public void UpdateBlockLight (int x, int y, int z)
{
_lightManager.UpdateBlockLight(x, y, z);
_dirty = true;
}
///
/// Updates the sky-source lighting of a block at the given local coordinates to maintain light consistency.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The lighting of the block will be updated to be consistent with the lighting in neighboring blocks.
/// If the block is itself a light source, many nearby blocks may be updated to maintain consistent lighting. These
/// updates may also touch neighboring objects, if they can be resolved.
/// This function assumes that the entire and neighboring s
/// already have consistent lighting, with the exception of the block being updated. If this assumption is violated,
/// lighting may fail to converge correctly.
public void UpdateSkyLight (int x, int y, int z)
{
_lightManager.UpdateBlockSkyLight(x, y, z);
_dirty = true;
}
///
/// Resets the block-source light value to 0 for all blocks in this .
///
public void ResetBlockLight ()
{
_blockLight.Clear();
_dirty = true;
}
///
/// Resets the sky-source light value to 0 for all blocks in this .
///
public void ResetSkyLight ()
{
_skyLight.Clear();
_dirty = true;
}
///
/// Reconstructs the block-source lighting for all blocks in this .
///
/// This function should only be called after the lighting has been reset in this
/// and all neighboring s, or lighting may fail to converge correctly.
/// This function cannot reset the lighting on its own, due to interactions between s.
/// If many light source or block opacity values will be modified in this , it may
/// be preferable to avoid explicit or implicit calls to and call this function once when
/// modifications are complete.
/// /
public void RebuildBlockLight ()
{
_lightManager.RebuildBlockLight();
_dirty = true;
}
///
/// Reconstructs the sky-source lighting for all blocks in this .
///
/// This function should only be called after the lighting has been reset in this
/// and all neighboring s, or lighting may fail to converge correctly.
/// This function cannot reset the lighting on its own, due to interactions between s.
/// If many light source or block opacity values will be modified in this , it may
/// be preferable to avoid explicit or implicit calls to and call this function once when
/// modifications are complete.
///
public void RebuildSkyLight ()
{
_lightManager.RebuildBlockSkyLight();
_dirty = true;
}
///
/// Reconstructs the height-map for this .
///
public void RebuildHeightMap ()
{
_lightManager.RebuildHeightMap();
_dirty = true;
}
///
/// Reconciles any block-source lighting inconsistencies between this and any of its neighbors.
///
/// It will be necessary to call this function if an is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.
///
public void StitchBlockLight ()
{
_lightManager.StitchBlockLight();
_dirty = true;
}
///
/// Reconciles any sky-source lighting inconsistencies between this and any of its neighbors.
///
/// It will be necessary to call this function if an is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.
///
public void StitchSkyLight ()
{
_lightManager.StitchBlockSkyLight();
_dirty = true;
}
///
/// Reconciles any block-source lighting inconsistencies between this and another on a given edge.
///
/// An -compatible object with the same dimensions as this .
/// The edge that is a neighbor on.
/// It will be necessary to call this function if an is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.
///
public void StitchBlockLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge)
{
_lightManager.StitchBlockLight(blockset, edge);
_dirty = true;
}
///
/// Reconciles any sky-source lighting inconsistencies between this and another on a given edge.
///
/// An -compatible object with the same dimensions as this .
/// The edge that is a neighbor on.
/// It will be necessary to call this function if an is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.
///
public void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge)
{
_lightManager.StitchBlockSkyLight(blockset, edge);
_dirty = true;
}
#endregion
#region IPropertyBlockCollection Members
///
/// Returns an object compatible with the interface from local coordinates relative to this collection.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible object.
///
IPropertyBlock IPropertyBlockCollection.GetBlock (int x, int y, int z)
{
return GetBlock(x, y, z);
}
///
/// Returns a reference object compatible with the interface from local coordinates relative to this collection.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An -compatible reference object.
///
IPropertyBlock IPropertyBlockCollection.GetBlockRef (int x, int y, int z)
{
return GetBlockRef(x, y, z);
}
///
/// Updates a block in this collection with values from an object.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// An object to copy block data from.
public void SetBlock (int x, int y, int z, IPropertyBlock block)
{
SetID(x, y, z, block.ID);
SetTileEntity(x, y, z, block.GetTileEntity().Copy());
}
///
/// Gets a record for a block at the given local coordinates, if one exists.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// A for the given block, or null if the is missing or the block type does not use a .
public TileEntity GetTileEntity (int x, int y, int z)
{
return _tileEntityManager.GetTileEntity(x, y, z);
}
///
/// Sets a record for a block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// The to add to the given block.
/// Thrown when the being passed is of the wrong type for the given block.
/// Thrown when the given block is of a type that does not support a record.
public void SetTileEntity (int x, int y, int z, TileEntity te)
{
_tileEntityManager.SetTileEntity(x, y, z, te);
_dirty = true;
}
///
/// Creates a default record suitable for the block at the given local coordinates.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
/// Thrown when the given block is of a type that does not support a record.
/// Thrown when the block type requests a that has not been registered with the .
public void CreateTileEntity (int x, int y, int z)
{
_tileEntityManager.CreateTileEntity(x, y, z);
_dirty = true;
}
///
/// Clears any record set for a block at the givne local coordinates, if one exists.
///
/// Local X-coordinate of a block.
/// Local Y-coordinate of a block.
/// Local Z-coordinate of a block.
public void ClearTileEntity (int x, int y, int z)
{
_tileEntityManager.ClearTileEntity(x, y, z);
_dirty = true;
}
#endregion
public void ResetFluid ()
{
_fluidManager.ResetWater(_blocks, _data);
_fluidManager.ResetLava(_blocks, _data);
_dirty = true;
}
public void RebuildFluid ()
{
_fluidManager.RebuildWater();
_fluidManager.RebuildLava();
_dirty = true;
}
public void UpdateFluid (int x, int y, int z)
{
bool autofluid = _autoFluid;
_autoFluid = false;
int blocktype = _blocks[x, y, z];
if (blocktype == BlockType.WATER || blocktype == BlockType.STATIONARY_WATER) {
_fluidManager.UpdateWater(x, y, z);
_dirty = true;
}
else if (blocktype == BlockType.LAVA || blocktype == BlockType.STATIONARY_LAVA) {
_fluidManager.UpdateLava(x, y, z);
_dirty = true;
}
_autoFluid = autofluid;
}
/*#region IEnumerable Members
public IEnumerator GetEnumerator ()
{
return new AlphaBlockEnumerator(this);
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
{
return new AlphaBlockEnumerator(this);
}
#endregion
public class AlphaBlockEnumerator : IEnumerator
{
private AlphaBlockCollection _collection;
private int _index;
private int _size;
public AlphaBlockEnumerator (AlphaBlockCollection collection)
{
_collection = collection;
_index = -1;
_size = collection.XDim * collection.YDim * collection.ZDim;
}
#region IEnumerator Members
public AlphaBlockRef Current
{
get
{
if (_index == -1 || _index == _size) {
throw new InvalidOperationException();
}
return new AlphaBlockRef(_collection, _index);
}
}
#endregion
#region IDisposable Members
public void Dispose () { }
#endregion
#region IEnumerator Members
object System.Collections.IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext ()
{
if (++_index == _size) {
return false;
}
return true;
}
public void Reset ()
{
_index = -1;
}
#endregion
}*/
}
}