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

时间:2018-10-20 15:45:55

标签: python network-programming blender

我从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,一开始就破坏了模式运算符的作用。

我的想法是检查一组相邻的网络数据包是否相同,这意味着我的数据流已暂时“稳定”。我可以为此设计出逻辑,但不确定如何使用它来使模式运算符将控制权释放回UI。然后,我还需要检查数据何时变得“不稳定”,以便知道再次快速连续运行解码,从而允许UI暂时锁定。

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

1 个答案:

答案 0 :(得分:0)

这里的超级简单修复!我的灯光更新代码已经具有对相同数据包的检测方法,因此,我要做的就是重新定义模版的计时器,以便在两个数据包相同时进入“解码模式”:

#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)