Search code examples
pythonnetwork-programmingblender

Python Network Decode with Modal Operator


I was referred to this community from the Blender exchange as my question regards a Python algorithm more specifically.

I am working on a script that reads network packets to modify the emission strength of lights in Blender. In order to use the UI at the same time as reading from the network, I have created a modal operator:

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

Unfortunately, 0.5 seconds is too slow for proper processing of these packets, but something like 0.1 will lock up the UI, defeating the purpose of the modal operator in the first place.

My thought is to check to see if an adjacent group of network packets are identical, which would mean my data stream has temporarily "settled." I can work out the logic for that but am unsure how to use it to make the modal operator release control back to the UI. I would also need to then check for when data becomes "unsettled" so I know to run the decodes in rapid succession again, allowing the UI to temporarily lock up.

Again, I can work out the logic for scanning adjacent packets, but I am unsure of where to put that code and what to call to implement this variable decode speed. Your help is appreciated!


Solution

  • Super simple fix here! My light updating code already has a detection method for identical data packets, so all I had to do was re-define the modal's timer to go into "decode mode" when two packets are identical:

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