Project1

标题: 简单的监听机制 [打印本页]

作者: yagami    时间: 2014-7-22 23:35
标题: 简单的监听机制
为了帮小伙伴做一套炫酷的ui 所以有了这东西
RUBY 代码复制
  1. class NotifyCenter
  2.   def initialize
  3.     @obsarray = [[],[]]
  4.     @procarray = [[],[]]
  5.     @desarr = [[],[]]
  6.   end
  7.   def addObserver(obs,proc,des)#增加监听
  8.       @obsarray[obs.kind].push(obs)
  9.       if obs.kind == 1#这里预留按钮机制 触摸优先级 可以无视
  10.         @obsarray[obs.kind].sort! {|a,b|b.z - a.z}
  11.         index = @obsarray[obs.kind].index(obs)
  12.         @procarray[obs.kind].insert( index, proc)
  13.         @desarr[obs.kind].insert( index, des)
  14.       else
  15.         @procarray[obs.kind].push(proc)
  16.         @desarr[obs.kind].push(des)
  17.       end
  18.  
  19.   end
  20.   def removeObserver(obs)#移除监听
  21.     loop do
  22.       index = @obsarray[obs.kind].index(obs)
  23.       break if index == nil
  24.       @obsarray[obs.kind].delete_at(index)
  25.       @procarray[obs.kind].delete_at(index)
  26.       @desarr[obs.kind].delete_at(index)
  27.     end
  28.     #一个对象可能同时被观察多个请求 所以用了循环
  29.   end
  30.  
  31.   def postmsg(kind,des)#发送通知 对所有被监听的小伙伴 回调
  32.     for i in 0..@desarr[kind].size
  33.       if @desarr[kind][i] == des
  34.         @procarray[kind][i].call
  35.       end
  36.     end
  37.   end
  38.  
  39. end
  40. ###################testclass##############
  41. class Obstest
  42.   attr_reader   :kind
  43.   attr_reader   :testnum
  44.   def initialize(testnum)
  45.     @kind = 0
  46.     @testnum = testnum
  47.     $notifycenter.addObserver(self,Proc.new { self.test },"aaa")
  48.     $notifycenter.addObserver(self,Proc.new { self.test2 },"bbb")
  49.   end
  50.  
  51.   def test
  52.     p "test"
  53.   end
  54.   def test2
  55.     p @testnum.to_s
  56.   end
  57. end
  58.  
  59. class Obstest2
  60.   attr_reader   :kind
  61.   def initialize
  62.     @kind = 0
  63.     $notifycenter.addObserver(self,Proc.new { self.test },"ccc")
  64.   end
  65.  
  66.   def test
  67.     p "testccc"
  68.   end
  69.  
  70. end


测试代码偷懒写在main里了
RUBY 代码复制
  1. #==============================================================================
  2. # ■ Main
  3. #------------------------------------------------------------------------------
  4. #  各定义结束后、从这里开始实际处理。
  5. #==============================================================================
  6.  
  7. begin
  8.   # 准备过渡
  9.   # 设置系统默认字体
  10.   Font.default_name = (["黑体"])
  11.   Graphics.freeze
  12.   # 生成场景对像 (标题画面)
  13.   $scene = Scene_Title.new
  14.  
  15.   ################################
  16.   $notifycenter = NotifyCenter.new
  17.   a = Obstest.new(0)
  18.   $notifycenter.postmsg(0,"aaa")
  19.   $notifycenter.postmsg(0,"ccc")
  20.   p "step 1"
  21.   #通知aaa 和 ccc需求  a对象绑定了 aaa 和 bbb需求 所以 aaa对应的函数会被执行 显示test
  22.   #但并没有对象绑定ccc 所以 ccc这条消息发出去也是没意义的
  23.   b = Obstest.new(1)
  24.   $notifycenter.postmsg(0,"aaa")
  25.   $notifycenter.postmsg(0,"bbb")
  26.   p "step 2"
  27.   #通知aaa 和 bbb需求 因为 增加了b对象 所以通知aaa需求的时候 会同时通知 a 和 b对象
  28.   #先打印2个 test  再通知bbb需求 打印 0 和1
  29.   $notifycenter.removeObserver(a)#将a对象移除监听
  30.   $notifycenter.postmsg(0,"aaa")
  31.   $notifycenter.postmsg(0,"bbb")
  32.   p "step 3"
  33.   #因为a对象被移除了 所以 通知 aaa 和 bbb时 只剩下 b对象了 打印 test 和 1
  34.   c = Obstest2.new
  35.   $notifycenter.postmsg(0,"ccc")
  36.    p "over"
  37.   #有了c对象 所以也就有了ccc的绑定 这时再通知 会显示testccc了
  38. ###############################
  39.  
  40.  
  41.  
  42.   # $scene 为有效的情况下调用 main 过程
  43.   while $scene != nil
  44.     $scene.main
  45.   end
  46.   # 淡入淡出
  47.   Graphics.transition(20)
  48. rescue Errno::ENOENT
  49.   # 补充 Errno::ENOENT 以外错误
  50.   # 无法打开文件的情况下、显示信息后结束
  51.   filename = $!.message.sub("No such file or directory - ", "")
  52.   print("找不到文件 #{filename}。 ")
  53. 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个界面里 到底有几个是现在存在的  这时 可能会写出这样的 代码
RUBY 代码复制
  1. if 升级
  2. 界面1.refresh if 界面1 !=nil
  3. 界面2.refresh if 界面2 !=nil
  4. ...
  5. 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个界面里 到 ...


我可能会写出这样的代码
RUBY 代码复制
  1. instance_variables.each do |ivar_name|
  2.   ivar = instance_variable_get ivar_name
  3.   ivar.refresh if ivar.respond_to? :refresh
  4. end


另外,不要用 nil 来表示界面不存在。
你可以使用 hide,xxx.visible = false 这些方法。
这样的话直接每个都刷新一遍就没有问题了,不需要判断是否为 nil。
因此我也会写出这样的代码
RUBY 代码复制
  1. 界面1.refresh
  2. 界面2.refresh
  3. #...

作者: 无脑之人    时间: 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