Results 1 to 8 of 8

Thread: [RESOLVED] vbRichClient custom Widget Refresh (time consuming)

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Sep 2010
    Location
    Italy
    Posts
    678

    Resolved [RESOLVED] vbRichClient custom Widget Refresh (time consuming)

    A question about custom widgets of vbRichClient

    More precisely I'm looking for a help about PhotoModularFX

    (Maybe only @olaf can answer....)

    In this project I have a cfMain as standard RC form.
    Code:
    Public WithEvents Form As cWidgetForm
    Private NODE() As cwNode
    In it I have an array of "NODES" cwNode that have the basic widget declarations:
    Code:
    Private WithEvents W As cWidgetBase
    Public Property Get Widget() As cWidgetBase: Set Widget = W: End Property
    Public Property Get Widgets() As cWidgets: Set Widgets = W.Widgets: End Property
    My problem is that during processing, each node should "display" somehow (in my case with a green botton to up fill color) the progress it is doing.

    So while a node is doing its job a "Setprogress" sub is called. (not much often)
    This sub, among other things have to visually update the Node progress, so the node have to be refreshed/ (re-drawn).

    To refresh it, I use:
    Code:
     NODE(i).Widget.Refresh
    In the IDE I can see that every time a NODE is refreshed (with above code line)
    following line of code in cwNode is called (looply) many many times
    Code:
    Public Property Get Widget() As cWidgetBase: Set Widget = W: End Property
    This cause a very huge slow down during process, and it is the problem I'm trying to resolve...

    By the way,
    drawing a NODE is not much time consuming, I can see this by checking the option button "Auto Arrange" in the panel.
    Nodes are moved with NODE(i).Widget.Move (and they move fast)

    So, moving a custom widget is very much faster than refreshing it.
    I don't know why this happens , maybe my code has some bug.


    I tried to resolve it this way:
    on cwNode set W to public
    Code:
    Public WithEvents W As cWidgetBase
    and refreshing so:
    Code:
     NODE(i).W.Refresh
    but nothing changed. problem remains the same.
    Code:
    Public Property Get Widget() As cWidgetBase: Set Widget = W: End Property
    Called many many many times........


    Hope for help.

  2. #2
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: vbRichClient custom Widget Refresh (time consuming)

    I remember your "Setup of Node-Widgets", which in principle is layed out like that Demo here:
    http://www.vbforums.com/showthread.p...r-Connections)

    And no, accessing the Widget-Property on a given cwClass over:
    Code:
    Public Property Get Widget() As cWidgetBase: Set Widget = W: End Property
    is not the cause for the slow-down.

    It's in all likelihood the frequency, how often per second you call:
    Code:
     NODE(i).Widget.Refresh
    from your Progress-Events.
    (especially, when you do a loop over the entire Node-Widget-Array each time).

    I would solve that by simply refreshing the whole Form.WidgetRoot cyclically,
    using a timer with an interval-frequency of only 5Hz (200msec) or so, as long
    as there are "ongoing processing-activities" on the whole Node-Tree.

    Each single Node-Refresh will likely cause a refresh of the entire Canvas anyways
    (because the Node-Widgets themselves are transparent with Alpha, and might overlap) -
    so you will not loose performance by refreshing the whole Node-Container instead.

    Just set a Progress-State-Variable inside your Node-Widgets (without doing any specific
    Node-Widget-Refresh whilst setting the Node(i).Progress-Property), because any 200msec
    or so, the whole NodeTree will be re-rendered "in a single swoop" by your timer-triggered
    Container-Refresh.

    Refreshing the whole Node-Parent-Canvas any 200msec should not take-up too much time from your
    ImageProcessing-tasks which happen "across the Nodes".

    Just make sure, you disable the described "Progress-Timer" after you reached your "EndNode".

    Olaf

  3. #3
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: vbRichClient custom Widget Refresh (time consuming)

    Just played that through on the old Demo (with the suggestions from above) -
    adding a few Extra-Nodes and -Node-Connections, then enhancing a simple Property:
    Public Percent As Double
    on the cwNode-Class and implementing appropriate Rendering for this State-Prop in its Paint-Event.

    Then I've put a:
    Private WithEvents tmrProgress as cTimer
    into the Form-Class, and the following Test-code into its Event-Handler:
    Code:
    Private Sub tmrProgress_Timer()
      Static p As Long, i As Long
      For i = 1 To UBound(N)
        N(i).Progress = p / 100 'here only a State-Prop is updated (no Refresh)
      Next
      p = (p + 1) Mod 100
      Form.WidgetRoot.Widget.Refresh ' a single, "whole Canvas"-Refresh
    End Sub
    The time above was started within a Form_DoubleClick Event (then running with 100msec a "10 FPS" RefreshRate.

    With a Form-Size as shown below:

    the wind-TaskManager has shown between 0%-1% CPU-Load.

    After switching the Form (and thus the Root-Canvas) to FullScreen, the CPU-Load was between 1% and 2%.
    (so it seems, that the GUI should leave you enough "breathing-space" - for your other, CPU-intensive calculations).

    Olaf

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Sep 2010
    Location
    Italy
    Posts
    678

    Re: vbRichClient custom Widget Refresh (time consuming)

    THANK YOU very much !!!

    I resolved thanks to your help.
    At the moment I prefer not to put a timer (even if it should be a good solution), but just refresh all
    when a SetProgress is called (I try not to call it much often, just at 0% and 100& plus few intermediate values)
    [it is called one node at a time]

    Let me say that this behaviour is not so intuitive, it's very strange that refreshing the whole container
    Form.WidgetRoot.Widget.Refresh
    is very much faster than refreshing a single "Node"
    NODE(i).Widget.Refresh

    Anyway it works! Thanks!

    (just a small doubt: I see that in works even with .Canvas.Widget.Refresh, time-consuming difference is not sensitive, but maybe one is better than the other)

  5. #5
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: vbRichClient custom Widget Refresh (time consuming)

    Quote Originally Posted by reexre View Post
    ... this behaviour is not so intuitive, it's very strange that refreshing the whole container
    Form.WidgetRoot.Widget.Refresh
    is very much faster than refreshing a single "Node"
    NODE(i).Widget.Refresh
    Since you wrote Node(i).Widget.Refresh, I assume that you were doing a Loop over i (refreshing all Nodes)?
    If yes, then you have your explanation already (why it is slower this way).

    I've just tested this in my little Demo-Project - and when I really refresh only
    a single Node in my Test-Timer - as e.g. NODE(3).Widget.Refresh, then I see no decrease in performance
    (compared to refreshing the Root- or the Canvas-Container-Widget).

    Just keep in mind, that a Widget-Rendering-Engine which supports Widget.Alpha and Widget.BackColor = -1 (no BackColor) -
    even across nested (potentially overlapping) Widgets, the rules one knows from other "non-alpha-supporting" Child-Control-Engines
    (which work with invalidated Regions and simple Clipping) are a bit different.

    Sometimes I have no other choice than to "go back to the Parent-Widget and refresh that" (including
    an automatic internal Refresh-Cascade over all its Child-Widgets).

    As a general rule with Alpha-Widgets:
    If you foresee, that you have to do "larger Refreshs-causing Actions on multiple Children in a Loop"
    (e.g. resizing them, moving them - setting new Backgrounds on them, adding new ones - or whatever),
    you are often better off with a:
    Code:
      ParentContainer.Widget.Lockrefresh = True
          '... now do all your potentially Child-Refreshs triggering, multiple actions on multiple Children
      ParentContainer.Widget.Lockrefresh = False '<- this will automatically do also a refresh on the previously locked Container (also on the now re-arranged Children)
    Quote Originally Posted by reexre View Post
    I see that in works even with .Canvas.Widget.Refresh, time-consuming difference is not sensitive, but maybe one is better than the other)
    Yes, if the Canvas is the direct Parent of your Node-Widgets, then this is a bit less
    straining for the WidgetEngine than a refresh on the Root-Widget itself.

    Olaf

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Sep 2010
    Location
    Italy
    Posts
    678

    Re: vbRichClient custom Widget Refresh (time consuming)

    Quote Originally Posted by Schmidt View Post
    Since you wrote Node(i).Widget.Refresh, I assume that you were doing a Loop over i (refreshing all Nodes)?
    If yes, then you have your explanation already (why it is slower this way).
    No, only 1 node at a time is "Running", so only (i)one is(was) refreshed.

    Quote Originally Posted by Schmidt View Post
    Yes, if the Canvas is the direct Parent of your Node-Widgets, then this is a bit less
    straining for the WidgetEngine than a refresh on the Root-Widget itself.
    structure:
    Code:
    inside cFMain:
            -Form    (cWidgetForm)
            -Node(i)    (array of cwNode)
            -Canvas (cwCanvas)  , mainly draws connections
    Nodes are children of cFmain, not canvas, but
    Code:
    fMain.Form.WidgetRoot.Widget.Refresh     
    fMain.Canvas.Widget.Refresh
    the above lines seems to have no difference, both refresh all nodes without slowdown.




    I take the chance to let you know about PhotoModularFX (ZIP WEB) update:
    Update 0.3.580 (18-Dec-2017)
    [Nodes]
    -NEW: Stretch;Stretch3: Histogram Stretch.
    -NEW: ToneMap,ToneMap3: Tone Mapping for 1 and 3 channels.
    -Blur;Blur3: Added BOX blur Algo.
    -StdDEV;stdDEV3 (Standard Deviation): Really a lot Faster
    -LocalHEii: Little faster
    -VRCLAHE: Algo retouch
    -BilaOAEX: Pyramids without cairo
    -Normalize;Normalize3: Now output range can be not clamped 0-1
    -MtBlur;MtBlur3: small bug fix
    -Ramp: Bug fix on RepatMode:Standard (Left-Right;Up-Down)
    -RGB>HSL;HSL>RGB: Added HSV colorspace conversion.
    [Other]
    -Sound: Added checkbox to turn "ready output" sound on/off.
    -GUI: Little restyles, lighter nodes and draw speedup.

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: vbRichClient custom Widget Refresh (time consuming)

    Quote Originally Posted by reexre View Post

    structure:
    Code:
    inside cFMain:
            -Form    (cWidgetForm)
            -Node(i)    (array of cwNode)
            -Canvas (cwCanvas)  , mainly draws connections
    Nodes are children of cFmain, not canvas, ...
    In the old example they are ... so I would check that...
    Also in my example, the Nodes-Array is directly available in an Array, declared at cfMain-Class-Level.

    But that's not the thing you will need to look-up, to determine Parent-Child-Relations "Widget-wise".
    It's the ...Widgets.Add.call which determines these...:
    - if the Nodes-Array is populated per Canvas.Widgets.Add, then the Nodes are (visually and renderwise) children of the Canvas-Widget.
    - if the Nodes-Array is populated per Form.Widgets.Add, then the Nodes are (visually and renderwise) children of the Form-Objects WidgetRoot.

    Olaf

  8. #8

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width