aMSN Forums
August 22, 2018, 08:22:12 am *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: New forum for aMSN !!
 
   Home   Help Search Login Register  
Pages: [1] 2
  Print  
Author Topic: Tcl threads?  (Read 17473 times)
OnEmAnArMy
Newbie

Offline Offline

Posts: 9


View Profile
« 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 Cheesy 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).

Code:
 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 Wink
(all othere functions are alreay working..i need just this trick Smiley )

can someone help me?? is there a way to develop plugin in java (which i know better) ?
thanks in advice:)
Logged
kakaroto
Administrator
Super Power User
*****
Offline Offline

Posts: 9428


View Profile WWW
« 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_Guide
To answer your specific problem, the answer is here : http://www.tcl.tk/man/tcl8.4/TclCmd/after.htm

basically, to launch something every 5000 ms, you'd do :
Code:

proc do_something { } {
    # ....
    after 5000 do_something
}
do_something


to do it the same way you do, you would just do :
Code:

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.html
but 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 Offline

Posts: 9


View Profile
« Reply #2 on: May 28, 2009, 11:44:19 pm »

thanks for your fastest reply Smiley
i've modified the code as you told me to do in this way (pratically copied and pasted from yours)
Code:
      proc scheduler { } {
every 5000 { puts "Scheduled Event" }
}

proc every { ms command } {
    eval $command
    after $ms [list every $ms $command]
}

but when running it says:
Code:
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 Smiley

no java then Smiley i wanted to learn python.. but tcl seems interesting too Wink
Logged
siller
Power user
*
Offline Offline

Posts: 54


View Profile
« 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 Offline

Posts: 133


View Profile
« 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
Administrator
Super Power User
*****
Offline Offline

Posts: 9428


View Profile WWW
« 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 :
Code:
  proc scheduler { } {
      every 5000 { puts "Scheduled Event" }
   }
   
   proc every { ms command } {
         eval $command
         after $ms [list ::psmchanger::every $ms $command]
   }

happy to help! Smiley
Logged

KaKaRoTo
OnEmAnArMy
Newbie

Offline Offline

Posts: 9


View Profile
« Reply #6 on: May 29, 2009, 10:44:55 am »

Smiley very thanks for you helping mates Smiley
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 Cheesy )

another little help..?Cheesy
thanks a lot Smiley
Logged
kjir
Power user
*
Offline Offline

Posts: 133


View Profile
« 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 Tongue

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 Offline

Posts: 9


View Profile
« Reply #8 on: May 29, 2009, 12:42:27 pm »

lol Cheesy 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 Smiley

thanks a lot:)
Logged
OnEmAnArMy
Newbie

Offline Offline

Posts: 9


View Profile
« Reply #9 on: May 29, 2009, 01:55:42 pm »

it's ready! Cheesy
i'm gonna use it some hours and publish it Smiley
Logged
kakaroto
Administrator
Super Power User
*****
Offline Offline

Posts: 9428


View Profile WWW
« Reply #10 on: May 29, 2009, 06:08:27 pm »

better solution to stop the loop :
Code:
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 :
Code:
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 Offline

Posts: 9


View Profile
« Reply #11 on: May 29, 2009, 06:35:27 pm »

Quote from: "kakaroto"
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 Offline

Posts: 9


View Profile
« 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
Administrator
Super Power User
*****
Offline Offline

Posts: 9428


View Profile WWW
« 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 Offline

Posts: 9


View Profile
« Reply #14 on: May 30, 2009, 10:23:54 am »

Smiley 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 Smiley
So. Ok. It IS SINGLE THREADED Cheesy i won't ask more Cheesy

I will put the 0 parameter to the update function then Smiley 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 Smiley )

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 Smiley
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
Pages: [1] 2
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!