using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using Substrate.Core;
using Substrate.Nbt;
using Substrate.Data;
namespace Substrate
{
///
/// An abstract representation of any conforming chunk-based world.
///
/// By default, NbtWorld registers handlers to check if a given world can be opened as an or
/// a , which are used by 's generic method to automatically
/// detect a world's type and open it.
/// Advanced implementors can support loading other Nbt-compatible world formats by extending and registering
/// an event handler with the event, which will allow the generic method to
/// open worlds of the new format.
public abstract class NbtWorld
{
private const string _DATA_DIR = "data";
private string _path;
private string _dataDir;
///
/// Creates a new instance of an object.
///
protected NbtWorld () {
_dataDir = _DATA_DIR;
}
///
/// Gets or sets the path to the directory containing the world.
///
public string Path
{
get { return _path; }
set { _path = value; }
}
///
/// Gets or sets the directory containing data resources, rooted in the world directory.
///
public string DataDirectory
{
get { return _dataDir; }
set { _dataDir = value; }
}
///
/// Gets a reference to this world's object.
///
public abstract Level Level { get; }
///
/// Gets an for the default dimension.
///
/// An tied to the default dimension in this world.
public IBlockManager GetBlockManager ()
{
return GetBlockManagerVirt(Dimension.DEFAULT);
}
///
/// Gets an for the given dimension.
///
/// The id of the dimension to look up.
/// An tied to the given dimension in this world.
public IBlockManager GetBlockManager (int dim)
{
return GetBlockManagerVirt(dim);
}
///
/// Gets an for the default dimension.
///
/// An tied to the default dimension in this world.
public IChunkManager GetChunkManager ()
{
return GetChunkManagerVirt(Dimension.DEFAULT);
}
///
/// Gets an for the given dimension.
///
/// The id of the dimension to look up.
/// An tied to the given dimension in this world.
public IChunkManager GetChunkManager (int dim)
{
return GetChunkManagerVirt(dim);
}
///
/// Gets an for maanging players on multiplayer worlds.
///
/// An for this world.
public IPlayerManager GetPlayerManager ()
{
return GetPlayerManagerVirt();
}
///
/// Gets a for managing data resources, such as maps.
///
/// A for this world.
public DataManager GetDataManager ()
{
return GetDataManagerVirt();
}
///
/// Attempts to determine the best matching world type of the given path, and open the world as that type.
///
/// The path to the directory containing the world.
/// A concrete type, or null if the world cannot be opened or is ambiguos.
public static NbtWorld Open (string path)
{
if (ResolveOpen == null) {
return null;
}
OpenWorldEventArgs eventArgs = new OpenWorldEventArgs(path);
ResolveOpen(null, eventArgs);
if (eventArgs.HandlerCount != 1) {
return null;
}
foreach (OpenWorldCallback callback in eventArgs.Handlers) {
return callback(path);
}
return null;
}
///
/// Saves the world's data, and any objects known to have unsaved changes.
///
public abstract void Save ();
///
/// Raised when is called, used to find a concrete type that can open the world.
///
protected static event EventHandler ResolveOpen;
#region Covariant Return-Type Helpers
///
/// Virtual implementor of .
///
/// The given dimension to fetch an for.
/// An for the given dimension in the world.
protected abstract IBlockManager GetBlockManagerVirt (int dim);
///
/// Virtual implementor of .
///
/// The given dimension to fetch an for.
/// An for the given dimension in the world.
protected abstract IChunkManager GetChunkManagerVirt (int dim);
///
/// Virtual implementor of .
///
/// An for the given dimension in the world.
protected abstract IPlayerManager GetPlayerManagerVirt ();
///
/// Virtual implementor of
///
/// A for the given dimension in the world.
protected virtual DataManager GetDataManagerVirt ()
{
throw new NotImplementedException();
}
#endregion
static NbtWorld ()
{
ResolveOpen += AnvilWorld.OnResolveOpen;
ResolveOpen += BetaWorld.OnResolveOpen;
ResolveOpen += AlphaWorld.OnResolveOpen;
}
}
}