Project1

标题: 如何获取 RGSS 的内部类 [打印本页]

作者: 听海    时间: 2011-4-17 15:23
提示: 作者被禁止或删除 内容自动屏蔽
作者: 禾西    时间: 2011-4-17 15:31
本帖最后由 禾西 于 2011-4-17 16:21 编辑

找了一下,發覺沒有找到,于是丟一下代碼

  1. class Table
  2. include Flowable
  3.   def initialize(*arg)
  4.     tempAry=[*arg]
  5.     txsize = tempAry[0]
  6.     tysize = tempAry[1] != nil ? tempAry[1] : 1
  7.     tzsize = tempAry[2] != nil ? tempAry[2] : 1
  8.     # 缁存暟
  9.     tdim = [tempAry.size,3].min
  10.    
  11.     if tempAry[tdim].nil?
  12.       @data = int2str(tdim)+int2str(txsize)+int2str(tysize)+int2str(tzsize)+int2str(txsize*tysize*tzsize)
  13.       
  14.       for z in 0...tzsize
  15.         for y in 0...tysize
  16.           for x in 0...txsize
  17.             @data += fix2str(0)
  18.           end
  19.         end
  20.       end
  21.     else
  22.       @data = tempAry[tdim]
  23.     end
  24.    
  25.   end
  26.   
  27.   def [](x,y=0,z=0)
  28.     return nil unless x < xsize and y < ysize and z < zsize
  29.     pos = 10 + z*xsize*ysize + y*xsize + x
  30.     pos *= 2
  31.    
  32.     str = @data[pos,2]
  33.     return str2fix(str)
  34.   end
  35.   
  36.   def []=(*arg)
  37.     x = 0
  38.     y = 0
  39.     z = 0
  40.    
  41.     tempAry=[*arg]
  42.    
  43.     value = tempAry[tempAry.size-1]
  44.    
  45.     case tempAry.size
  46.     when 2
  47.       x = tempAry[0]
  48.     when 3
  49.       x = tempAry[0]
  50.       y = tempAry[1]
  51.     when 4
  52.       x = tempAry[0]
  53.       y = tempAry[1]
  54.       z = tempAry[2]
  55.     end
  56.    
  57.     pos = 10 + z*xsize*ysize + y*xsize + x
  58.     pos *= 2
  59.     str = fix2str(value)
  60.    
  61.     @data = @data[0,pos] + str + @data[pos+2,@data.size - pos - 2]
  62.    
  63.     return value
  64.   end
  65.   
  66.   def resize(*arg)
  67.     tempAry=[*arg]
  68.     txsize = tempAry[0]
  69.     tysize = tempAry[1] != nil ? tempAry[1] : 1
  70.     tzsize = tempAry[2] != nil ? tempAry[2] : 1
  71.     # 缁存暟
  72.     tdim = [tempAry.size,3].min
  73.    
  74.     if tempAry[3].nil?
  75.       @data = int2str(tdim)+int2str(txsize)+int2str(tysize)+int2str(tzsize)
  76.       for z in 0...tzsize
  77.         for y in 0...tysize
  78.           for x in 0...txsize
  79.             @data += fix2str(0)
  80.           end
  81.         end
  82.       end
  83.     else
  84.       @data = tempAry[3]
  85.     end
  86.    
  87.   end
  88.   
  89.   def data;@data;end
  90.   def dim;str2int(@data[0,4]);end
  91.   def xsize;str2int(@data[4,4]);end
  92.   def ysize;str2int(@data[8,4]);end
  93.   def zsize;str2int(@data[12,4]);end
  94.   def size;str2int(@data[16,4]);end
  95.   
  96.   def _dump(aDepth)
  97.     return @data
  98.   end
  99.   
  100.   def Table._load(data)
  101.     dim = str2int(data[0,4])
  102.     xsize = str2int(data[4,4])
  103.     ysize = str2int(data[8,4])
  104.     zsize = str2int(data[12,4])
  105.     size = str2int(data[16,4])
  106.     return Table.new(xsize,ysize,zsize,data)
  107.   end
  108. end
  109. module Flowable
  110.   def str2fix(str)
  111.     case str.size
  112.     when 1
  113.       str.unpack("c")[0]
  114.     when 2
  115.       str.unpack("s")[0]
  116.     when 4
  117.       str.unpack("v")[0]
  118.     end
  119.   end
  120.   
  121.   def fix2str(fix)
  122.     str = [fix].pack("s")
  123.     return str
  124.   end
  125.   
  126.   def str2int(str)
  127.     return str.unpack("L")[0]
  128.   end
  129.   
  130.   def int2str(int)
  131.     return [int].pack("L")
  132.   end
  133.   
  134.   def str2float(str)
  135.     return str.unpack("d")[0]
  136.   end
  137.   
  138.   def float2str(float)
  139.     return [float].pack("d")
  140.   end
  141.   
  142. end
复制代码
這個已經不記得哪里偷的了,好像是輪子寫的?
作者: 听海    时间: 2011-4-17 16:07
提示: 作者被禁止或删除 内容自动屏蔽
作者: 禾西    时间: 2011-4-17 16:33
symbol轉化string,直接.to_s就行了- -
作者: 听海    时间: 2011-4-17 18:32
提示: 作者被禁止或删除 内容自动屏蔽
作者: 匿名    时间: 2011-4-17 19:03
部分内部类是C实现的,所以可能找不到RUBY源码
作者: 听海    时间: 2011-4-17 20:02
提示: 作者被禁止或删除 内容自动屏蔽
作者: 苏小脉    时间: 2011-4-18 00:58
本帖最后由 苏小脉 于 2011-4-18 01:29 编辑
  1. tempAry=[*arg]
复制代码
这个是冗余,arg 本身就是数组。
  1.       @data = int2str(tdim)+int2str(txsize)+int2str(tysize)+int2str(tzsize)
复制代码
@data 最好一开始就根据尺寸分配好大小(String.new),现在这样是动态增长的,其中包含了可能的 realloc 过程。

  1.     if tempAry[tdim].nil?
  2.       # ...
  3.     else
  4.       @data = tempAry[tdim]
  5.     end
复制代码
这里 else 下面的语句是何用意?三维尺寸之后如果还有第四个参数,就将其赋予 @data?不解。

另外 Table#_dump 和 Table._load 其实都不用定义——如果对象不响应 _dump 和 _load 方法,Ruby 就按照默认的 marshalling 方案进行序列化,由于这里的 Table 是纯 Ruby 实现,数据都存储在 Ruby 层,所以完全可以沿用默认方案,唯一的区别就是多了一层 Table 这个对象的外壳。

要注意的是 Table._load 是 Table 这个 Class 对象的单例方法,也就是 Table 的类方法,在 _load 的内部,self 引用的是 Table 元类实例,而不是像在 Table#_dump 内部那样引用的 Table 实例本身,所以在 Table 的元类单例上下文中是找不到 str2int 方法的。

在一开头 incldue Flowable 那里加上:
  1. class << Table
  2.   include Flowable
  3. end
复制代码
就可以了。或者直接用 Flowable::str2int 这样的修饰法。

顺带一提,如果保持目前这个 _dump 的实现不变的话,_load 那里又重新调用 initialize,pack 来 unpack 去的不太好,可以直接:

  1.   def Table._load(data)
  2.     return self.allocate.instance_eval { @data = data; self }
  3.   end
复制代码
其实用 Table 的目的是为了效率,所以最好还是生成本地代码,否则在 Ruby 的抽象层上无形间就丢失了效率。
作者: 禾西    时间: 2011-4-18 01:58
回复 苏小脉 的帖子

這東西有些年頭了,當時是copy & paste偷回來的,沒有細看。現在聽先生這麼說,的確有不善的地方,受教了。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1