设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 4231|回复: 8

[原创发布] 获取Fiber实例的状态编号,定义alive?

[复制链接]

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
39518
在线时间
7481 小时
注册时间
2009-7-6
帖子
13482

开拓者贵宾

发表于 2017-12-4 20:54:41 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
根据官方文档:http://ruby-doc.org/core-2.2.0/Fiber.html
使用fiber实例的alive?方法需要
You need to require 'fiber' before using this method.

有时候VA里也需要这么个操作,所以就出现了下面的玩意儿
思路也很简单,因为在resume一个status为TERMINATED的fiber时,会抛出dead fiber异常,
也就是说本身Fiber就存在判定自身状态的方法。通过这个提示的位置逆向出储存状态编号的地址,接着根据官方提供的源码逻辑,来定义alive?方法

RUBY 代码复制
  1. class Fiber
  2.  
  3.   Memcopy = Win32API.new('kernel32','RtlMoveMemory','pll','l')
  4.  
  5.   CREATING = 0
  6.   RUNNING = 1
  7.   TERMINATED = 2
  8.  
  9.   def status
  10.     buf = "\0"*4
  11.     Memcopy.call(buf,self.object_id*2+16,4)
  12.     objPtr = buf.unpack("L").first
  13.     return 0 if objPtr == 0
  14.     Memcopy.call(buf,objPtr+480,4)
  15.     return buf.unpack("L").first
  16.   end
  17.  
  18.   def alive?
  19.     return self.status != TERMINATE
  20.   end
  21.  
  22. end



评分

参与人数 2+2 收起 理由
魔法☆梅莉 + 1 666
⑨姐姐 + 1 我很赞同,精品文章,认可答案.

查看全部评分

RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托

Lv5.捕梦者 (版主)

梦石
28
星屑
10170
在线时间
4673 小时
注册时间
2011-8-22
帖子
1279

开拓者

发表于 2017-12-5 08:59:55 | 显示全部楼层
也来回复一下自己写的不用黑科技的#alive,以及带了个::current和::fork

RUBY 代码复制
  1. class Fiber
  2.   @@call_stack = []
  3.  
  4.   attr_accessor :alive
  5.   attr_accessor :children
  6.  
  7.   alias old_initialize initialize
  8.   def initialize(&block)
  9.     old_initialize(&block)
  10.     @alive = true
  11.     @children = []
  12.   end
  13.  
  14.   def self.current
  15.     @@call_stack.last
  16.   end
  17.  
  18.   alias old_resume resume
  19.   def resume
  20.     @@call_stack.push(self)
  21.     @children.each { |child|
  22.       child.resume
  23.     }
  24.     @children.delete_if { |child|
  25.       !child.alive
  26.     }
  27.     begin
  28.       old_resume
  29.     rescue FiberError => e
  30.       @alive = false
  31.     end
  32.     @@call_stack.pop
  33.   end
  34.  
  35.   def self.fork(&block)
  36.     if Fiber.current
  37.       child = Fiber.new(&block)
  38.       Fiber.current.children << child
  39.       child.resume
  40.     end
  41.   end
  42. end


测试代码

评分

参与人数 1+1 收起 理由
fux2 + 1 精品文章

查看全部评分

回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9275
在线时间
2504 小时
注册时间
2011-5-20
帖子
15389

开拓者

发表于 2017-12-5 14:09:01 | 显示全部楼层
和dead取反的区别是什么呢?

点评

如果存在dead的话,没有  发表于 2017-12-5 16:13
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
4583
在线时间
1205 小时
注册时间
2016-4-7
帖子
982

开拓者

发表于 2017-12-5 20:39:49 | 显示全部楼层
  1.       @fiber = Fiber.new do
  2.         @callback.call(helper, info)
  3.         @fiber = nil
  4.       end
复制代码


弱鸡如我就用这样的土办法了

点评

嗯 主要还是我当时用fiber的地方是用个类对原版fiber做过包装的 所以实际上也没啥重复工作量233 思路上其实和9姐姐alias initialize差不多  发表于 2017-12-6 16:05
单纯为了减少重复工作量  发表于 2017-12-6 10:10
附庸的附庸不是我的附庸,女儿的女儿还是我的女儿。CK2沉迷ing
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

发表于 2021-5-24 08:58:55 | 显示全部楼层
本帖最后由 guoxiaomi 于 2021-5-26 16:17 编辑

写了几天上论坛一搜Fiber,果然造了轮子……本意是准备写一个桌游模拟器,但是想在游戏主流程结算卡住的时候也能打开菜单或者播放动画等,所以决定使用Fiber。
然后发现坑爹的rgss3居然没有alive?和current方法,跟文档上不一致啊哭……

Fiber_Tree

定义好process后,简单的写一个scene就可以调用了。Fiber有3种唤起模式:start,join,listen。Fiber.yield里抛出一个lambda表达式作为此fiber的苏醒条件。

2021/05/26:修复了几个BUG。黄鸡说得对,这种东西自己实现一遍理解会更深。这些代码就给后来的人做个参考吧。

点评

造轮子不是坏事,做过理解更深  发表于 2021-5-25 06:15

评分

参与人数 1+1 收起 理由
fux2 + 1 塞糖

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-16 22:45

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表