Philippe Lang
2006-Oct-03 15:34 UTC
[fxruby-users] FXDataTarget & widget value update delay
Hi, When assigning a new value to an FXDataTarget programmatically, it takes a certain time for the widget linked to this FXDataTarget to be updated, just as if there was some sort of "polling" inside the framework. Delay can be as long as 1 second sometimes. Why aren''t the widgets updated straight away? --------------- Philippe Lang Attik System -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3125 bytes Desc: not available Url : http://rubyforge.org/pipermail/fxruby-users/attachments/20061003/49ae9bb9/attachment.bin
Joel VanderWerf
2006-Oct-03 17:18 UTC
[fxruby-users] FXDataTarget & widget value update delay
Philippe Lang wrote:> Hi, > > When assigning a new value to an FXDataTarget programmatically, it > takes a certain time for the widget linked to this FXDataTarget to be > updated, just as if there was some sort of "polling" inside the > framework. Delay can be as long as 1 second sometimes. Why aren''t the > widgets updated straight away?This is one reason I wrote foxtails: http://redshift.sourceforge.net/foxtails/ http://redshift.sourceforge.net/foxtails/doc/api/index.html See the examples dir. Also, it has a more ruby-like interface (IMO). -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
Jeroen van der Zijp
2006-Oct-03 18:24 UTC
[fxruby-users] FXDataTarget & widget value update delay
On Tuesday 03 October 2006 10:34, Philippe Lang wrote:> Hi, > > When assigning a new value to an FXDataTarget programmatically, it takes a certain time for the widget linked to this FXDataTarget to be updated, just as if there was some sort of "polling" inside the framework. Delay can be as long as 1 second sometimes. Why aren''t the widgets updated straight away?The GUI gets updated when the event loop is about to block for events; as long as there are events [keyboard, mouse, repaints, etc], the event loop processes those with priority. When all queued-up events have been processed, one would normally go to a blocking state [i.e. yield the CPU in some system call waiting on the event queue]. In FOX we don''t yield YET; we instead iterate over the widget tree, and send a SEL_UPDATE to the target of each widget. Once we''ve gone through the entire widget tree, THEN we block and yield the CPU. Of course, each time we update one widget, we check for events again, to ensure that the application reacts instantly when something happens. The updating process is therefore mostly invisible in the sense that interactive performance is not affected by it:- the only time we do updates is when there''s nothing else we would be doing anyway. However, this does have a few repercussions on the frequency of updates; in a very busy system with a large number of widgets it may take some time before an entire cycle through the widget tree is completed. For this reason, its important to keep the update-handlers small and to avoid unnecessary work in then whenever possible. The code in getNextEvent() is finely tuned to get great performance, but of course I''m not the one writing the update handlers! That is up to the software developer himself; it helps to know what to do and what to avoid. Hence this mail. Regards - Jeroen
Lyle Johnson
2006-Oct-03 18:24 UTC
[fxruby-users] FXDataTarget & widget value update delay
On Oct 3, 2006, at 10:34 AM, Philippe Lang wrote:> When assigning a new value to an FXDataTarget programmatically, it > takes a certain time for the widget linked to this FXDataTarget to > be updated, just as if there was some sort of "polling" inside the > framework. Delay can be as long as 1 second sometimes. Why aren''t > the widgets updated straight away?The update of a widget''s settings due to a change in a data target''s value is handled by FOX''s GUI update mechanism, described here: http://www.fox-toolkit.org/guiupdate.html This process only kicks in during idle time in the GUI, so there''s inevitably going to be some small delay. The problem is compounded in FXRuby due to the overhead required for converting back and forth between C++ objects and Ruby objects, as well as scheduling Ruby threads. If your FXRuby application doesn''t use any threads, you can try turning off FXRuby''s support for scheduling Ruby threads by calling the FXApp''s disableThreads() method: app.disableThreads Yet another option, but one which sort-of defeats the purpose of the GUI update process, is to call forceRefresh() directly whenever you make a change to the data target''s value, e.g. datatarget.value = "Foo" app.forceRefresh Calling forceRefresh() causes the application to immediately start the GUI update process without waiting for idle time. Hope this helps, Lyle
Philippe Lang
2006-Oct-03 20:40 UTC
[fxruby-users] FXDataTarget & widget value update delay
Jeroen van der Zijp wrote:> On Tuesday 03 October 2006 10:34, Philippe Lang wrote: >> Hi, >> >> When assigning a new value to an FXDataTarget > programmatically, it takes a certain time for the widget > linked to this FXDataTarget to be updated, just as if there > was some sort of "polling" inside the framework. Delay can be > as long as 1 second sometimes. Why aren''t the widgets updated > straight away? > > The GUI gets updated when the event loop is about to block > for events; as long as there are events [keyboard, mouse, > repaints, etc], the event loop processes those with priority. > > When all queued-up events have been processed, one would > normally go to a blocking state [i.e. yield the CPU in some > system call waiting on the event queue]. In FOX we don''t > yield YET; we instead iterate over the widget tree, and send > a SEL_UPDATE to the target of each widget. > > Once we''ve gone through the entire widget tree, THEN we block > and yield the CPU. Of course, each time we update one > widget, we check for events again, to ensure that the > application reacts instantly when something happens. > > The updating process is therefore mostly invisible in the > sense that interactive performance is not affected by it:- > the only time we do updates is when there''s nothing else we would be > doing anyway. > > However, this does have a few repercussions on the frequency > of updates; in a very busy system with a large number of > widgets it may take some time before an entire cycle through the > widget tree is completed. > > For this reason, its important to keep the update-handlers > small and to avoid unnecessary work in then whenever possible. > > The code in getNextEvent() is finely tuned to get great > performance, but of course I''m not the one writing the update > handlers! That is up to the software developer himself; it > helps to know what to do and what to avoid. Hence this mail.Hi, thanks for your answer! Following your explanation, I finally decided to refresh my widgets manually, when speed is a concern, simply by sending them a SEL_UPDATE message, just after the data target was changed, programatically: <widget>.handle(self, FXSEL(SEL_UPDATE, 0), nil) Works just fine, widgets get updated instantaneously now. But really, I still do not understand why the widget refresh is so slow, and so "random". Sometimes very quick, sometimes near a second. I don''t have a Pentium II 166 with 16MB RAM, I can assure you, and the application is not that big for the moment. Maybe it''s a "Ruby" effect? --------------- Philippe Lang Attik System -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3125 bytes Desc: not available Url : http://rubyforge.org/pipermail/fxruby-users/attachments/20061003/2d8c5e97/attachment-0001.bin
Philippe Lang
2006-Oct-03 21:51 UTC
[fxruby-users] FXDataTarget & widget value update delay
Jeroen van der Zijp wrote:> On Tuesday 03 October 2006 10:34, Philippe Lang wrote: >> Hi, >> >> When assigning a new value to an FXDataTarget > programmatically, it takes a certain time for the widget > linked to this FXDataTarget to be updated, just as if there > was some sort of "polling" inside the framework. Delay can be > as long as 1 second sometimes. Why aren''t the widgets updated > straight away? > > The GUI gets updated when the event loop is about to block > for events; as long as there are events [keyboard, mouse, > repaints, etc], the event loop processes those with priority. > > When all queued-up events have been processed, one would > normally go to a blocking state [i.e. yield the CPU in some > system call waiting on the event queue]. In FOX we don''t > yield YET; we instead iterate over the widget tree, and send > a SEL_UPDATE to the target of each widget. > > Once we''ve gone through the entire widget tree, THEN we block > and yield the CPU. Of course, each time we update one > widget, we check for events again, to ensure that the > application reacts instantly when something happens. > > The updating process is therefore mostly invisible in the > sense that interactive performance is not affected by it:- > the only time we do updates is when there''s nothing else we would be > doing anyway. > > However, this does have a few repercussions on the frequency > of updates; in a very busy system with a large number of > widgets it may take some time before an entire cycle through the > widget tree is completed. > > For this reason, its important to keep the update-handlers > small and to avoid unnecessary work in then whenever possible. > > The code in getNextEvent() is finely tuned to get great > performance, but of course I''m not the one writing the update > handlers! That is up to the software developer himself; it > helps to know what to do and what to avoid. Hence this mail.Hi again, I wrote a test application that updates the widget tree with: def update(window) window.handle(self, FXSEL(SEL_UPDATE, 0), nil) window.children().each { |child| update(child) } end This is much faster than waiting for the framework to issue a SEL_UPDATE to the widgets of the window. You can see the difference visually. I''m not sure if this kind of code can be included in FXRuby directly? Cheers, Philippe ----------------------------------------------- #!/usr/bin/ruby require ''fox16'' include Fox class MyWindow < FXMainWindow def initialize(app) super(app, "Window", nil, nil, DECOR_ALL, 0, 0, 500, 500) # Menu bar stretched along the top of the main window menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X) # File menu filemenu = FXMenuPane.new(self) FXMenuTitle.new(menubar, "&File", nil, filemenu) FXMenuCommand.new(filemenu, "&Quit\tCtl-Q\tQuit the application", nil, app, FXApp::ID_QUIT) # Frames frame1 = FXMatrix.new(self, 4, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) frame2 = FXMatrix.new(frame1, 4, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) frame3 = FXMatrix.new(frame2, 4, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) frame4 = FXMatrix.new(frame3, 4, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) frame5 = FXMatrix.new(frame4, 4, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED) @w1 = FXTextField.new(frame1, 5) FXTextField.new(frame1, 5) FXTextField.new(frame1, 5) FXTextField.new(frame1, 5) FXTextField.new(frame1, 5) FXTextField.new(frame1, 5) FXTextField.new(frame1, 5) @w2 = FXTextField.new(frame2, 5) FXTextField.new(frame2, 5) FXTextField.new(frame2, 5) FXTextField.new(frame2, 5) FXTextField.new(frame2, 5) FXTextField.new(frame2, 5) FXTextField.new(frame2, 5) @w3 = FXTextField.new(frame3, 5) FXTextField.new(frame3, 5) FXTextField.new(frame3, 5) FXTextField.new(frame3, 5) FXTextField.new(frame3, 5) FXTextField.new(frame3, 5) FXTextField.new(frame3, 5) @w4 = FXTextField.new(frame4, 5) FXTextField.new(frame4, 5) FXTextField.new(frame4, 5) FXTextField.new(frame4, 5) FXTextField.new(frame4, 5) FXTextField.new(frame4, 5) FXTextField.new(frame4, 5) @w5 = FXTextField.new(frame5, 5) FXTextField.new(frame5, 5) FXTextField.new(frame5, 5) FXTextField.new(frame5, 5) FXTextField.new(frame5, 5) @dt1 = FXDataTarget.new("1") @dt2 = FXDataTarget.new("1") @dt3 = FXDataTarget.new("1") @dt4 = FXDataTarget.new("1") @dt5 = FXDataTarget.new("1") @w1.target = @dt1 @w1.selector = FXDataTarget::ID_VALUE @w2.target = @dt2 @w2.selector = FXDataTarget::ID_VALUE @w3.target = @dt3 @w3.selector = FXDataTarget::ID_VALUE @w4.target = @dt4 @w4.selector = FXDataTarget::ID_VALUE @w5.target = @dt5 @w5.selector = FXDataTarget::ID_VALUE add_button = FXButton.new(frame5, "Add 1 with individual SEL_UPDATE") add_button.connect(SEL_COMMAND) do |sender, selector, data| @dt1.value = @dt1.value.to_i + 1 @dt2.value = @dt2.value.to_i + 1 @dt3.value = @dt3.value.to_i + 1 @dt4.value = @dt4.value.to_i + 1 @dt5.value = @dt5.value.to_i + 1 @w1.handle(self, FXSEL(SEL_UPDATE, 0), nil) @w2.handle(self, FXSEL(SEL_UPDATE, 0), nil) @w3.handle(self, FXSEL(SEL_UPDATE, 0), nil) @w4.handle(self, FXSEL(SEL_UPDATE, 0), nil) @w5.handle(self, FXSEL(SEL_UPDATE, 0), nil) end add_button2 = FXButton.new(frame5, "Add 1 with recursive SEL_UPDATE") add_button2.connect(SEL_COMMAND) do |sender, selector, data| @dt1.value = @dt1.value.to_i + 1 @dt2.value = @dt2.value.to_i + 1 @dt3.value = @dt3.value.to_i + 1 @dt4.value = @dt4.value.to_i + 1 @dt5.value = @dt5.value.to_i + 1 update(self) end def update(window) window.handle(self, FXSEL(SEL_UPDATE, 0), nil) window.children().each { |child| update(child) } end add_button3 = FXButton.new(frame5, "Add 1 without SEL_UPDATE") add_button3.connect(SEL_COMMAND) do |sender, selector, data| @dt1.value = @dt1.value.to_i + 1 @dt2.value = @dt2.value.to_i + 1 @dt3.value = @dt3.value.to_i + 1 @dt4.value = @dt4.value.to_i + 1 @dt5.value = @dt5.value.to_i + 1 end end def create super show(PLACEMENT_SCREEN) end end if __FILE__ == $0 application = FXApp.new("Attik System", "FXRuby Test") MyWindow.new(application) application.create application.run end --------------- Philippe Lang Attik System -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3125 bytes Desc: not available Url : http://rubyforge.org/pipermail/fxruby-users/attachments/20061003/2a18338a/attachment.bin
Jeroen van der Zijp
2006-Oct-04 00:22 UTC
[fxruby-users] FXDataTarget & widget value update delay
On Tuesday 03 October 2006 15:40, Philippe Lang wrote:> Jeroen van der Zijp wrote: > > On Tuesday 03 October 2006 10:34, Philippe Lang wrote: > >> Hi, > >> > >> When assigning a new value to an FXDataTarget > > programmatically, it takes a certain time for the widget > > linked to this FXDataTarget to be updated, just as if there > > was some sort of "polling" inside the framework. Delay can be > > as long as 1 second sometimes. Why aren''t the widgets updated > > straight away? > > > > The GUI gets updated when the event loop is about to block > > for events; as long as there are events [keyboard, mouse, > > repaints, etc], the event loop processes those with priority. > > > > When all queued-up events have been processed, one would > > normally go to a blocking state [i.e. yield the CPU in some > > system call waiting on the event queue]. In FOX we don''t > > yield YET; we instead iterate over the widget tree, and send > > a SEL_UPDATE to the target of each widget. > > > > Once we''ve gone through the entire widget tree, THEN we block > > and yield the CPU. Of course, each time we update one > > widget, we check for events again, to ensure that the > > application reacts instantly when something happens. > > > > The updating process is therefore mostly invisible in the > > sense that interactive performance is not affected by it:- > > the only time we do updates is when there''s nothing else we would be > > doing anyway. > > > > However, this does have a few repercussions on the frequency > > of updates; in a very busy system with a large number of > > widgets it may take some time before an entire cycle through the > > widget tree is completed. > > > > For this reason, its important to keep the update-handlers > > small and to avoid unnecessary work in then whenever possible. > > > > The code in getNextEvent() is finely tuned to get great > > performance, but of course I''m not the one writing the update > > handlers! That is up to the software developer himself; it > > helps to know what to do and what to avoid. Hence this mail. > > Hi, thanks for your answer! > > Following your explanation, I finally decided to refresh my widgets manually, when speed is a concern, simply by sending them a SEL_UPDATE message, just after the data target was changed, programatically: > > <widget>.handle(self, FXSEL(SEL_UPDATE, 0), nil) > > Works just fine, widgets get updated instantaneously now. > > But really, I still do not understand why the widget refresh is so slow, and so "random". Sometimes very quick, sometimes near a second. I don''t have a Pentium II 166 with 16MB RAM, I can assure you, and the application is not that big for the moment. Maybe it''s a "Ruby" effect?If you want to ensure some sub-tree of the widget tree is fully updated, you can also use window->forceRefresh() to do this. No need to add your own code for it!! The downside is that forceRefresh() doesn''t return until ALL widgets have had an update. For a massive application [e.g. CAD system], that may mean ploughing through thousands of update handlers; the way the normal GUI update is done is sort of behind the scenes in a piecemeal fashion; its invisible during normal use because it doesn''t impact performance. At any rate, the API is there and you can use it where you need to.... - Jeroen -- +----------------------------------------------------------------------------+ | Copyright (C) 19:10 10/ 3/2006 Jeroen van der Zijp. All Rights Reserved. | +----------------------------------------------------------------------------+ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://rubyforge.org/pipermail/fxruby-users/attachments/20061003/c53f9453/attachment.bin
Philippe Lang
2006-Oct-04 06:26 UTC
[fxruby-users] FXDataTarget & widget value update delay
fxruby-users-bounces at rubyforge.org wrote:> On Oct 3, 2006, at 10:34 AM, Philippe Lang wrote: > >> When assigning a new value to an FXDataTarget programmatically, it >> takes a certain time for the widget linked to this FXDataTarget to be >> updated, just as if there was some sort of "polling" inside the >> framework. Delay can be as long as 1 second sometimes. Why aren''t the >> widgets updated straight away?> Yet another option, but one which sort-of defeats the purpose > of the GUI update process, is to call forceRefresh() directly > whenever you make a change to the data target''s value, e.g. > > datatarget.value = "Foo" > app.forceRefresh > > Calling forceRefresh() causes the application to immediately > start the GUI update process without waiting for idle time.I''m developing a client for a database, and in such a scenario, app.forceRefresh is exactly what I need! Again, thanks for your support, and thanks for FOX. That''s really a great great tool. Cheers, --------------- Philippe Lang Attik System -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3125 bytes Desc: not available Url : http://rubyforge.org/pipermail/fxruby-users/attachments/20061004/07016a13/attachment-0001.bin
Björn Bergqvist
2009-Oct-09 17:58 UTC
[fxruby-users] FXDataTarget & widget value update delay
Hello, this was an old thread but I noticed a significant speedup with "app.disableThreads" Ruby version 1.9.1p243, fxruby (1.6.19), Linux 32-bit (ArchLinux). Thanks! Bj?rn Bergqvist http://www.discretizer.org 2006/10/3 Lyle Johnson <lyle at knology.net>:> > On Oct 3, 2006, at 10:34 AM, Philippe Lang wrote: > >> When assigning a new value to an FXDataTarget programmatically, it >> takes a certain time for the widget linked to this FXDataTarget to >> be updated, just as if there was some sort of "polling" inside the >> framework. Delay can be as long as 1 second sometimes. Why aren''t >> the widgets updated straight away? > > The update of a widget''s settings due to a change in a data target''s > value is handled by FOX''s GUI update mechanism, described here: > > ? ? ? ?http://www.fox-toolkit.org/guiupdate.html > > This process only kicks in during idle time in the GUI, so there''s > inevitably going to be some small delay. The problem is compounded in > FXRuby due to the overhead required for converting back and forth > between C++ objects and Ruby objects, as well as scheduling Ruby > threads. If your FXRuby application doesn''t use any threads, you can > try turning off FXRuby''s support for scheduling Ruby threads by > calling the FXApp''s disableThreads() method: > > ? ? ? ?app.disableThreads > > Yet another option, but one which sort-of defeats the purpose of the > GUI update process, is to call forceRefresh() directly whenever you > make a change to the data target''s value, e.g. > > ? ? ? ?datatarget.value = "Foo" > ? ? ? ?app.forceRefresh > > Calling forceRefresh() causes the application to immediately start > the GUI update process without waiting for idle time. > > Hope this helps, > > Lyle > _______________________________________________ > fxruby-users mailing list > fxruby-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/fxruby-users >