cow4263 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm writing a AIM bot using Net::OSCAR. If you're unfamilar with the module, it basically sets each AIM event (receiving an IM, someone going offline, etc) as a different callback (I would appreciate someone directing me towards a place I could get more information about these callbacks; I've looked and my searches have come up mostly empty) and then calls a function in your code. Some functions rely on the result of other functions to work properly (ie the function that changes the buddylist ( commit_buddylist() ) must recieve an status message about the previous change ( buddylist_ok() or buddylist_error() ) before it can be called again, ).

The problem I'm experiencing is the program just rushes through execution without waiting for certain events to occur.
My question is: how do you stop excecution at a certain point, wait for a particular callback (or event) and then continue? Ideally, it should handle timing out after a certain time as well (if the expected result hasn't been returned).
For example:
# assume $bot is a valid Net::OSCAR object # callbacks $bot->set_callback_signon_done(\&signon_done); $bot->set_callback_buddylist_ok(\&buddylist_ok); $bot->set_callback_buddylist_error(\&buddylist_error); $bot->signon($sn,$passwd); #this logs you into the net # Program should wait here until signon_done # parse a list of @buddies to be added (this works) foreach (@buddies) { $bot->add_buddy($grp, $_) #adds a user $bot->commit_buddylist(); # sets changes to the server # program should wait here until either # buddylist_ok() or buddylist_error() is returned } # ... do other stuff

Even if you aren't familar with Net::Oscar, I hope you understand what I'm trying to accomplish. If you don't understand anything above, please tell me and I'll try to clarify.

Thanks in advance,
-mike

Replies are listed 'Best First'.
Re: Waiting for callback event
by sweetblood (Prior) on Nov 22, 2004 at 19:44 UTC
    After taking a quick look at the docs for Net::Oscar, it would appear as you need to wrap a while loop around the Net::Oscar::do_one_loop() function. Your code just runs through without waiting.

    Re-read the docs, you'll get it.

    Good luck

    Sweetblood

      Hmm, I have one of those (its actually the next thing in the code after the block posted). But, I wanted these to be executed before said loop, but I think I could move these into the buddy of the signon_done() subroutine. But, then I'd still have the problem of making multiple calls to commit_buddylist without waiting for the proper return. I could have a do-until loop with the buddylist_ok and buddylist_error taking a global variable as a parameter (which would then be the conditional of the while loop). Hmm. I don't know if that made any sense, but I've gotta jet real quick and wanted to get these thoughts down somewhere :P.

      Thanks for your help, anybody else with ideas feel free to post em.

      -mike
Re: Waiting for callback event
by eric256 (Parson) on Nov 22, 2004 at 19:52 UTC

    AIM bots have to be programmed in an event driven style. Well they don't HAVE to be, but it makes life easier.

    This means that you need to break that sequence of commands you have down, and put them in the events when they should be executed. As was already mentioned you need to use do_one_loop to tell the AIM protocol you are ready for it to loop, then keep calling do_one_loop constantly, normaly in an infinite loop of sorts.

    If you would like to learn more about bot programming you can check out my forums at http://Bot-depot.com, there are programmers there of all levels of experience. Many of us program AIM,MSN, Jabber and IRC bots in perl, and there are some who use other languages like VB and PHP. Good luck.


    ___________
    Eric Hodges
      As I may have mentioned in the hastily written reply above, I would like these events to occur before the infinite do_once_loop() (or as I like to refer to it, interactive mode). I have a feeling that manually calling do_once_loop() will get the results I desire, but that will have to wait until I get home later tonight.

        I beleive that you can add multiple buddies, and then commit the list. Other than that I would setup a que of buddies to add, add one, and then add another and commit everytime you get the buddylist_ok() or buddylist_error().

        Calling do_one_loop manualy between each call will be iffy at best. Its going to go check each socket and see if there is something new. If there is no message then it returns, if there is then it processes it and calls the event. You would be counting on your events to come at the right time and in the right order, which is generaly a bad idea. I think you should probably focus more on how to fit your needs into an event driven program.


        ___________
        Eric Hodges
Re: Waiting for callback event
by castaway (Parson) on Nov 22, 2004 at 19:58 UTC
    The point of event driven programming is that you just react to events, you don't wait for them.. Anyfish, what you're missing is the set_callback_signon_done callback, which tells you when the signon is finished. And in that callback you can then get on with the rest of your stuff.

    Using a command-line Net::OSCAR client daily..

    C.