您的位置:首页 > 其它

silverlight游戏设计(二)资源管理篇(下)--资源的状态通知、管理与缓存

2010-12-24 19:18 507 查看
在上篇中,我们实现了一个带有池化、并发连接限制能力的资源下载器,虽然这个下载器能够使我们的游戏动态加载资源并在加载完毕/失败后调用回调方法。但是还是缺乏一些智能。比如我要加载一个game_role_petegg.zip的资源包,如我们有需求:

1.对已经下载过的资源不再重复下载。

2.下载过的资源要缓存,一方面存在内存中,一方面存在isolatedstorage中。

实现这些功能会极大的提高用户体验,所我们有必要设计一个带有缓存控制能力的资源管理器。

复用已有的DownloadDelegater

搞开发的嘛,不可能每一个需求都单独写一片代码,这要将对象的职责分离清楚,复用还是很容易的。

我们定义需求接口:

public interface IWebClientResourceService

{

void Load(Uri uri, DownloadResultEventHandler callback);

void PutIsolatedStorageToMemoryCache(Uri uri);

void PutMemoryCacheToIsolatedStorage(Uri uri);

void RemoveCache(Uri uri);

}

Load方法会下载指定uri的资源,如果之前已经在下载过就不会重复下载。

PutIsolatedStorageToMemoryCache将隔离存储中的数据加载到内存中。

PutMemoryCacheToIsolatedStorage将内存数据保存到隔离存储。

下面通过组合的方式复用之前的DownloadDelegater。

GameImageResService

namespace Sopaco.Silverlight.GameFramewrok.GameRes

{

/// <summary>

/// 应用WebClientResourceService定制的一个游戏资源服务模块

/// </summary>

public class GameImageResService

{

#region make it a singleton

public static readonly GameImageResService Instance;

static GameImageResService()

{

Instance = new GameImageResService();

}

public GameImageResService()

{

}

#endregion

private static readonly string IMG_ZIP_XML = "resconfig.xml";

private WebClientResourceService _resourceService = WebClientResourceService.Instance;

private Dictionary<Uri, BitmapImage> _imageCache = new Dictionary<Uri, BitmapImage>();

private Dictionary<string, BitmapImage> _namedImageCache = new Dictionary<string, BitmapImage>();

/// <summary>

/// 图片资源

/// </summary>

public void GetBitmapImage(Uri uri, Action<BitmapImage> callback)

{

if(_imageCache.ContainsKey(uri))

{

callback(_imageCache[uri]);

return;

}

_resourceService.Load(uri, (stream, status) =>

{

if(status == DownloadStatus.Completed)

{

var image = new BitmapImage();

image.SetSource(stream);

_imageCache[uri] = image;

_resourceService.PutMemoryCacheToIsolatedStorage(uri);//图片资源由GameResService托管,将WebClientResourceService中的缓存持久化

callback.ExecuteSecurity(image);

}

else

{

#if DEBUG

throw new Exception("error in resource downloading");

#endif

}

});

}

/// <summary>

/// 载入一个zip资源包中的图片资源

/// </summary>

/*配置文件格式

* resconfig.xml

* <?……?>

* <AppRoot>

* <ImgResSection><Image key="……" uri="……" /></ImgResSection>

* </AppRoot>

* #endregion

*/

public void GetBitmapImageInZip(Uri uri, Action onZipLoaded, Action onResourcesLoad)

{

_resourceService.Load(uri, (stream, status) =>

{

if(status != DownloadStatus.Completed)

{

#if DEBUG

throw new Exception("error in download resource");

#endif

}

onZipLoaded.ExecuteSecurity();

StreamResourceInfo info = new StreamResourceInfo(stream, null);

using (var reader = new StreamReader(Application.GetResourceStream(info, new Uri(IMG_ZIP_XML, UriKind.Relative)).Stream))

{

var xmlReader = XmlReader.Create(reader);

while(xmlReader.Read())

{

if(xmlReader.IsStartElement("ImgResSection"))

{

while(xmlReader.Read())

{

if(xmlReader.IsStartElement("Image"))

{

xmlReader.MoveToAttribute("key");

xmlReader.ReadAttributeValue();

string imgKey = xmlReader.Value;

xmlReader.MoveToAttribute("uri");

xmlReader.ReadAttributeValue();

var targetUri = new Uri(xmlReader.Value, UriKind.RelativeOrAbsolute);

var bitmapStream = Application.GetResourceStream(info, targetUri).Stream;

var image = new BitmapImage();

image.SetSource(bitmapStream);

_namedImageCache[imgKey] = image;

}

}

}

}

}

onResourcesLoad.ExecuteSecurity();

#region zip图片资源包由GameResService托管,将WebClientResourceService中的缓存持久化

_resourceService.PutMemoryCacheToIsolatedStorage(uri);

#endregion

});

}

public BitmapImage GetImageByUri(Uri uri)

{

if (!_imageCache.ContainsKey(uri))

return null;

return _imageCache[uri];

}

public BitmapImage GetImageBySpecialName(string key)

{

if(!_namedImageCache.ContainsKey(key))

return null;

return _namedImageCache[key];

}

}

}

本文源码下载



最后祝大家圣诞快乐Merry Christmas!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐