Python 使用模态运算符进行网络解码

Python Network Decode with Modal Operator

我是从 Blender 交易所提到这个社区的,因为我的问题更具体地涉及 Python 算法。

我正在编写一个脚本,该脚本读取网络数据包以修改 Blender 中灯光的发射强度。为了在从网络读取的同时使用 UI,我创建了一个模态运算符:

class BlenDMX(bpy.types.Operator):
    bl_idname = ".blendmx"
    bl_label = "BlenDMX"
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    _updating = False
    _timer = None  

    def modal(self, context, event):
        if event.type == 'TIMER' and not self._updating:
            self._updating = True
            #Here is where i would read the data from the network and modify the lights. 
            #I will spare you those details for now...
            self._updating = False
    return {'PASS_THROUGH'}

    def execute(self, context):
        context.window_manager.modal_handler_add(self)
        self._updating = False
        self._timer = context.window_manager.event_timer_add(0.5, context.window)
        port = 6454
        self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.s.bind(("127.0.0.1", port))
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        self._timer = None
        return {'CANCELLED'}

def register():
    bpy.utils.register_class(BlenDMX)

def unregister():
bpy.utils.unregister_class(BlenDMX)

if __name__=="__main__":
    register()

不幸的是,0.5 秒对于正确处理这些数据包来说太慢了,但是像 0.1 这样的东西会锁定 UI,首先会破坏模态运算符的目的。

我的想法是检查相邻的一组网络数据包是否相同,这意味着我的数据流暂时"settled."我可以找出逻辑但不确定如何使用它使模态操作员释放控制权回到 UI。然后我还需要检查数据何时变为 "unsettled" 所以我知道 运行 再次快速连续解码,允许 UI 暂时锁定。

同样,我可以计算出扫描相邻数据包的逻辑,但我不确定将该代码放在哪里以及调用什么来实现这种可变解码速度。感谢您的帮助!

超级简单的修复!我的光更新代码已经有一个检测相同数据包的方法,所以我所要做的就是重新定义模态的定时器,当两个数据包相同时进入"decode mode":

#if two packets are identical (UI Mode):
    context.window_manager.event_timer_remove(self._timer)             
    self._timer = context.window_manager.event_timer_add(0.5, context.window)
#otherwise (Decode Mode):
    context.window_manager.event_timer_remove(self._timer)             
    self._timer = context.window_manager.event_timer_add(0.001, context.window)