-
Dec 13th, 2017, 06:53 PM
#1
[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:
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.
-
Dec 13th, 2017, 08:22 PM
#2
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
-
Dec 14th, 2017, 01:22 AM
#3
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
-
Dec 14th, 2017, 05:21 AM
#4
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)
-
Dec 14th, 2017, 09:32 AM
#5
Re: vbRichClient custom Widget Refresh (time consuming)
Originally Posted by reexre
... 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)
Originally Posted by reexre
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
-
Dec 17th, 2017, 01:56 PM
#6
Re: vbRichClient custom Widget Refresh (time consuming)
Originally Posted by Schmidt
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.
Originally Posted by Schmidt
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.
-
Dec 17th, 2017, 08:09 PM
#7
Re: vbRichClient custom Widget Refresh (time consuming)
Originally Posted by reexre
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
-
Dec 18th, 2017, 11:03 AM
#8
Re: [RESOLVED] vbRichClient custom Widget Refresh (time consuming)
thanks for the clarification
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|