Project1
标题: 简单的监听机制 [打印本页]
作者: yagami 时间: 2014-7-22 23:35
标题: 简单的监听机制
为了帮小伙伴做一套炫酷的ui 所以有了这东西 class NotifyCenter
def initialize
@obsarray = [[],[]]
@procarray = [[],[]]
@desarr = [[],[]]
end
def addObserver(obs,proc,des)#增加监听
@obsarray[obs.kind].push(obs)
if obs.kind == 1#这里预留按钮机制 触摸优先级 可以无视
@obsarray[obs.kind].sort! {|a,b|b.z - a.z}
index = @obsarray[obs.kind].index(obs)
@procarray[obs.kind].insert( index, proc)
@desarr[obs.kind].insert( index, des)
else
@procarray[obs.kind].push(proc)
@desarr[obs.kind].push(des)
end
end
def removeObserver(obs)#移除监听
loop do
index = @obsarray[obs.kind].index(obs)
break if index == nil
@obsarray[obs.kind].delete_at(index)
@procarray[obs.kind].delete_at(index)
@desarr[obs.kind].delete_at(index)
end
#一个对象可能同时被观察多个请求 所以用了循环
end
def postmsg(kind,des)#发送通知 对所有被监听的小伙伴 回调
for i in 0..@desarr[kind].size
if @desarr[kind][i] == des
@procarray[kind][i].call
end
end
end
end
###################testclass##############
class Obstest
attr_reader :kind
attr_reader :testnum
def initialize(testnum)
@kind = 0
@testnum = testnum
$notifycenter.addObserver(self,Proc.new { self.test },"aaa")
$notifycenter.addObserver(self,Proc.new { self.test2 },"bbb")
end
def test
p "test"
end
def test2
p @testnum.to_s
end
end
class Obstest2
attr_reader :kind
def initialize
@kind = 0
$notifycenter.addObserver(self,Proc.new { self.test },"ccc")
end
def test
p "testccc"
end
end
class NotifyCenter
def initialize
@obsarray = [[],[]]
@procarray = [[],[]]
@desarr = [[],[]]
end
def addObserver(obs,proc,des)#增加监听
@obsarray[obs.kind].push(obs)
if obs.kind == 1#这里预留按钮机制 触摸优先级 可以无视
@obsarray[obs.kind].sort! {|a,b|b.z - a.z}
index = @obsarray[obs.kind].index(obs)
@procarray[obs.kind].insert( index, proc)
@desarr[obs.kind].insert( index, des)
else
@procarray[obs.kind].push(proc)
@desarr[obs.kind].push(des)
end
end
def removeObserver(obs)#移除监听
loop do
index = @obsarray[obs.kind].index(obs)
break if index == nil
@obsarray[obs.kind].delete_at(index)
@procarray[obs.kind].delete_at(index)
@desarr[obs.kind].delete_at(index)
end
#一个对象可能同时被观察多个请求 所以用了循环
end
def postmsg(kind,des)#发送通知 对所有被监听的小伙伴 回调
for i in 0..@desarr[kind].size
if @desarr[kind][i] == des
@procarray[kind][i].call
end
end
end
end
###################testclass##############
class Obstest
attr_reader :kind
attr_reader :testnum
def initialize(testnum)
@kind = 0
@testnum = testnum
$notifycenter.addObserver(self,Proc.new { self.test },"aaa")
$notifycenter.addObserver(self,Proc.new { self.test2 },"bbb")
end
def test
p "test"
end
def test2
p @testnum.to_s
end
end
class Obstest2
attr_reader :kind
def initialize
@kind = 0
$notifycenter.addObserver(self,Proc.new { self.test },"ccc")
end
def test
p "testccc"
end
end
测试代码偷懒写在main里了
#==============================================================================
# ■ Main
#------------------------------------------------------------------------------
# 各定义结束后、从这里开始实际处理。
#==============================================================================
begin
# 准备过渡
# 设置系统默认字体
Font.default_name = (["黑体"])
Graphics.freeze
# 生成场景对像 (标题画面)
$scene = Scene_Title.new
################################
$notifycenter = NotifyCenter.new
a = Obstest.new(0)
$notifycenter.postmsg(0,"aaa")
$notifycenter.postmsg(0,"ccc")
p "step 1"
#通知aaa 和 ccc需求 a对象绑定了 aaa 和 bbb需求 所以 aaa对应的函数会被执行 显示test
#但并没有对象绑定ccc 所以 ccc这条消息发出去也是没意义的
b = Obstest.new(1)
$notifycenter.postmsg(0,"aaa")
$notifycenter.postmsg(0,"bbb")
p "step 2"
#通知aaa 和 bbb需求 因为 增加了b对象 所以通知aaa需求的时候 会同时通知 a 和 b对象
#先打印2个 test 再通知bbb需求 打印 0 和1
$notifycenter.removeObserver(a)#将a对象移除监听
$notifycenter.postmsg(0,"aaa")
$notifycenter.postmsg(0,"bbb")
p "step 3"
#因为a对象被移除了 所以 通知 aaa 和 bbb时 只剩下 b对象了 打印 test 和 1
c = Obstest2.new
$notifycenter.postmsg(0,"ccc")
p "over"
#有了c对象 所以也就有了ccc的绑定 这时再通知 会显示testccc了
###############################
# $scene 为有效的情况下调用 main 过程
while $scene != nil
$scene.main
end
# 淡入淡出
Graphics.transition(20)
rescue Errno::ENOENT
# 补充 Errno::ENOENT 以外错误
# 无法打开文件的情况下、显示信息后结束
filename = $!.message.sub("No such file or directory - ", "")
print("找不到文件 #{filename}。 ")
end
#==============================================================================
# ■ Main
#------------------------------------------------------------------------------
# 各定义结束后、从这里开始实际处理。
#==============================================================================
begin
# 准备过渡
# 设置系统默认字体
Font.default_name = (["黑体"])
Graphics.freeze
# 生成场景对像 (标题画面)
$scene = Scene_Title.new
################################
$notifycenter = NotifyCenter.new
a = Obstest.new(0)
$notifycenter.postmsg(0,"aaa")
$notifycenter.postmsg(0,"ccc")
p "step 1"
#通知aaa 和 ccc需求 a对象绑定了 aaa 和 bbb需求 所以 aaa对应的函数会被执行 显示test
#但并没有对象绑定ccc 所以 ccc这条消息发出去也是没意义的
b = Obstest.new(1)
$notifycenter.postmsg(0,"aaa")
$notifycenter.postmsg(0,"bbb")
p "step 2"
#通知aaa 和 bbb需求 因为 增加了b对象 所以通知aaa需求的时候 会同时通知 a 和 b对象
#先打印2个 test 再通知bbb需求 打印 0 和1
$notifycenter.removeObserver(a)#将a对象移除监听
$notifycenter.postmsg(0,"aaa")
$notifycenter.postmsg(0,"bbb")
p "step 3"
#因为a对象被移除了 所以 通知 aaa 和 bbb时 只剩下 b对象了 打印 test 和 1
c = Obstest2.new
$notifycenter.postmsg(0,"ccc")
p "over"
#有了c对象 所以也就有了ccc的绑定 这时再通知 会显示testccc了
###############################
# $scene 为有效的情况下调用 main 过程
while $scene != nil
$scene.main
end
# 淡入淡出
Graphics.transition(20)
rescue Errno::ENOENT
# 补充 Errno::ENOENT 以外错误
# 无法打开文件的情况下、显示信息后结束
filename = $!.message.sub("No such file or directory - ", "")
print("找不到文件 #{filename}。 ")
end
作者: fux2 时间: 2014-7-22 23:50
(ノ゚∀゚)ノ触手总是深夜出现
作者: 越前リョーマ 时间: 2014-7-22 23:55
虽然完全不明白是什么但是看到LZ的头像总是令我浮想联翩
作者: 小传子 时间: 2014-7-22 23:55
妈蛋完全看不懂啊
作者: yagami 时间: 2014-7-23 00:02
至于为毛要这东西 举个简单的例子 假如角色升级了 我有n个界面 要对lv进行刷新 但我又不确定 n个界面里 到底有几个是现在存在的 这时 可能会写出这样的 代码if 升级
界面1.refresh if 界面1 !=nil
界面2.refresh if 界面2 !=nil
...
end
if 升级
界面1.refresh if 界面1 !=nil
界面2.refresh if 界面2 !=nil
...
end
如果在界面生成的时候绑定监听 我在升级的时候根本不用在意 到底要刷新哪些 仅仅发一条消息就可以了
作者: 天使喝可乐 时间: 2014-7-23 00:03
给大神跪了
作者: taroxd 时间: 2014-7-23 06:22
本帖最后由 taroxd 于 2014-7-23 06:28 编辑
yagami 发表于 2014-7-23 00:02 
至于为毛要这东西 举个简单的例子 假如角色升级了 我有n个界面 要对lv进行刷新 但我又不确定 n个界面里 到 ...
我可能会写出这样的代码instance_variables.each do |ivar_name|
ivar = instance_variable_get ivar_name
ivar.refresh if ivar.respond_to? :refresh
end
instance_variables.each do |ivar_name|
ivar = instance_variable_get ivar_name
ivar.refresh if ivar.respond_to? :refresh
end
另外,不要用 nil 来表示界面不存在。
你可以使用 hide,xxx.visible = false 这些方法。
这样的话直接每个都刷新一遍就没有问题了,不需要判断是否为 nil。
因此我也会写出这样的代码
界面1.refresh
界面2.refresh
#...
界面1.refresh
界面2.refresh
#...
作者: 无脑之人 时间: 2014-7-23 09:19
给大触跪了|д゚ )
作者: IamI 时间: 2014-7-23 09:30
proc 放后面去,写成 &block。
亲以前是写Java的吧。
作者: 楼主是我的女仆 时间: 2014-7-23 10:10
我居然真的以为这个是用来监听的脚本(ノ゚∀゚)ノ
作者: 机械守护者 时间: 2014-7-23 11:00
大触这是我的膝盖
作者: 你最珍贵 时间: 2014-7-23 14:11
完全看不懂用途强烈要求发范例(σ゚∀゚)σ
作者: 晴兰 时间: 2014-7-23 23:26
提示: 作者被禁止或删除 内容自动屏蔽
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |