Hooks and Pipelines
PYUI has two very important feature Hooks and Pipeline. Pipeline helps in sending a batched set of DOM Manipulation commands to UI.While Hooks are lossy batched channels for sending data at a fast fixed rate to UI. In this page we will discuss both of them in more detail.
Pipeline
For example you need to update 10 things in UI. Normally you will call dedicated functions for the changes 10 time. But PYUI has much better solution for this type of senarious.Rather than sending 10 different message tokens to JS.Pipeline gives a way to batch several such DOM Manipulation messages into one and send them at onces. This reduces the networking overhead significantly.
Example
Before we give the general syntax for Pipeline it is better to discuss it via a example, otherwise syntax may cause several confusions.
from PYUI.Package.PYUI import Pipeline # this import is needed
class App:
def __init__(self,obj:PYUI):
self.pyui = obj
self.p = Pipeline()
# build the pipeline for sending batch
self.p.add(self.pyui.setText)
self.p.add(self.pyui.setStyle)
self.p.add(self.pyui.setStyle)
self.p.add(self.pyui.changeClass)
example_send() # call the function for batch update
def example_send(self):
# send batched UI mutation commands
self.p.call(
[
('eid1','New text') # params for calling 1st function (setText)
('eid2','color','red') # params for calling 2nd function (setStyle)
('eid1','backgroundColor','blue') # params for calling 3rd function (setStyle)
('eid2','class_new','ADD') # params for calling 4th function (changeClass)
]
)
So the steps to use Pipeline are:
-
Make a instance of
Pipelinep = Pipeline() -
Add the
PYUIfunctions that are compatible with PipelineLook for the functions in
PYUI Libarythat haveretparameter are directly compatible withPipeline.p.add(self.pyui.function) -
When needed call pyui with list of tuple of parameters that needed to be passed to the functions
p.call( [ (parms_of_func1), (params_of_func2) . . . (params_of_func_n) ] )
When to use Pipeline
Whenever there is a need for sending a set of pre-known UI mutations it is better to use Pipeline. Also always define a pipeline ones and use it multiple times.
Bad usage
def example_send(self):
p = Pipeline()
# build the pipeline for sending batch
p.add(self.pyui.setText)
p.add(self.pyui.setStyle)
p.add(self.pyui.setStyle)
p.add(self.pyui.changeClass)
# send batched UI mutation commands
p.call(
[
('eid1','New text') # params for calling 1st function (setText)
('eid2','color','red') # params for calling 2nd function (setStyle)
('eid1','backgroundColor','blue') # params for calling 3rd function (setStyle)
('eid2','class_new','ADD') # params for calling 4th function (changeClass)
]
)
This will make Pipeline instance each time example_send is called. So better usage is to define Pipeline in a shared space like in __init__ functions and only use call inside mutating functions.
Arithmetic approach of adding targets to Pipeline
Using p.add() multiple time clutter the code. So PYUI 0.6 intoduced arithmetic approach of adding targets to pipeline
Example
p = Pipeline() + self.pyui.setText + self.pyui.setStyle + self.pyui.setStyle + self.pyui.changeClass
Is equivalent to:
p = Pipeline()
# build the pipeline for sending batch
p.add(self.pyui.setText)
p.add(self.pyui.setStyle)
p.add(self.pyui.setStyle)
p.add(self.pyui.changeClass)
Using this approach will keep your code clean and crisp
Hooks
When a batch instruction (i.e Pipeline) is to be called in a fixed interval multiple times using Hooks is better. But Hooks serve much more than just that:
-
FPS Control: Your updates might be very fast but you can control how fast (in fps) you want that to be updated in your UI. Your sensor might give results in 100 fps. But you might want to send the changes to UI at only 30 fps you can use
Hooks. -
Lossy updates: For fast updates it is needed to preserve each updates. So some updates can be dropped from being shown from UI.This improves application response
-
Higher Priority: Hook messages travel in much higher priority than normal updates. Hence the UI updates remain more clean.
-
Update on demand: The updates are only send if there is any change. For example a progressbar connected to hook the percentage to change the progress will be sent only when there is change in progress than sending it at high fps.
Example
from PYUI.Package.PYUI import Pipeline,Hook # this import is needed
import time
class App:
def __init__(self,obj:PYUI):
self.pyui = obj
self.p = Pipeline()
# build the pipeline for sending batch
self.p.add(self.pyui.setText)
self.p.add(self.pyui.setStyle)
self.p.add(self.pyui.setStyle)
self.p.add(self.pyui.changeClass)
self.h = Hook(pipe=self.p,pyui=self.pyui,fps=15)
# simulating fast updates
while True:
example_send() # call the function for batch update
time.sleep(0.01) # small pause
def example_send(self):
# send updates
self.h.update(
[
('eid1',str(time.time_ns())) # params for calling 1st function (setText)
('eid2','color','red') # params for calling 2nd function (setStyle)
('eid1','backgroundColor','blue') # params for calling 3rd function (setStyle)
('eid2','class_new','ADD') # params for calling 4th function (changeClass)
]
)
Eventhough updates are coming at 100fps the updates happen only at 15fps only.
Steps to use Hook:
-
Make a Pipeline and add the functions
-
Call
.updatefunction to update the values