価値があるのは、ディスク上のディレクトリツリーに少し似た「パス」でアクセスするのが非常にうまくいくことです。これは、私が書いているいくつかのC#コードから取られています(以下のクラスのビットを見逃していることに注意してください)が、アイデアはC++に直接変換されます。
sealed class Entity : IEntity
{
private readonly IDictionary<string,IEntity> m_children = new Dictionary<string,IEntity>();
private readonly IDictionary<string,dynamic> m_properties;
public string Name { get { return m_properties["Name"]; } }
public IEntity Parent { get; set; }
/// <summary>
/// Adds a child to this entity.
/// </summary>
/// <param name="child">The child to add.</param>
public void AddChild(IEntity child)
{
m_children.Add(child.Name, child);
child.Parent = this;
}
/// <summary>
/// Gets the absolute path of this entity in its tree.
/// </summary>
/// <returns>The entity's absolute path.</returns>
public string GetAbsolutePath()
{
IEntity cur = this;
var path = new LinkedList<string>();
while(cur.Parent != null)
{
path.AddFirst(cur.Name);
cur = cur.Parent;
}
path.AddFirst(".");
return string.Join("/", path);
}
/// <summary>
/// Gets another entity in this entity's tree by its absolute path (i.e. its path relative to the root entity).
/// </summary>
/// <param name="path">The absolute path to the other entity.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByAbsolutePath(string path)
{
return GetRootEntity().GetEntityByRelativePath(path);
}
/// <summary>
/// Gets another entity in this entity's tree by its absolute path (i.e. its path relative to the root entity).
/// </summary>
/// <param name="path">The absolute path to the other entity, as a list of path components.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByAbsolutePath(LinkedList<string> path)
{
return GetRootEntity().GetEntityByRelativePath(path);
}
/// <summary>
/// Gets another entity in this entity's tree by its path relative to this entity.
/// </summary>
/// <param name="path">The relative path to the other entity.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByRelativePath(string path)
{
return GetEntityByRelativePath(new LinkedList<string>(path.Split('/')));
}
/// <summary>
/// Gets another entity in this entity's tree by its path relative to this entity.
/// </summary>
/// <param name="path">The relative path to the other entity, as a list of path components.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByRelativePath(LinkedList<string> path)
{
IEntity cur = this;
while(cur != null && path.Count != 0)
{
switch(path.First())
{
case ".":
break;
case "..":
cur = cur.Parent;
break;
default:
cur = cur.GetChild(path.First());
break;
}
path.RemoveFirst();
}
return cur;
}
/// <summary>
/// Gets the root entity of this entity's tree.
/// </summary>
/// <returns>The root entity of this entity's tree.</returns>
private IEntity GetRootEntity()
{
IEntity cur = this;
while(cur.Parent != null)
{
cur = cur.Parent;
}
return cur;
}
}
エンティティツリー内の任意のエンティティを指定すると、絶対パスまたは相対パスで他のエンティティにアクセスできます。
cityA.GetEntityByRelativePath("../city:B/building:1");