2011-10-26 9 views
0

私のゲームでは、マネージャリソースがテクスチャ、サウンド、フォントなどを好むリソースクラスを作っています。このImageListクラスは、必要に応じてランタイム中に自動的にテクスチャを読み込みます。このImageListクラスはどのようにしてリソースを使用できるようにするのですか?

class TextureList 
{ 
    private Dictionary<string, Texture> _list; 

    public Texture this[string name] 
    { 
     get 
     { 
      Texture tex; 
      bool success = List.TryGetValue(name, out tex); 

      if (!success) 
      { 
       tex = Resources.LoadImage(name); 
       List[name] = tex; 
      } 

      return tex; 
     } 
    } 

    protected Dictionary<String, Texture> List 
    { 
     get 
     { 
      return _list ?? new Dictionary<String, Texture>(); 
     } 
    } 
} 

今、私は音にすべてのテクスチャを変更したり、フォント(と重複したコードの多くを書く)の手間をかけずにフォントリストまたはSoundListクラスを作ることができるように、このクラスは汎用的にするようにしたいです。誰でもこのジェネリック版を作るのを手伝ってくれますか?

+4

あなたのコードは常に(_listが設定されることはありません新しいリストを作成

public abstract class ResourceList<TYPE> where TYPE : BaseResource // change to your actual base-class or interface { private Dictionary<string, TYPE> resources_ = new Dictionary<string, TYPE>(); // loader protected abstract TYPE LoadImpl(string name); public TYPE this[string name] { get { TYPE resource; if(!resources_.ContainsKey(name)) { resource = LoadImpl(); resources_[name] = resource; } else resource = resources_[name]; return resource; } } } // eo class ResourceList 

は、異なるリソースのための具体的な実装を提供します任意の値に) –

+0

参照:[スレッドセーフメモ](http://stackoverflow.com/questions/1254995/thread-safe-memoization)。スレッド安全性が必要ない場合は、Wes Dyerの[post](http://blogs.msdn.com/b/wesdyer/archive/2007/01/26/function-memoization.aspx)のメモを参照してください。 – Ani

+0

@VirtualBlackFoxいいキャッチ!今すぐ変更する。 – Dlaor

答えて

7
  1. はコンストラクタで
  2. あなたのクラスは、一般的な作り、あなたはTがあなたのジェネリック引数でのFuncを渡す必要があります。
  3. ロジックは次のようになります。項目が見つからない場合、Funcで渡された結果が呼び出され、結果が内部リストに格納されます。

ので、あなたのクラスは、あなたのテクスチャを想定すると

var x = new Cachinglist<Texture>(s => Resources.LoadImage(s)); 

または

class CachingList<T> 
{ 
    private readonly Dictionary<string, T> _list = new Blabla..(); 
    private readonly Func<string,T> _itemsFactory; 

    public CachingList(Func<string,T> itemsFactory) { 
     _itemsFactory = itemsFactory; 
    } 

    public T this[string name] 
    { 
     get 
     { 
      T t; 

      if (!_list.TryGetValue(name, out t)) 
      { 
       t = _itemsFactory(name); 
       _list[name] = t; 
      } 

      return t; 
     } 
    } 
} 
6

となり、その他のすべてが(私はこの例ではBaseResourceそれを呼び出すつもり共通の基底クラスを持って聞こえます)、ローダーを持つ汎用基本クラスを作成します。おそらく1は次のようになりますサウンド

public class TextureList : ResourceList<Texture> 
{ 
    protected override Texture LoadImpl(string name) 
    { 
     return Resources.LoadImage(name); 
    } 
} 

public class SoundList : ResourceList<Sound> 
{ 
    protected override Sound LoadImpl(string name) 
    { 
     return Resources.LoadSound(name); 
    } 
}