Cache在RMVX中主要负责储存读取过的Bitmap,源码的注释如下
# ■ Cache #------------------------------------------------------------------------------ # 本模组载入所有图像,建立并保存Bitmap物件。为加快载入速度并节省内存, # 本模组将以建立的bitmap物件保存在内部哈希表中,使得程序在需求已存在 # 的图像时能快速读取bitmap物件。
Cache模块的重要度自不用说。
如果没有这个模块将bitmap物件保存到哈希表的话,我们不得不对自己生成的每一个bitmap手动dispose,否则程序很会快的吃掉所有内存崩溃。
Cache中最关键的方法如下
#-------------------------------------------------------------------------- # * 载入图档 #-------------------------------------------------------------------------- def self.load_bitmap(folder_name, filename, hue = 0) @cache = {} if @cache == nil path = folder_name + filename if not @cache.include?(path) or @cache[path].disposed? if filename.empty? @cache[path] = Bitmap.new(32, 32) else @cache[path] = Bitmap.new(path) end end if hue == 0 return @cache[path] else key = [path, hue] if not @cache.include?(key) or @cache[key].disposed? @cache[key] = @cache[path].clone @cache[key].hue_change(hue) end return @cache[key] end end
该方法的主要目的是根据要读取的folder_name和filename拼凑出path,之后把path当做key检查内部哈希表是否已经保存过此bitmap物件
如果已有则返回此物件,否则生成此物件后将其保存进哈希表并返回。
一眼看过去没什么问题,但是有一点小的不足。
假设我们用如下方式调用了两次这个方法
bitmap1 = Cache.load_bitmap("Graphics/picture/", "aaa") bitmap2 = Cache.load_bitmap("Graphics/picture/", "AAA")
显然,aaa和AAA指的是同一文件,但是两次读取的path并不相同,根本原因就是filename一个是大写一个是小写,从而导致path的不同。
这样的话,Cache会在内部哈希表中保存两个其实一模一样的bitmap物件,如果你的这张图片不巧在1M左右,这样就会浪费掉大量内存。
虽然我们可以强制自己在调用时的全部用小写输入,但难免疏忽,所以我们可以简单处理一下path,将其全部转为大写或者小写即可。
另外,也许由于年代问题,rmvx当时还是直接使用String进行hash的,我们知道Symbol可以节约内存并加快读取速度,所以我们可以把其转为Symbol再哈希。
最后的load_bitmap方法如下
def self.load_bitmap(folder_name, filename, hue = 0) @cache = {} if @cache == nil path = (folder_name + filename).downcase sym = path.to_sym if not @cache.include?(sym) or @cache[sym].disposed? if filename.empty? @cache[sym] = Bitmap.new(32, 32) else @cache[sym] = Bitmap.new(path) end end if hue == 0 return @cache[sym] else key = [sym, hue] if not @cache.include?(key) or @cache[key].disposed? @cache[key] = @cache[sym].clone @cache[key].hue_change(hue) end return @cache[key] end end