OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« on: May 28, 2009, 07:57:03 pm » |
|
Hi people, i'm developing a plugin that will change the personal message every x seconds, reading quotes from a textfile. (yes it is useless  and it will be public when stable) I've got some troubles with timing: i need to call a proc every x seconds...this is the code i'm using, but it gets amsn to become unresponsive (yes i know it's and endless while and it takes A LOT of cpu). proc every { ms comando } { eval $comando after $ms }
proc scheduler { } { while { 1 } { every 5000 { setta_frase } } }
i know this is not a good way to do this. but i'm really newbie with TCL (this is my first coding!:D) and i found nothing about threads or something similar (all othere functions are alreay working..i need just this trick  ) can someone help me?? is there a way to develop plugin in java (which i know better) ? thanks in advice:)
|
|
|
|
|
Logged
|
|
|
|
|
kakaroto
|
 |
« Reply #1 on: May 28, 2009, 09:53:50 pm » |
|
hi, welcome to the aMSN forums! nice to see some new plugin developer around! Make sure you read the tcl/tk tutorial a wrote that explains the basics : http://www.amsn-project.net/wiki/Dev:TclTk_Tutorial (as well as the tcl/tk man pages!) and the plugin developer guide : http://www.amsn-project.net/wiki/Dev:Plugin_Developer_GuideTo answer your specific problem, the answer is here : http://www.tcl.tk/man/tcl8.4/TclCmd/after.htmbasically, to launch something every 5000 ms, you'd do : proc do_something { } { # .... after 5000 do_something } do_something
to do it the same way you do, you would just do : proc every { ms command } { eval $command after $ms [list every $ms $command] } proc scheduler { } { every 5000 { setta_frase } }
In your case, the 'after $ms' with no command to execute after it means that it would block and freeze for $ms.. which of course blocks the whole UI... "after $ms $command" will return right away and the command will automagically be executed after $ms have elapsed... And no, sorry you can't have a java plugin.. unless you want to have a look here : http://tcljava.sourceforge.net/docs/website/index.htmlbut I guarantee you, it will be 1000 times more complicated to do it with java... p.s.: you don't need a thread, tcl can work very well while being single threaded, that's what a "main loop" is for!
|
|
|
|
|
Logged
|
KaKaRoTo
|
|
|
OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« Reply #2 on: May 28, 2009, 11:44:19 pm » |
|
thanks for your fastest reply  i've modified the code as you told me to do in this way (pratically copied and pasted from yours) proc scheduler { } { every 5000 { puts "Scheduled Event" } } proc every { ms command } { eval $command after $ms [list every $ms $command] }
but when running it says: invalid command name "every" while executing "every 5000 { puts "EventoSchedulato" }" ("after" script) i read that this happens when i call a proc before it has been defined.. but it's not this way (i think:P) oh yes, i've already read the tutorial, and i took a look at tcl tutorial too  no java then  i wanted to learn python.. but tcl seems interesting too 
|
|
|
|
|
Logged
|
|
|
|
siller
Power user
Offline
Posts: 54
|
 |
« Reply #3 on: May 29, 2009, 12:21:57 am » |
|
don't know anything of Tcl but did you try switching places ?
'cause you call the proc 'every' in your proc 'scheduler' so i think the proc 'every' hasn't been defined @ that point.
but like I said don't know anything of tcl.
|
|
|
|
|
Logged
|
|
|
|
kjir
Power user
Offline
Posts: 133
|
 |
« Reply #4 on: May 29, 2009, 12:57:00 am » |
|
You switched the order of the procedures, it's not like in Object-Oriented Programming languages where order doesn't matter inside a class, it is a procedural language where order does matter...
|
|
|
|
|
Logged
|
|
|
|
|
kakaroto
|
 |
« Reply #5 on: May 29, 2009, 03:30:37 am » |
|
hehe, actually, both siller and kjir are WRONG :p actually, order does not matter at all because the tcl file gets 'source'-ed entirely before your proc is being called (if you have code in the tcl file directly (not inside a proc) it will get evaluated during the 'source' and then the order will matter, but not in your case).. notice in the stack trace that the 'every command is not found when being called by the "after script".. which means it's not in scheduler, it's in the 'after'.. the reason is simple, the 'after' command is executed in the "global" namespace.. but your proc is inside your plugin's namespace, solution is easy, assuming the namespace of your plugin is psmchanger, then you'd do : proc scheduler { } { every 5000 { puts "Scheduled Event" } } proc every { ms command } { eval $command after $ms [list ::psmchanger::every $ms $command] } happy to help! 
|
|
|
|
|
Logged
|
KaKaRoTo
|
|
|
OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« Reply #6 on: May 29, 2009, 10:44:55 am » |
|
 very thanks for you helping mates  now the looping works.. but due to this loop the deinit proc is never started: in fact when i try to stop the plugin, it does not work. (the plugin becomes inactive in the window, but it continues the "every" loop, as i can see in the console) i've read about the "update" command, andi tried to put it in.. but with no result. then i tought to get the pid of my plugin and killing it... but i've seen that pluins have the same pid of amsn, so it would quit amsn (oh yes i've done it  ) another little help..? thanks a lot 
|
|
|
|
|
Logged
|
|
|
|
kjir
Power user
Offline
Posts: 133
|
 |
« Reply #7 on: May 29, 2009, 12:00:03 pm » |
|
Doh! KaKaRoTo kicked my ass again... Oh well, luckily I know almost nothing about Tcl  To solve your problem, I don't know if there are better ways to do this in Tcl, but you could simply wrap the body of the every proc in an if that checks for a variable, so that you can set that to false when deactivating the plugin...
|
|
|
|
|
Logged
|
|
|
|
OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« Reply #8 on: May 29, 2009, 12:42:27 pm » |
|
lol  you're perfectly right kjir! it works quite well now! good good! i tried this before, but due to a stupid syntax error the deinit procedure did not start. now it does thanks a lot:)
|
|
|
|
|
Logged
|
|
|
|
OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« Reply #9 on: May 29, 2009, 01:55:42 pm » |
|
it's ready!  i'm gonna use it some hours and publish it 
|
|
|
|
|
Logged
|
|
|
|
|
kakaroto
|
 |
« Reply #10 on: May 29, 2009, 06:08:27 pm » |
|
better solution to stop the loop : after cancel [list ::psmchanger::every $ms $command] The command in the "after cancel" must be exactly the same as the one you set when creating the 'after' timer... If deinit is never called, make sure that the plugininfo.xml specifies a deinit proc and that the proc's name is correct... it's all explained in Tcl's manual... You could also save a variable with the after id like this : variable after_id set after_id [after $ms [list ::psmchanger::every $ms $command]]
# ... proc Deinit { } { variable after_id after cancel $after_id }
(make sure to catch it and that the variable exists, etc...
|
|
|
|
|
Logged
|
KaKaRoTo
|
|
|
OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« Reply #11 on: May 29, 2009, 06:35:27 pm » |
|
If deinit is never called, make sure that the plugininfo.xml specifies a deinit proc and that the proc's name is correct.... now it works with the variable chechink stuff;) it's was a stupid syntax error. one question: when amsn quits, are all deinit procedure called, and waited to finish ? because i guess that amsn does not wait all deinit procedure to terminate... again, i found that changing PSM too often take the server to reject the request, not making the quote upgraded to the profile. updating every 5 minutes causes too much activity after 40-45 minutes... do you know anything about this threadshot ?
|
|
|
|
|
Logged
|
|
|
|
OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« Reply #12 on: May 29, 2009, 06:41:32 pm » |
|
i got another issue: when i close AMSN with my plugin active, upon next AMSN launch, i find all plugins deactivated except mine...
|
|
|
|
|
Logged
|
|
|
|
|
kakaroto
|
 |
« Reply #13 on: May 29, 2009, 09:38:29 pm » |
|
Ok, first, you have to understand that aMSN doesn't run threaded! It's all using Tcl's main loop in a single thread.. so there is no new thread per plugin or for anything... so the question "does amsn wait for the deinit procedure to finish?" doesn't make sense.. it's one thread, so if it calls DeInit, then there's no way for it to do anything (like calling 'exit') until the DeInit returns.. Anyways, yes the server can be quite bitchy about flooding, Actually, you *can* change the PSM and the server won't mind, but uploading the PSM change to the server for content roaming (being able to get the same PSM when connecting from another machine) is probably protected against flooders... I suggest you do like the music plugin does, when calling the ChangePSM, give it '0' for the update argument so it doesn't update the content roaming server, but only updates it locally (others contacs will see the PSM change, but if you connect from another machine, you won't get the new PSM)...
About the all plugins deactivated except mine.. Are you sure about that.. ? I know there's a bug somewhere that causes all plugins to become disabled or disable all except one but we weren't able to reproduce it (it just happens rarely).. if you can reproduce it constantly, could you help us track down and fix this bug? could you upload your plugin with instructions on how to reproduce the problem somewhere so I can get access to it? Thanks!
|
|
|
|
|
Logged
|
KaKaRoTo
|
|
|
OnEmAnArMy
Newbie
Offline
Posts: 9
|
 |
« Reply #14 on: May 30, 2009, 10:23:54 am » |
|
 sorry for my noobish, bus as i am Java and PHP experienced it's hard to me to think to a so complex program as AMSN without threads  So. Ok. It IS SINGLE THREADED  i won't ask more I will put the 0 parameter to the update function then  thanks. i did not find any documentation about this. Or i will update only on quitting.. gotta think about it (if someone has suggestion, i'll be pleased to hear  ) For the "all plugins deactivated except mine": oh yes it's reproducible. I've got 2 macs with leopard, running different CVS of amsn, and it shows (quite) all the time at the same way: just close amsn with my plugin opened, and on next launch all other plugins but mine will be deactivated. Oh sure, fell free to watch at my code. leave me a PM with your email address and i'll send it to you  I'm sorry i cannot do more, but i cannot debug tcl, and i have not much time to study it well (damn "digital electronic" exam!!!) thanks to you too
|
|
|
|
|
Logged
|
|
|
|
|