Application Logic Restructuring

From ParaQ Wiki
Jump to navigationJump to search

As ParaView grows into an application framework rather than an application itself, we find that more and more custom applications developed on top of ParaView are cropping up. While many have adopted (either whole heartedly or by following some serious arm twisting) ParaView's application logic sitting in the pqCore library, due to the dependence on Qt, it cannot be used in application directly on top of server manager such as pvbatch/pvpython. However such application require the same application logic on top of the server manager to make things easy. Hence we are finding ourselves duplication code between the Qt layer and python to provide similar side effects for operations.

This sparked the need for what we are referring to as the Application Logic Layer. The goal here is to provide a layer very close to the ServerManager layer which encapsulates application behavior so that it can be easily shared among applications. At the same time it should be easily replaceable by custom logic so that applications with behavior totally different from ParaView's can still exploit the client-server and parallelism benefits provided by the Server Manager. This will allow the Server Manager to evolve into not much more than client-server-enabled-VTK broadening the domain for the applications that can adopt the ParaView framework.

Goals

  • Must be extensible/replaceable -- the most important objective is to avoid embedding ParaView behavior into the API. Think of applications like VolView and OverView which move away from ParaView's pipeline-centric world view. They should be able to use this layer by providing their own implementation. Of course, applications similar to ParaView will simply extend/override the ParaView's default layer.
  • Easy to Debug -- Server Manager layer already adds considerable depth to the debug stack. We don't want to make that even more complicated.
  • Performance should not be affected -- if not make things even faster.
  • Don't forget the plugins -- plugins can add new types of filters, representations etc. With them they should be able to provide application logic suitable for the plugin.

What are we talking about here?

One can think of this effort as moving as much code from the pqCore layer to this new Qt-independent AL layer. There are few important things that this pqCore layer currently manages:

  • default values for properties
  • Property dependencies such as: such as associating lookup tables as needed with arraynames, ensuring coloring by some array is enabled before volume rendering etc.
  • Easy access to pipeline objects such as inputs of filters, representations for sources.

The easy access logic should directly move into the Server Manager Layer. vtkSMSourceProxy should have API to access inputs, representations etc. This directly relates to the VTK layer and hence all applications can use it i.e. it's not a concept introduced by ParaView and hence not a ParaView specific logic that will hamper applications.

Default values are the tricky ones. These are not only application dependent but also proxy dependent. For example, currently the pqPipelineRepresentation goes great lengths to ensure default coloring is correct, which is totally different from the logic in pqChartRepresentation to ensure that default series are enabled correctly. ParaView also supports default values restored from settings/registry for views so that they can be configured by the user. This is totally application dependent logic. And hence cannot be the server manager layer, will have to be in the AL layer.

Another thing to remember about default values, is that users are time and again asking for functionality where the default value for a property is obtained from the server side (after RequestInformation() possibly), can we support that?

Same is the case with property dependencies -- application dependent logic and hence should be in the AL layer.

Design

Easy Access

It's of utmost importance to be able to traverse the pipeline easily in server manager. Currently one has to use properties. Also, we need to know when the pipeline changes i.e. inputs are removed/added etc. So we need signals (not silly VTK events).

We could simply add API to vtkSMSourceProxy however the "easy access" requirement goes beyond upstream/downstream pipeline objects. For representations, we need easy access to the LUT, for LUT we need easy access to the scalar bar etc.

There are two solutions:

  • We can simply punt on these non-pipeline connections and say that the application has to use SM properties for those. Then vtkSMSourceProxy can have convenience API upstream/downstream connections and signals when they are changed.
  • We create a light-weight helper: think of is a specialized vtkSMPropertyHelper for the proxy. It has methods to get/set some values on some properties of the proxies as well as signals when they change. There will be different types of these helpers eg. vtkSMFilterHelper(), vtkSMRenderedRepresentationHelper(), vtkSMChartRepresentationHelper(). These must be very light weight. They just consolidate code for getting/setting properties and relay signals for changes to them. When an application entity is interested in the time when the input of a particular filter changes, it simply creates a vtkSMFilterHelper() for that filter proxy and listens to the modified signals. These helpers are different from the current pqProxy (and subclasses) in a couple of major ways: there is no one-to-one associate between a proxy and its helper; the helper does not change default property values or any such. This also has another advantage: it provides for an easily extensible setup for dealing with property associations e.g. changing coloring to color by array, means, we need a lookup table etc. We may also want to consider a factory based instantiation for these helpers to make it easy for plugins/applications to tweak behaviors eg. in my application you use a special global pool to setup the lookup table different than what ParaView uses.

Property Associations

If we go with the helpers approach for Easy Access, we won't have to do anything special for this. The helper can provide logic to manage the property dependencies.

Default Values

Solution A

Properties need to have notion of "auto-generated" value and "user-generated" value. Deafult values, both compile-time, as well as run-time defaults are auto-generated values. If the user sets the value of a property to a value which is same as the current auto-generated value, it should still realize that it's a user-generated value. If the user then undoes, then the property should realize that it's now set to the auto-generated value.

Solution B

Think harder.