Project1
标题:
如何获取 RGSS 的内部类
[打印本页]
作者:
听海
时间:
2011-4-17 15:23
提示:
作者被禁止或删除 内容自动屏蔽
作者:
禾西
时间:
2011-4-17 15:31
本帖最后由 禾西 于 2011-4-17 16:21 编辑
找了一下,發覺沒有找到,于是丟一下代碼
class Table
include Flowable
def initialize(*arg)
tempAry=[*arg]
txsize = tempAry[0]
tysize = tempAry[1] != nil ? tempAry[1] : 1
tzsize = tempAry[2] != nil ? tempAry[2] : 1
# 缁存暟
tdim = [tempAry.size,3].min
if tempAry[tdim].nil?
@data = int2str(tdim)+int2str(txsize)+int2str(tysize)+int2str(tzsize)+int2str(txsize*tysize*tzsize)
for z in 0...tzsize
for y in 0...tysize
for x in 0...txsize
@data += fix2str(0)
end
end
end
else
@data = tempAry[tdim]
end
end
def [](x,y=0,z=0)
return nil unless x < xsize and y < ysize and z < zsize
pos = 10 + z*xsize*ysize + y*xsize + x
pos *= 2
str = @data[pos,2]
return str2fix(str)
end
def []=(*arg)
x = 0
y = 0
z = 0
tempAry=[*arg]
value = tempAry[tempAry.size-1]
case tempAry.size
when 2
x = tempAry[0]
when 3
x = tempAry[0]
y = tempAry[1]
when 4
x = tempAry[0]
y = tempAry[1]
z = tempAry[2]
end
pos = 10 + z*xsize*ysize + y*xsize + x
pos *= 2
str = fix2str(value)
@data = @data[0,pos] + str + @data[pos+2,@data.size - pos - 2]
return value
end
def resize(*arg)
tempAry=[*arg]
txsize = tempAry[0]
tysize = tempAry[1] != nil ? tempAry[1] : 1
tzsize = tempAry[2] != nil ? tempAry[2] : 1
# 缁存暟
tdim = [tempAry.size,3].min
if tempAry[3].nil?
@data = int2str(tdim)+int2str(txsize)+int2str(tysize)+int2str(tzsize)
for z in 0...tzsize
for y in 0...tysize
for x in 0...txsize
@data += fix2str(0)
end
end
end
else
@data = tempAry[3]
end
end
def data;@data;end
def dim;str2int(@data[0,4]);end
def xsize;str2int(@data[4,4]);end
def ysize;str2int(@data[8,4]);end
def zsize;str2int(@data[12,4]);end
def size;str2int(@data[16,4]);end
def _dump(aDepth)
return @data
end
def Table._load(data)
dim = str2int(data[0,4])
xsize = str2int(data[4,4])
ysize = str2int(data[8,4])
zsize = str2int(data[12,4])
size = str2int(data[16,4])
return Table.new(xsize,ysize,zsize,data)
end
end
module Flowable
def str2fix(str)
case str.size
when 1
str.unpack("c")[0]
when 2
str.unpack("s")[0]
when 4
str.unpack("v")[0]
end
end
def fix2str(fix)
str = [fix].pack("s")
return str
end
def str2int(str)
return str.unpack("L")[0]
end
def int2str(int)
return [int].pack("L")
end
def str2float(str)
return str.unpack("d")[0]
end
def float2str(float)
return [float].pack("d")
end
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 编辑
tempAry=[*arg]
复制代码
这个是冗余,arg 本身就是数组。
@data = int2str(tdim)+int2str(txsize)+int2str(tysize)+int2str(tzsize)
复制代码
@data 最好一开始就根据尺寸分配好大小(String.new),现在这样是动态增长的,其中包含了可能的 realloc 过程。
if tempAry[tdim].nil?
# ...
else
@data = tempAry[tdim]
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 那里加上:
class << Table
include Flowable
end
复制代码
就可以了。或者直接用 Flowable::str2int 这样的修饰法。
顺带一提,如果保持目前这个 _dump 的实现不变的话,_load 那里又重新调用 initialize,pack 来 unpack 去的不太好,可以直接:
def Table._load(data)
return self.allocate.instance_eval { @data = data; self }
end
复制代码
其实用 Table 的目的是为了效率,所以最好还是生成本地代码,否则在 Ruby 的抽象层上无形间就丢失了效率。
作者:
禾西
时间:
2011-4-18 01:58
回复
苏小脉
的帖子
這東西有些年頭了,當時是copy & paste偷回來的,沒有細看。現在聽先生這麼說,的確有不善的地方,受教了。
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1