Glenn W Munroe wrote:
Rob,Your enhancements sound good. In principal, I'm a little wary of straying from MS's underlying interface, but I think that in the case of this control, the precedent was set in the early days of the module (from what I understand of the MS documentation, the SetTimer function creates the timer and sets its interval in one call). Your proposed new 'Kill' behaviour again strays a little from the MS standard, but it will achieve the goal of not breaking old programs.
The MS api has only 2 calls: SetTimer(HWND, ID, INTERVAL) KillTimer(HWND, ID)If programming directly using this api the user chooses an ID, and then calls SetTimer to start the timer, or KillTimer to stop (and free) the timer.
The Win32::GUI::Timer class has the following api (as proposed by me below):new(PARENT, NAME, ELAPSE). Underneath it maps name to an ID, stores the parameters in a perl Win32::GUI::Timer object and adds a reference to the object to its window(parent) object. It then calls SetTimer, if ELAPSE is greater than 0.
INTERVAL(ELAPSE). Retrieves the parameters from the object, and calls SetTimer if ELAPSE > 0, or KillTimer if ELAPSE=0.
Kill(REMOVE). Retrieves the parameters from the object and calls KillTimer. Removes the reference from its window(parent) object if REMOVE evaluates true.
DESTROY(). Called when the reference count to the timer object goes to zero. Calls KillTimer.
So you can consider it like this: new - calls SettTimer Interval(n) - calls SetTimer Interval(0) - calls KillTimerKill() - calls KillTimer, leaving the mapping between NAME and ID so that Interval(n) still has the parameters to call SetTimer again.
Kill(1) - calls KillTimer and removes the NAME to ID mapping. It doesn't feel too far from the MS api to me. > The only problem I can think of is if anybody were to
repeatedly create and destroy a lot of timers, assuming standard MS behaviour, then memory usage (which seems to be a hot topic of late) might increase, as the timers would be simply disabled and not destroyed. But that's unlikely, and as long as the changes are documented, there shouldn't be a problem.
I don't see that's how it works. KillTimer is always called. The problem with the current implementation is that if you repeatedly call new(), then a new perl object is created, and as there is a reference from the parent to it, it cannot get DESTROYed until the parent object is destroyed, so perl memory usage increases. Under the proposed implementation this is fixed by (1) allowing re-use of the same perl object (with Interval(0) and Kill() killing the underlying windows timer, and Interval(n) re-starting it) or (2) Kill(1) freeing all the perl resources.
I'm going to go ahead and re-work it and update the documentation and tests. Regards, Rob.
So, in general, though I'm more of a user than a developer, I agree with your suggestions. Glenn -----Original Message-----From: Robert May [mailto:[EMAIL PROTECTED] Sent: Friday, 11 November, 2005 18:46To: perl-win32-gui-hackers@lists.sourceforge.net Cc: Glenn W Munroe Subject: Win32::GUI::Timer [Was: Next Release soon on the users list]I've had reason to look in more detail at the changes that Reini made some months ago. I propose that I'm going to make another round of changes to the timer class:(1) I want to get rid of the circular reference. I think this is possible. (2) I'd like to not break existing implementations. I propose the following interface: new(PARENT, [NAME, [ELAPSE=0]])creates a Win32::GUI::Timer object, adds it to the PARENT window's hash etc. as today. I'll add the capability of creating the object with ELAPSE=0, which will create the object, but not start the timer.Interval([ELAPSE]) get or set the timer interval, as today. I will modify it so that whensetting it returns the previous interval. Setting the interval to 0 will suspend the timer.Kill([REMOVE=0])Calling Kill with no parameters (or any parameter that evaluates to false) will suspend the timer exactly like Interval(0).Calling Kill with a parameter that evaluates to True will remove all traces of the timer from the parent hash, although true destruction will still only happen when the object's ref-count goes to zero. In most case this will happen after a Kill(1).Additionally, by removing the circular reference, I believe that regular destruction when the (parent) window object goes out of scope will happen, rather than the current implementation where if you have not called Kill explicitly, object destruction doe not happen until the final garbage collection sweep when the program terminates.If we can agree on this, then I will make the changes, update the documentation and update the tests.Your comments welcome, as always. Regards, Rob. Robert May wrote:Hi Glenn,Thanks for the investigation. The changes were made by Reini, to try to bring the behaviour in line with what part 4 of the tutorial says about timers. Having looked at this text myself, I'm not sure that what he has done matches what the tutorial says, although I think his implementation is good.Under the current implementation kill() destroys the timer completely (including, as you say, removing it's reference from the parent window). To disable the timer temporarily you need to set the interval to 0.If we all agree that the new implementation is good, then I'll update the Timer documentation and part 4 of the tutorial to reflect this. I'll also make sure that this behavioural change gets mentioned in the release notes.Regards, Rob. Glenn W Munroe wrote:I had been building the new version using MinGW, but I just reinstalled it from Rob's PPM. This installed the new documentation correctly and I now seethat there is some Timer documentation. Apologies for flooding the list with replies to myself... -----Original Message----- From: [EMAIL PROTECTED][mailto:[EMAIL PROTECTED] On Behalf Of GlennW Munroe Sent: Friday, 28 October, 2005 12:27 To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: RE: [perl-win32-gui-users] Next Release soon I spent a little time to dig into this more. As I suspected, this isn't a bug, but a change in implementation. Under version 1.01_01, the Kill()method simply made a call to the system function KillTimer. Version 1.02_02 explicitly destroys the timer, which includes removing its definition fromthe window hash. Hence, my "nothing strange" code below was defining each timer then destroying it in the next step! In practice, there was a more subtle difference. The effect of the oldKill() method was simply to disable the timer; it could then be resurrectedwith a new Interval(). I'm not sure that this behaviour was correct ordesired, but I was using it in my program. I can't just remember why I did it that way, but it was probably a "safe" way of ensuring the timer didn'tfire until I was ready for it (the alternative being either to make the Interval() very large--for some arbitrary value of "very large"--or torepeatedly kill and redefine the timer). It could also have been to cover adeeper problem in the implementation, but time will tell.The Win32::GUI documentation for Timers is bare, but the MSDN documentationdoes suggest that the new behaviour is correct. However, version 1.02_02 will break any program using the old behaviour. The addition of a simple definition to the method documentation would help. Glenn -----Original Message-----From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Sent: Friday, 21 October, 2005 16:44To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED]; [EMAIL PROTECTED] Subject: RE: [perl-win32-gui-users] Next Release soon Sorry for the delay, but it's been hectic at work this week.I've attached (an image of) the error message. Sure enough, a 'dump' of themain window object shows that the timers don't get registered for some reason: bless({ # tied Win32::GUI::Window "-accel" => 41_681_429, "-font" => -334_885_755, "-handle" => 2_032_212, "-minheight" => 595, "-minwidth" => 850, "-name" => "mw", "-timers" => {}, "-type" => 0, etc. There's nothing strange about the declaration of the timers: $mw->AddTimer("tmList",100000); $mw->tmList->Kill(); $mw->AddTimer("tmLoop",100000); $mw->tmLoop->Kill(); etc. The same script runs with no problem on 1.01_01. There, the dump shows: bless({ # tied Win32::GUI::Window "-accel" => 25_036_785, "-font" => "-1626733967", "-handle" => 6_358_280, "-minheight" => 595, "-minwidth" => 850, "-name" => "mw", "-timers" => { 1 => "tmList", 2 => "tmLoop", 3 => "tmStatus", 4 => "tmYearVerify", 5 => "tmTrackVerify", 6 => "tmGenreVerify", }, "-type" => 0, etc. I'll keep trying to narrow it down and will post back if I do. Glenn ------------------- reply ---------------From: [EMAIL PROTECTED] To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: RE: [perl-win32-gui-users] Next Release soon Date: 2005-10-19 15:40:09 ---------------------------------- [EMAIL PROTECTED] wrote:hit another more worrying problem: I have a large-ish program, which uses a number of timers. With 1.02_02 I get an error whenever any one of the timers tries to fire (Can't locate auto/tmList.al in @INC...). I tried to replicate this in a smaller program, but was unable to; a simple program with a timer works fine. It's quite possible that my program has a flaw, of which 1.01_01 is more tolerant, but there may be a problem in the new GUI code.That is indeed worrying. There have been some minor changes to the timer code that Reini made when he put his tests together, but I can't immediately see anything that would cause this.Typically when I see errors like that it turns out to be a mis-spelled method call or window name, but if that was the case I would expect it to fail in 1.01_01 too.If you can't get a short example to exhibit this problem, can you post the exact error message that you're getting.Rob. -- Robert May Win32::GUI, a perl extension for native Win32 applications http://perl-win32-gui.sourceforge.net/------------------------------------------------------- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today * Register for a JBoss Training Course Free Certification Exam for All Training Attendees Through End of 2005 Visit http://www.jboss.com/services/certification for more information _______________________________________________ Perl-Win32-GUI-Users mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users http://perl-win32-gui.sourceforge.net/------------------------------------------------------- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today * Register for a JBoss Training Course Free Certification Exam for All Training Attendees Through End of 2005 Visit http://www.jboss.com/services/certification for more information _______________________________________________ Perl-Win32-GUI-Users mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users http://perl-win32-gui.sourceforge.net/